io.github.cyanheads/mcp-ts-template

TypeScript template for building MCP servers with declarative tooling, observability, and auth.

122Apache-2.0devtools

Install

Config snippet generator goes here (5 client tabs)

README

<div align="center">
  <h1>@cyanheads/mcp-ts-core</h1>
  <p><b>Agent-native TypeScript framework for building MCP servers. Build tools, not infrastructure. Declarative definitions with auth, multi-backend storage, OpenTelemetry, and first-class support for Node.js and Cloudflare Workers.</b></p>
</div>

<div align="center">

[![Version](https://img.shields.io/badge/Version-0.1.29-blue.svg?style=flat-square)](./CHANGELOG.md) [![MCP Spec](https://img.shields.io/badge/MCP%20Spec-2025--11--25-8A2BE2.svg?style=flat-square)](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-11-25/changelog.mdx) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.27.1-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE)

[![TypeScript](https://img.shields.io/badge/TypeScript-^6.0.2-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-v1.3.2-blueviolet.svg?style=flat-square)](https://bun.sh/)

</div>

---

## What is this?

`@cyanheads/mcp-ts-core` is the infrastructure layer for TypeScript MCP servers. Install it as a dependency — don't fork it. You write tools, resources, and prompts; the framework handles transports, auth, storage, config, logging, telemetry, and lifecycle.

```ts
import { createApp, tool, z } from '@cyanheads/mcp-ts-core';

const greet = tool('greet', {
  description: 'Greet someone by name and return a personalized message.',
  annotations: { readOnlyHint: true },
  input: z.object({ name: z.string().describe('Name of the person to greet') }),
  output: z.object({ message: z.string().describe('The greeting message') }),
  handler: async (input) => ({ message: `Hello, ${input.name}!` }),
});

await createApp({ tools: [greet] });
```

That's a complete MCP server. Every tool call is automatically logged with duration, payload sizes, memory usage, and request correlation — no instrumentation code needed. `createApp()` handles config parsing, logger init, transport startup, signal handlers, and graceful shutdown.

## Features

- **Declarative definitions** — `tool()`, `resource()`, `prompt()` builders with Zod schemas. Framework handles registration, validation, and response formatting.
- **Unified Context** — handlers receive a single `ctx` object with `ctx.log` (request-scoped logging), `ctx.state` (tenant-scoped storage), `ctx.elicit` (user prompting), `ctx.sample` (LLM completion), and `ctx.signal` (cancellation).
- **Inline auth** — `auth: ['scope']` on definitions. No wrapper functions. Framework checks scopes before calling your handler.
- **Task tools** — `task: true` flag for long-running operations. Framework manages the full lifecycle (create, poll, progress, complete/fail/cancel).
- **Definition linter** — `validateDefinitions()` checks tools, resources, and prompts against MCP spec at startup. Name format, schema structure, `.describe()` presence, JSON Schema serializability, auth scope validity, annotation coherence, and URI template–params alignment. Also available as a standalone CLI (`lint:mcp`) and devcheck step.
- **Structured error handling** — Handlers throw freely; the framework catches, classifies, and formats. Error factories (`notFound()`, `validationError()`, `serviceUnavailable()`, etc.) for precise control when the code matters. Auto-classification from plain `Error` messages when it doesn't.
- **Multi-backend storage** — `in-memory`, `filesystem`, `Supabase`, `Cloudflare D1/KV/R2`. Swap providers via env var without changing tool logic. Cursor pagination, batch ops, TTL, tenant isolation.
- **Pluggable auth** — `none`, `jwt`, or `oauth` modes. JWT with local secret or OAuth with JWKS verification.
- **Observability** — Pino structured logging with optional OpenTelemetry tracing and metrics. Request IDs, trace correlation, tool execution metrics — all automatic.
- **Local + edge** — Same code runs on stdio, HTTP (Hono), and Cloudflare Workers. `createApp()` for Node, `createWorkerHandler()` for Workers.
- **Tiered dependencies** — Core deps always installed. Parsers, sanitization, scheduling, OTEL SDK, Supabase, OpenAI — optional peers. Install what you use.
- **Agent-first DX** — Ships `CLAUDE.md` with full exports catalog, patterns, and contracts. AI coding agents can build on the framework with zero ramp-up.

## Quick start

```bash
bunx @cyanheads/mcp-ts-core init my-mcp-server
cd my-mcp-server
bun install
```

That gives you a working project with `CLAUDE.md`, skills, config files, and a scaffolded `src/` directory. Open it in your editor, start your coding agent, and tell it what tools to build. The agent learns the framework from the included docs and skills — tool definitions, resources, services, testing patterns, all of it.

### What you get

Here's what tool definitions look like:

```ts
import { tool, z } from '@cyanheads/mcp-ts-core';

export const search = tool('