Claude-code-plugins exa-deploy-integration
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/exa-pack/skills/exa-deploy-integration" ~/.claude/skills/jeremylongshore-claude-code-plugins-exa-deploy-integration && rm -rf "$T"
manifest:
plugins/saas-packs/exa-pack/skills/exa-deploy-integration/SKILL.mdsource content
Exa Deploy Integration
Overview
Deploy applications using Exa's neural search API to production. Covers API endpoint creation, secret management per platform, caching for production traffic, and health check endpoints.
Prerequisites
- Exa API key stored in
environment variableEXA_API_KEY - Application using
SDKexa-js - Platform CLI installed (vercel, docker, or gcloud)
Instructions
Step 1: Vercel Edge Function
// api/search.ts — Vercel API route import Exa from "exa-js"; export const config = { runtime: "edge" }; export default async function handler(req: Request) { if (req.method !== "POST") { return new Response("Method not allowed", { status: 405 }); } const exa = new Exa(process.env.EXA_API_KEY!); const { query, numResults = 5 } = await req.json(); if (!query || typeof query !== "string") { return Response.json({ error: "query is required" }, { status: 400 }); } try { const results = await exa.searchAndContents(query, { type: "auto", numResults: Math.min(numResults, 20), text: { maxCharacters: 1000 }, highlights: { maxCharacters: 300, query }, }); return Response.json({ results: results.results.map(r => ({ title: r.title, url: r.url, score: r.score, snippet: r.text?.substring(0, 300), highlights: r.highlights, })), }); } catch (err: any) { const status = err.status || 500; return Response.json( { error: err.message, requestId: err.requestId }, { status } ); } }
# Deploy to Vercel vercel env add EXA_API_KEY production vercel --prod
Step 2: Docker Deployment
FROM node:20-slim WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . RUN npm run build EXPOSE 3000 CMD ["node", "dist/index.js"]
// src/server.ts — Express search API import express from "express"; import Exa from "exa-js"; const app = express(); app.use(express.json()); const exa = new Exa(process.env.EXA_API_KEY!); app.post("/api/search", async (req, res) => { const { query, numResults = 5, type = "auto" } = req.body; try { const results = await exa.searchAndContents(query, { type, numResults, text: { maxCharacters: 1000 }, }); res.json(results); } catch (err: any) { res.status(err.status || 500).json({ error: err.message }); } }); app.get("/health", async (_req, res) => { try { await exa.search("health", { numResults: 1 }); res.json({ status: "healthy", service: "exa" }); } catch { res.status(503).json({ status: "unhealthy", service: "exa" }); } }); app.listen(3000, () => console.log("Listening on :3000"));
Step 3: Google Cloud Run
set -euo pipefail # Store API key in Secret Manager echo -n "$EXA_API_KEY" | gcloud secrets create exa-api-key --data-file=- # Deploy with secret mounted as env var gcloud run deploy exa-search-api \ --source . \ --set-secrets=EXA_API_KEY=exa-api-key:latest \ --allow-unauthenticated \ --region us-central1
Step 4: Production Search with Redis Cache
import Exa from "exa-js"; import { Redis } from "ioredis"; import { createHash } from "crypto"; const exa = new Exa(process.env.EXA_API_KEY!); const redis = new Redis(process.env.REDIS_URL!); async function cachedSearch(query: string, opts: any = {}, ttl = 3600) { const key = `exa:${createHash("sha256").update(JSON.stringify({ query, ...opts })).digest("hex")}`; const cached = await redis.get(key); if (cached) return JSON.parse(cached); const results = await exa.searchAndContents(query, { type: "auto", numResults: 5, text: { maxCharacters: 1000 }, ...opts, }); await redis.set(key, JSON.stringify(results), "EX", ttl); return results; }
Error Handling
| Issue | Cause | Solution |
|---|---|---|
| 401 in production | API key not set | Verify env var in deployment platform |
| Rate limited | Too many requests | Implement Redis cache + request queue |
| Slow responses | Large content requests | Reduce or |
| Timeout on Edge | Query too complex | Use for edge functions |
| Cold start latency | Serverless cold start | Keep Exa client initialization outside handler |
Resources
Next Steps
For multi-environment setup, see
exa-multi-env-setup. For production checklist, see exa-prod-checklist.