---
title: MCP server
description: Serve docs to MCP clients over stdio or Streamable HTTP — the gate
  for when it's worth it, the optional-peer-dep and stateless-HTTP gotchas, and
  how edge/bundled hosts skip the disk path.
related:
  - title: Agent search tools
    href: /docs/search/agent-tools
    description: In-process bash tools for your own AI app — the alternative to a
      standalone MCP server.
  - title: CLI
    href: /docs/reference/cli
    description: leadtype mcp flags and exit codes.
  - title: Search reference
    href: /docs/reference/search
    description: searchDocs() and the index the MCP server ranks over.
---
`leadtype/mcp` serves your generated docs to MCP clients with two tools:
`search-docs(query, limit?)` returns ranked `{ title, urlPath, snippet }`, and
`get-page(urlPath)` returns the full Markdown of one page. (`list-pages()` is
available but off by default.) It's a thin adapter over artifacts you already
build — the search index ranks results, the `.md` mirror supplies pages — so
there's no new content surface to maintain.

There are **two paths**, same two tools — pick by *who connects*:

* **[Path 1 — in your editor](#path-1-in-your-editor-stdio)** (`leadtype mcp`, stdio): your *own*
  agent (Cursor, Claude Desktop, Cline) searches your docs while you work.
* **[Path 2 — a hosted endpoint](#path-2-a-hosted-endpoint-createmcphandler)** (`createMcpHandler`,
  Streamable HTTP): *other people's* agents connect to `yoursite.com/mcp`.

Everything else on this page is a variation on one of those two.

## Path 1 — in your editor (stdio)

The common case: give your own editor's agent live search over your docs.

1. **Install the MCP SDK** It's an optional peer dependency — install it in the project that runs the server.

   ```bash
   bun add @modelcontextprotocol/sdk
   ```

2. **Generate the artifacts** The same `leadtype generate` you run for your docs site writes everything the server reads — `public/docs/search-index.json`, `agent-readability.json`, and the `.md` mirror. The server never builds these; it only reads them.

   ```bash
   leadtype generate
   ```

3. **Point your editor at the binary** Use an **absolute** `--artifacts` path — the client spawns the binary from an unpredictable working directory.

   // .cursor/mcp.json
   \{ "mcpServers": \{ "my-docs": \{ "command": "leadtype", "args": \["mcp", "--artifacts", "/abs/path/to/public"] } } }// claude\_desktop\_config.json
   \{ "mcpServers": \{ "my-docs": \{ "command": "leadtype", "args": \["mcp", "--artifacts", "/abs/path/to/public"] } } }

4. **Verify it works — before touching your editor** Exercise the tools once, with no client and no SDK:

   ```bash
   leadtype mcp --check --query "getting started"
   ```

   It prints the tools, the search-docs hits, and a get-page byte count. If that looks right, the server is good — wire it into your editor next.

5. **Ask the agent** Restart the client and ask its agent something about your docs — it calls `search-docs`, then `get-page` on the best hit.

That's the whole loop: `leadtype generate` makes the artifacts, `leadtype mcp` serves them over stdio, your editor's agent calls the two tools. Nothing to host. (Want a full client UI to poke at? `npx @modelcontextprotocol/inspector leadtype mcp --artifacts ./public`.)

### Variant: a dependency's docs (`--package`)

Same stdio command, pointed at an installed package instead of a local dir — to read *that
version's* docs. The package must have been built with `leadtype generate --bundle --mcp` so its
tarball ships the artifacts (see [Bundle docs into a package](/docs/package-docs/bundle)):

```bash
leadtype mcp --package some-installed-lib
```

> `get-page` reads the `.md` mirror from disk, not the index. If the mirror was deleted, search still works but `get-page` reports the page missing — regenerate to restore it.

## Path 2 — a hosted endpoint (`createMcpHandler`)

`createMcpHandler` returns a Web-standard `(Request) => Promise<Response>` you
mount in your own route. **leadtype never owns the port, hosting, or auth** —
that's the host's job.

**Next (App Router)**

```ts
// app/mcp/route.ts
import { createMcpHandler } from "leadtype/mcp";

export const POST = createMcpHandler({ artifacts: "./public" });
```

**Generic Request → Response**

```ts
// Works on TanStack Start, SvelteKit, Nuxt, Astro, Workers, Deno, Bun.
import { createMcpHandler } from "leadtype/mcp";

const handler = createMcpHandler({ artifacts: "./public" });
// mount `handler(request)` on a POST route at /mcp
```

> ℹ️ **Info:**
> It runs stateless and returns JSON — it never opens an SSE stream. That's the whole transport: a client POSTs a JSON-RPC request and gets one JSON response. There are no sessions to track and nothing to keep alive between requests, which is exactly what makes the handler safe to drop onto serverless and edge routes. Artifacts load once and are reused; each request gets a fresh server instance so concurrent requests never share state. It reads the generated artifacts from disk (\<artifacts>/docs/), so run it where those files exist.

## When is it worth adding?

> ℹ️ **Info:**
> A docs MCP server earns its keep on large corpora, not small ones. If your whole doc set fits comfortably in an agent's context, llms-full.txt already hands it everything in one fetch — an MCP server just adds a round-trip. Reach for MCP when the docs are large enough that targeted retrieval beats dumping the corpus: SDK references, multi-product docs, anything an agent should search rather than read end-to-end.

These tools also don't make your *product* agent-callable — they let an agent
read your *docs*. Function-calling against your API is a separate surface that
lives in your own backend, not here.

## Tools

|Tool|Input|Returns|
|--|--|--|
|`search-docs`|`query: string`, `limit?: number` (default 5, max 50)|Ranked `{ title, urlPath, snippet }[]`|
|`get-page`|`urlPath: string` (e.g. a `search-docs` result, with or without `.md`)|Full page Markdown|
|`list-pages` *(opt-in)*|—|`{ title, urlPath, groups }[]` for every page|

Expose a different set with `tools` (CLI: `--tools search-docs,get-page,list-pages`;
API: `createMcpHandler({ tools: [...] })`). The default is `search-docs` +
`get-page` — the consensus minimal set.

## The SDK is an optional dependency

The MCP server is built on `@modelcontextprotocol/sdk` (v1.x), declared as an
**optional peer dependency** and imported lazily only when a server actually
runs. It stays out of installs that never touch MCP. If it's missing when you
start a server, you get an actionable `bun add @modelcontextprotocol/sdk`
message instead of a module-not-found crash — so install it alongside any app
that mounts `createMcpHandler` or runs `leadtype mcp`.

## MCP server vs. bash tools

This page is about a **standalone server** other clients connect to. If instead
you're building *your own* AI app and want the model to explore docs inside that
app, use the in-process [bash tools](/docs/search/agent-tools) — same index, no
server, no transport.
