Callspec
Stop duct-taping your API stack.
One TypeScript route → typed SDK, docs, OpenAPI, and MCP.
Open source
MIT licensed — free to use and fork.
RPC routes
Methods like getProductById — not bikeshedding REST.
Structured errors
Errors as values with typed codes — no try/catch needed.
Test without HTTP
Unit-test handler(input, ctx) — no server setup.
MCP included
Same routes become Cursor/Claude tools — no second spec.
Most teams duct-tape the same API across REST routes, OpenAPI specs, DIY clients, docs, types, validators and MCP. That's a ton of repetitive work and brittle code that drifts.
Instead, define each route once in TypeScript — inputs, outputs, and errors — and Callspec ships the server, SDK, docs, OpenAPI, and MCP from that contract. One source of truth, unit-testable, no drift.
How it works
Define
export const searchPosts = route({ input, output, handler: async (inp, ctx) => { // your logic }, }) export const api = spec({ routes: {searchPosts}, })Serve
- MCP
/mcp - HTTP RPC
/v1/* - Docs UI
/docs - OpenAPI
/openapi.json
- MCP
Generate
npx callspecIntegrate
Generate multi-language SDKs and docs from your
openapi.jsonwith tools like Fern or Microsoft Kiota.Python
Go
Java
C#
Built-in docs UI
Try-it panels, search, OpenAPI, and MCP connect — shipped with your API, no extra wiring. Whitelabel with your logo, accent, and nav links when you want; the defaults are simple and ready to go.

Typed SDK from the same spec
Docs, OpenAPI, and MCP share one contract — your frontend gets the same types and error codes, so nothing drifts when routes change.
const result = await api.getProductById({id});
if (!result.ok) {
if (result.code === 'NOT_FOUND') return null;
throw result;
}
return result.value; // typed ProductBuilt for coding agents
Agents call the same routes as your app — mountSpec exposes them as MCP tools with shared validation, auth, and error codes. The explorer ships connect snippets; the package ships a coding-agent skill.
MCP from your routes
Set mcp: true on a route — mountSpec exposes it as a tool with the same validation, auth, and error codes as RPC.
Connect from docs
The explorer home panel ships copy-paste snippets — server URL, bearer hints, and tool names ready for Cursor or Claude.
Agent skill included
The npm package ships SKILL.md so agents follow Callspec conventions — Result errors, callspec.json codegen, route layout.
We do file uploads too
Small files on the same RPC — avatars, CSVs, a PDF. Same handler, same generated client, same auth and errors. The client posts multipart for you.
const result = await api.upload({
file: input.files[0],
caption: 'hi',
});Bring your own auth
Callspec reads the Bearer token from each request. Wire authenticate on your spec to verify it and return context — your existing provider or session logic.
Need a hand?
Questions, a stuck integration, or just saying hi — join us on Discord.
