Help us improve
Share bugs, ideas, or general feedback.
From perplexity-pack
Deploys Perplexity Sonar API apps to Vercel edge functions, Cloud Run with Redis caching, and Docker, handling secrets and production setup.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin perplexity-packHow this skill is triggered — by the user, by Claude, or both
Slash command
/perplexity-pack:perplexity-deploy-integrationThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Deploy applications using Perplexity Sonar API to edge and server platforms. Perplexity's OpenAI-compatible endpoint at `https://api.perplexity.ai/chat/completions` works from any platform that can make HTTPS requests.
Installs OpenAI client and configures Perplexity Sonar API authentication for Node.js or Python. Provides env setup and verification scripts.
Deploys Exa search API apps to Vercel Edge, Docker, and Cloud Run with endpoint templates, secret configs, and production bash commands.
Deploys Mistral AI apps to Vercel Edge/Serverless, Docker, and Cloud Run with secret configuration and code examples for production.
Share bugs, ideas, or general feedback.
Deploy applications using Perplexity Sonar API to edge and server platforms. Perplexity's OpenAI-compatible endpoint at https://api.perplexity.ai/chat/completions works from any platform that can make HTTPS requests.
PERPLEXITY_API_KEY// api/search.ts
import OpenAI from "openai";
export const config = { runtime: "edge" };
const perplexity = new OpenAI({
apiKey: process.env.PERPLEXITY_API_KEY!,
baseURL: "https://api.perplexity.ai",
});
export default async function handler(req: Request) {
const { query, model = "sonar", stream = false } = await req.json();
if (stream) {
const response = await perplexity.chat.completions.create({
model,
messages: [{ role: "user", content: query }],
stream: true,
max_tokens: 2048,
});
return new Response(response.toReadableStream(), {
headers: { "Content-Type": "text/event-stream" },
});
}
const response = await perplexity.chat.completions.create({
model,
messages: [{ role: "user", content: query }],
max_tokens: 2048,
});
return Response.json({
answer: response.choices[0].message.content,
citations: (response as any).citations || [],
model: response.model,
});
}
set -euo pipefail
# Deploy to Vercel
vercel env add PERPLEXITY_API_KEY production
vercel deploy --prod
// server.ts
import express from "express";
import OpenAI from "openai";
import { createClient } from "redis";
import { createHash } from "crypto";
const app = express();
app.use(express.json());
const perplexity = new OpenAI({
apiKey: process.env.PERPLEXITY_API_KEY!,
baseURL: "https://api.perplexity.ai",
});
const redis = createClient({ url: process.env.REDIS_URL });
await redis.connect();
app.post("/api/search", async (req, res) => {
const { query, model = "sonar" } = req.body;
const cacheKey = `pplx:${createHash("sha256").update(`${model}:${query}`).digest("hex")}`;
// Check cache first
const cached = await redis.get(cacheKey);
if (cached) {
return res.json({ ...JSON.parse(cached), cached: true });
}
const response = await perplexity.chat.completions.create({
model,
messages: [{ role: "user", content: query }],
max_tokens: 2048,
});
const result = {
answer: response.choices[0].message.content,
citations: (response as any).citations || [],
model: response.model,
tokens: response.usage?.total_tokens,
};
// Cache for 1 hour
await redis.setEx(cacheKey, 3600, JSON.stringify(result));
res.json(result);
});
app.listen(8080);
set -euo pipefail
# Deploy to Cloud Run
gcloud secrets create perplexity-api-key --data-file=<(echo -n "$PERPLEXITY_API_KEY")
gcloud run deploy perplexity-search \
--source . \
--set-secrets=PERPLEXITY_API_KEY=perplexity-api-key:latest \
--port=8080 \
--allow-unauthenticated
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
RUN npm run build
ENV NODE_ENV=production
EXPOSE 8080
CMD ["node", "dist/server.js"]
{
"functions": {
"api/search.ts": {
"maxDuration": 30
}
}
}
app.get("/health", async (req, res) => {
const start = Date.now();
try {
await perplexity.chat.completions.create({
model: "sonar",
messages: [{ role: "user", content: "ping" }],
max_tokens: 5,
});
res.json({ status: "healthy", latencyMs: Date.now() - start });
} catch {
res.status(503).json({ status: "unhealthy", latencyMs: Date.now() - start });
}
});
| Issue | Cause | Solution |
|---|---|---|
| Edge function timeout | sonar-pro takes >30s | Use sonar or increase maxDuration |
| Cache stale for news | TTL too long | Use search_recency_filter + shorter TTL |
| API key invalid after deploy | Wrong secret reference | Verify vercel env ls or gcloud secrets |
| Stream interrupted | Client disconnect | Handle abort signal gracefully |
For multi-environment setup, see perplexity-multi-env-setup.