ShipKit docs
The stack

AI

Vercel AI SDK with Anthropic for chat and Google Gemini for embeddings, RAG over pgvector, and a small MCP server.

The AI stack lives in packages/ai and apps/admin/app/(authed)/chat.

Models

  • Chat@ai-sdk/anthropic with Claude. The chat UI is in apps/admin (behind auth).
  • Embeddings@ai-sdk/google with Gemini's text-embedding model. Cheap, fast, good enough for RAG.

Switching providers is a one-line change in packages/ai/src/models.ts — the rest of the code talks to the AI SDK abstraction, not the provider.

RAG

bun run rag:ingest walks content/ and apps/docs/content/, chunks the markdown, embeds each chunk with Gemini, and writes rows into the embedding table (pgvector). At query time, the chat route does a cosine-similarity search and feeds the top chunks into the system prompt.

The embeddings.user_id column scopes rows to their owner. Ingested docs are written under RAG_USER_ID, and the chat route's similarity search filters WHERE user_id = <caller> — a user only retrieves chunks they own.

MCP

apps/mcp is a small Model Context Protocol server exposing the API as tools. It runs in two modes:

  • stdio — for local agents (Claude Desktop, etc.)
  • HTTP — for hosted clients, via StreamableHTTPServerTransport over node:http

Auth headers are picked from MCP_AUTH_HEADER / MCP_AUTH_HEADER_<N> env vars so the same binary works with cookies, bearer tokens, or whatever else the project has wired up.

Agent example

See docs/agent-example.md for a worked example of pointing Claude Desktop at the MCP server and calling shipkit endpoints as tools.

On this page