@cyanheads/mcp-ts-core
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 Bun/Node/Cloudflare Workers.
______________________________________________________________________
这是什么?
@cyanheads/mcp-ts-core 是TypeScript MCP服务器的基础架构层。将其作为依赖项安装——不要分叉。您的代理与您合作,为您的服务器设计和构建工具、资源和提示。
该框架处理管道:传输、身份验证、配置、日志记录、遥测等。用构建器定义你的域逻辑,让框架来处理其余的事情。
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'),
}),
errors: [
{
reason: 'name_blocked',
code: JsonRpcErrorCode.Forbidden,
when: 'The provided name is on the configured block list.',
recovery: 'Use a different name.',
},
],
handler: async (input, ctx) => {
if (isBlocked(input.name)) throw ctx.fail('name_blocked', `"${input.name}" is blocked`);
return { message: `Hello, ${input.name}!` };
},
});
await createApp({ tools: [greet] });这是一个完整的MCP服务器。每个工具调用都会自动记录持续时间、有效载荷大小和请求相关性,不需要插装代码。 createApp() 处理配置解析、记录器初始化、传输启动、信号处理程序和优雅关闭。
快速开始
bunx @cyanheads/mcp-ts-core init my-mcp-server
cd my-mcp-server
bun install你得到一个脚手架项目 CLAUDE.md、代理技能和a src/ 树准备好了你的工具。基础设施——传输、身份验证、存储、遥测、生命周期、linting——存在于 node_modules剩下的就是域:要包装哪些API,要公开哪些工作流。
启动你的编码代理(即Claude Code、Codex)并描述你想要什么。代理人知道从那里该怎么办。所包含的代理技能涵盖了整个周期: setup, design-mcp-server脚手架、测试, security-pass, release-and-publish, maintenance,&更多。
你得到了什么
以下是工具定义的样子:
import { tool, z } from '@cyanheads/mcp-ts-core';
export const search = tool('search', {
description: 'Search for items by query.',
input: z.object({
query: z.string().describe('Search query'),
limit: z.number().default(10).describe('Max results'),
}),
output: z.object({
items: z.array(z.string()).describe('Search results'),
}),
async handler(input) {
const results = await doSearch(input.query, input.limit);
return { items: results };
},
});资源:
import { resource, z } from '@cyanheads/mcp-ts-core';
export const itemData = resource('items://{itemId}', {
description: 'Retrieve item data by ID.',
params: z.object({
itemId: z.string().describe('Item ID'),
}),
async handler(params, ctx) {
return await getItem(params.itemId);
},
});在编译时键入的故障模式契约,会向客户端显示模型可以采取行动的恢复提示:
import { tool, z } from '@cyanheads/mcp-ts-core';
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
export const search = tool('search', {
// ...input, output as above
errors: [
{
reason: 'no_match',
code: JsonRpcErrorCode.NotFound,
when: 'The query returned zero items from the upstream index.',
recovery: 'Broaden the query — close matches by edit distance are in `data.suggestions`.',
},
],
async handler(input, ctx) {
const { items, suggestions } = await doSearch(input.query, input.limit);
if (items.length === 0) throw ctx.fail('no_match', `No matches for "${input.query}"`, { suggestions });
return { items };
},
});过梁交叉检查 errors[] 针对处理程序主体,合同发布在 tools/list 因此,客户端可以预览故障模式,以及 data.recovery.hint 镜子照进标记处 content[] 所以只有工具的客户端也能看到它。
一切都通过注册 createApp() 在您的入口点:
await createApp({
name: 'my-mcp-server',
version: '0.1.0',
tools: allToolDefinitions,
resources: allResourceDefinitions,
prompts: allPromptDefinitions,
instructions: 'Brief composition hints for the model.', // optional, sent on every `initialize`
});它也适用于Cloudflare Workers createWorkerHandler() --相同的定义,不同的切入点。
特性
- 声明性定义 —
tool(),resource(),prompt()使用Zod模式的构建者;appTool()/appResource()添加交互式HTML UI。 - 服务器级定位 —
instructions上createApp/createWorkerHandler骑每initialize对于模型。跨工具组合提示、区域注释、范围指导——不会在每个工具描述中泄露文本。 - 统一上下文 --一个
ctx用于日志记录、租户范围的存储、启发、采样、取消和任务进度。 - 认证 —
auth: ['scope']在定义上,在分派之前进行检查(没有包装器代码)。模式:none,jwt,或oauth(当地秘密或JWKS)。 - 任务工具 —
task: true对于长期运行的操作;框架管理创建/轮询/进度/完成/取消。 - 过梁定义 --在启动时验证名称、模式、身份验证范围、注释、格式奇偶校验和跨供应商JSON模式可移植性。独立通过
lint:mcp或devcheck。 - 键入错误合同 --声明
errors: [{ reason, code, when, recovery, retryable? }]处理程序会得到一个类型化的ctx.fail(reason, …).合同发布于tools/list因此,客户端可以预览故障模式;门楣对搬运工进行交叉检查。工厂(notFound(),httpErrorFromResponse(),…)掩护临时投掷;朴素Error自动分类。 - 多后端存储 —
in-memory,文件系统,Supabase,Cloudflare D1/KV/R2。通过env-var进行交换;处理程序不会改变。 - DataCanvas(可选) --由DuckDB支持的第3层SQL/分析工作区。从上游API注册表格数据,在注册的表中运行SQL,导出CSV/Parquet/JSON。代币共享模型(不透明
canvas_id)用于多智能体协作;滑动TTL+每个租户范围。通过以下方式选择加入CANVAS_PROVIDER_TYPE=duckdb;未关闭工人。 - 可观测性 --引脚记录+可选的OpenTetry跟踪/指标。自动请求相关性和工具度量。
- 分层依赖关系 --解析器、OTEL SDK、Supabase、OpenAI作为可选对等体。安装你使用的东西。
- 代理优先DX --船舶
CLAUDE.md/AGENTS.md代码库记录在Agent Skills中。
服务器结构
my-mcp-server/
src/
index.ts # createApp() entry point
worker.ts # createWorkerHandler() (optional)
config/
server-config.ts # Server-specific env vars
services/
[domain]/ # Domain services (init/accessor pattern)
mcp-server/
tools/definitions/ # Tool definitions (.tool.ts)
resources/definitions/ # Resource definitions (.resource.ts)
prompts/definitions/ # Prompt definitions (.prompt.ts)
package.json
tsconfig.json # extends @cyanheads/mcp-ts-core/tsconfig.base.json
CLAUDE.md # Points to core's CLAUDE.md for framework docs不 src/utils/,没有 src/storage/,没有 src/types-global/,没有 src/mcp-server/transports/ --基础设施生活在 node_modules.
配置
所有核心配置都经过环境变量的Zod验证。特定于服务器的配置使用单独的Zod模式和延迟解析。
| 变量 | 描述 | 默认值 |
|---|---|---|
MCP_TRANSPORT_TYPE | stdio 或 http | stdio |
MCP_HTTP_PORT | HTTP服务器端口 | 3010 |
MCP_HTTP_HOST | HTTP服务器主机名 | 127.0.0.1 |
MCP_AUTH_MODE | none, jwt,或 oauth | none |
MCP_AUTH_SECRET_KEY | JWT签名密钥(必需 jwt 模式) | -- |
STORAGE_PROVIDER_TYPE | in-memory, filesystem, supabase, cloudflare-d1/kv/r2 | in-memory |
CANVAS_PROVIDER_TYPE | none 或 duckdb (第3级,可选对等部门 @duckdb/node-api) | none |
OTEL_ENABLED | 启用开放遥测 | false |
OPENROUTER_API_KEY | OpenRouter LLM API密钥 | - |
看 CLAUDE.md 以获取完整的配置参考。
API概述
入口点
| 功能 | 目的 |
|---|---|
createApp(options) | Node.js服务器——处理整个生命周期 |
createWorkerHandler(options) | Cloudflare员工-退货 { fetch, scheduled } |
建筑者
| 生成器 | 用法 |
|---|---|
tool(name, options) | 定义一个工具 handler(input, ctx) |
resource(uriTemplate, options) | 使用定义资源 handler(params, ctx) |
prompt(name, options) | 使用定义提示 generate(args) |
appTool(name, options) | 定义一个自动填充的MCP应用程序工具 _meta.ui |
appResource(uriTemplate, options) | 使用正确的MIME类型定义MCP Apps HTML资源 _meta.ui 读取内容的镜像 |
上下文
处理程序收到统一的 Context 对象:
| 属性 | 类型 | 描述 |
|---|---|---|
ctx.log | ContextLogger | 请求范围记录器(自动关联requestId、traceId、tenantId) |
ctx.state | ContextState | 租户范围的键值存储 |
ctx.elicit | Function? | 询问用户输入(当客户支持时) |
ctx.sample | Function? | 向客户请求LLM完成 |
ctx.signal | AbortSignal | 取消信号 |
ctx.notifyResourceUpdated | Function? | 通知已订阅的客户端资源已更改 |
ctx.notifyResourceListChanged | Function? | 通知客户端资源列表已更改 |
ctx.progress | ContextProgress? | 任务进度报告(当 task: true) |
ctx.requestId | string | 唯一请求ID |
ctx.tenantId | string? | 租户ID(JWT tid 索赔,或 'default' 用于stdio和HTTP+MCP_AUTH_MODE=none) |
子路径导出
import { createApp, tool, resource, prompt } from '@cyanheads/mcp-ts-core';
import { createWorkerHandler } from '@cyanheads/mcp-ts-core/worker';
import { McpError, JsonRpcErrorCode, notFound, serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
import { checkScopes } from '@cyanheads/mcp-ts-core/auth';
import { markdown, fetchWithTimeout } from '@cyanheads/mcp-ts-core/utils';
import { OpenRouterProvider, GraphService } from '@cyanheads/mcp-ts-core/services';
import type { DataCanvas, CanvasInstance } from '@cyanheads/mcp-ts-core/canvas';
import { validateDefinitions } from '@cyanheads/mcp-ts-core/linter';
import { createMockContext } from '@cyanheads/mcp-ts-core/testing';
import { fuzzTool, fuzzResource, fuzzPrompt } from '@cyanheads/mcp-ts-core/testing/fuzz';看 CLAUDE.md/代理商.md 以获取完整的出口参考。
例子
这 examples/ 目录包含一个通过公共导出使用核心的参考服务器,演示了所有模式:
| 工具 | 图案 |
|---|---|
template_echo_message | 基本工具 format, auth |
template_cat_fact | 外部API调用,错误工厂 |
template_madlibs_elicitation | ctx.elicit 用于交互式输入 |
template_code_review_sampling | ctx.sample 完成法学硕士 |
template_image_test | 图像内容块 |
template_async_countdown | task: true 随着 ctx.progress |
template_data_explorer | 通过链接UI资源的MCP应用程序 appTool()/appResource() 建设者 |
测试
import { createMockContext } from '@cyanheads/mcp-ts-core/testing';
import { myTool } from '@/mcp-server/tools/definitions/my-tool.tool.js';
const ctx = createMockContext({ tenantId: 'test-tenant' });
const input = myTool.input.parse({ query: 'test' });
const result = await myTool.handler(input, ctx);createMockContext() 提供短梗 log, state,以及 signal.通行证 { tenantId } 对于状态操作, { sample } 对于LLM嘲讽, { elicit } 为了引发嘲笑, { progress: true } 任务工具。
模糊测试
通过以下方式进行模式感知模糊测试 fast-check。从Zod模式和对抗有效载荷(原型污染、注入字符串、类型混淆)生成有效输入,以验证处理程序不变量。
import { fuzzTool } from '@cyanheads/mcp-ts-core/testing/fuzz';
const report = await fuzzTool(myTool, { numRuns: 100 });
expect(report.crashes).toHaveLength(0);
expect(report.leaks).toHaveLength(0);
expect(report.prototypePollution).toBe(false);也出口 fuzzResource, fuzzPrompt, zodToArbitrary,以及 ADVERSARIAL_STRINGS 用于基于自定义属性的测试。
文档
- CLAUDE.md/代理商.md --框架参考:导出目录、模式、上下文接口、错误代码、身份验证、配置、测试。在npm包中发货。
- 文档/遥测/ --OpenTetry:框架发出的跨度、指标和属性的完整目录(可观测性.md),再加上Grafana仪表板示例和Datadog、New Relic、Honeycomb的供应商无关查询配方(仪表板.md).
- 更改日志.md --版本历史记录-基于目录,便于代理解析。每个条目都包括摘要、迁移说明和提交/问题链接。
发展
bun run rebuild # clean + build (scripts/clean.ts + scripts/build.ts)
bun run devcheck # full gate: lint/format, typecheck, MCP defs, framework antipatterns, docs/skills/changelog sync, tests, audit, outdated, secrets/TODO scan
bun run lint:mcp # validate MCP definitions against spec
bun run test:all # vitest: unit + Workers pool + integration贡献
欢迎问题和拉取请求。提交前运行检查:
bun run devcheck
bun run test:all许可证
Apache 2.0——请参阅 许可证.
______________________________________________________________________
Sponsor this project • Buy me a coffee
