Skip to main content
Glama
EuKennedy

mcpkit

by EuKennedy

mcpkit

ci release license node

ボイラープレートなしでMCPサーバーを構築するためのTypeScriptツールキット。

Zodスキーマとハンドラーを使ってツールを定義するだけ。スキーマ生成、入力バリデーション、エラーエンベロープ、トランスポートの配線など、すべてが完了したModel Context Protocolサーバーが手に入ります。

import { defineServer, defineTool } from 'mcpkit';
import { z } from 'zod';

const server = defineServer({
  name: 'demo',
  version: '0.1.0',
  tools: [
    defineTool({
      name: 'add',
      description: 'Add two numbers.',
      input: z.object({ a: z.number(), b: z.number() }),
      handler: ({ a, b }) => `${a + b}`,
    }),
  ],
});

await server.start();

これは、実用的で機能するMCPサーバーです。mcpkit devで実行し、MCP対応クライアントを接続してください。


なぜこれが存在するのか

公式SDKでMCPサーバーを書くことは可能ですが、毎回同じような配線作業が必要になります:

  • ツールリストを1箇所で宣言する

  • 各ツールに対して個別のJSONスキーマを宣言する

  • 呼び出しハンドラー内でツール名によるswitch文を書く

  • ハンドラーの戻り値をプロトコルのコンテンツエンベロープに変換する

  • トランスポートを配線する

  • エラーをキャッチして適切なisError形式に変換する

mcpkitは、これらすべてをdefineTool + defineServerに集約します。スキーマはZod型から生成され、バリデーションはハンドラーの前に実行され、エラーは適切なプロトコルレスポンスに変換され、文字列の戻り値はテキストコンテンツブロックになります。あなたは実際に重要なレイヤー(ツールが何をするか)に集中し、重要でないレイヤーをスキップできます。

Related MCP server: xmcp Application

比較:なし vs あり

同じツールを、生のSDKで書いた場合とmcpkitで書いた場合の比較:

const server = new Server(
  { name: 'demo', version: '0.1.0' },
  { capabilities: { tools: {} } },
);

server.setRequestHandler(
  ListToolsRequestSchema,
  async () => ({
    tools: [
      {
        name: 'add',
        description: 'Add two numbers.',
        inputSchema: {
          type: 'object',
          properties: {
            a: { type: 'number' },
            b: { type: 'number' },
          },
          required: ['a', 'b'],
        },
      },
    ],
  }),
);

server.setRequestHandler(
  CallToolRequestSchema,
  async (req) => {
    if (req.params.name === 'add') {
      const { a, b } = req.params.arguments as {
        a: number; b: number;
      };
      return {
        content: [{ type: 'text', text: `${a + b}` }],
      };
    }
    throw new Error('unknown tool');
  },
);

await server.connect(new StdioServerTransport());
const server = defineServer({
  name: 'demo',
  version: '0.1.0',
  tools: [
    defineTool({
      name: 'add',
      description: 'Add two numbers.',
      input: z.object({
        a: z.number(),
        b: z.number(),
      }),
      handler: ({ a, b }) => `${a + b}`,
    }),
  ],
});

await server.start();

右側の列は、同じワイヤーレベルの動作に加え、入力バリデーション、型安全なハンドラー引数、キャッチされない例外に対するisErrorエンベロープを備えています。

インストール

npm install mcpkit zod

または、新規プロジェクトをスキャフォールドします(最初のサーバー作成にはこちらを推奨):

npx mcpkit create my-server
cd my-server
npm run dev

stdioサーバー、3つのサンプルツール、厳格モードに設定されたtsconfig.jsonを含む小さなプロジェクトが作成されます。サンプルツールを自分のツールに置き換えてリリースしてください。

CLI

mcpkit create [target]   scaffold a new server from a template
mcpkit dev               run with hot reload (uses tsx under the hood)
mcpkit build             compile to dist/
mcpkit inspect           launch the official inspector against your server

createコマンドは現在4つのテンプレートを提供しています:

テンプレート

内容

stdio-basic

stdio経由のローカルMCPサーバー。ほとんどのクライアントがこれを使用します。

http-streaming

ストリーム可能なHTTPトランスポート経由のネットワーク到達可能なサーバー。

with-fetch

HTTPフェッチツールを備えたstdioサーバー(タイムアウト設定済み)。

with-sqlite

SQLiteバックエンドのCRUD例を備えたstdioサーバー(better-sqlite3, WAL)。

API

defineTool

defineTool({
  name: string,            // [a-zA-Z0-9_-]+
  description: string,     // shown to the client / LLM
  input: z.ZodType,        // Zod schema; converted to JSON Schema for you
  handler: (input) => string | ToolContent | ToolContent[] | { content, isError? }
})

ハンドラーの入力はz.inferを通じて完全に型付けされます。文字列を返すと、単一のテキストコンテンツブロックとしてラップされます(一般的なケース)。ハンドラー内で例外を投げると、自動的にisError: trueレスポンスに変換されます。エラーメッセージをカスタマイズしたい場合は、defineServerにonToolErrorハンドラーを渡してください。

defineServer

defineServer({
  name: string,
  version: string,
  description?: string,
  tools?: ToolDefinition[],
  resources?: ResourceDefinition[],
  prompts?: PromptDefinition[],
  onToolError?: (err, toolName) => ToolResult,
  onEvent?: (event: ServerEvent) => void,
})

DefinedServerを返し、以下のメソッドを提供します:

  • .start({ transport: 'stdio' }) — トランスポートを接続してサーバーを起動します。

  • .connect(transport) — 自分で構築したトランスポートインスタンス(HTTP、カスタム、Transportのように振る舞うものなら何でも)を接続します。

  • .stop() — アクティブなトランスポートと基盤となるサーバーを閉じます。

  • .raw — 特殊な操作が必要な場合の、基盤となるSDKのServerインスタンス。

リソースとプロンプト

宣言的な形式は同じです:

defineResource({
  uri: 'file:///etc/hosts',
  name: 'hosts',
  mimeType: 'text/plain',
  read: async () => ({ text: await fs.readFile('/etc/hosts', 'utf8') }),
});

definePrompt({
  name: 'summarize',
  description: 'Summarize a chunk of text.',
  arguments: z.object({ text: z.string() }),
  build: ({ text }) => ({
    messages: [{ role: 'user', content: { type: 'text', text: `Summarize:\n${text}` } }],
  }),
});

可観測性

onEventは、ツール呼び出し、リソース読み取り、プロンプト取得のすべてに対して構造化されたコールバックを受け取ります。開始時間、終了時間、レイテンシ、エラー、呼び出しごとのrequestIdが含まれます。pino、console、OpenTelemetry、自作の集約ツールなど、何にでも接続できます。シンプルなケース向けに組み込み機能もあります:

import { defineServer, consoleLogger, jsonLogger } from 'mcpkit';

const server = defineServer({
  name: 'demo',
  version: '0.1.0',
  onEvent: consoleLogger(),    // → pretty stderr lines
  // or: onEvent: jsonLogger() // → one JSON object per line, on stderr
  tools: [...]
});

ログは常にstderrに出力されます。stdoutはstdioトランスポートのプロトコル通信用に予約されています。

テスト

mcpkit/testingは、メモリ内トランスポートを介してサーバーと通信するプロセス内クライアントを公開します。サブプロセスもstdioパイプも、不安定なプロセス終了もありません。実際のコンシューマーが使用するのと同じクライアントを、RAM経由でルーティングするだけです。

import { describe, it, expect } from 'vitest';
import { createTestClient, expectToolError, snapshotTools } from 'mcpkit/testing';
import { server } from '../src/index.js';

describe('add', () => {
  it('adds', async () => {
    const client = await createTestClient(server);
    const result = await client.callTool('add', { a: 2, b: 3 });
    expect(result.text).toBe('5');
    expect(result.isError).toBe(false);
    await client.close();
  });

  it('rejects bad input', async () => {
    const client = await createTestClient(server);
    const text = await expectToolError(client, 'add', { a: 'nope', b: 1 });
    expect(text).toMatch(/invalid/i);
    await client.close();
  });

  it("doesn't drift its public surface", () => {
    expect(snapshotTools(server)).toMatchSnapshot();
  });
});

知っておくべき設計上の選択

生のJSONスキーマではなく、Zodを使用。 型を一度書くだけで済みます。バリデーション、プロトコル用の生成済みJSONスキーマ、ハンドラー用のTypeScript推論がすべて同じソースから得られます。3つの定義を同期させ続けることこそが、このプロジェクトが排除しようとしているボイラープレートです。

エラーは例外ではなく値。 ハンドラーが例外を投げると、isError: trueのコンテンツエンベロープになります。クライアントはトランスポートレベルの失敗ではなく、意味のあるレスポンスを受け取ります。エラーを自分でフォーマットしたい場合は、onToolErrorをオーバーライドしてください。

トランスポートに依存しないコア。 同じdefineServerがstdio、ストリーム可能なHTTPトランスポート、メモリ内テストトランスポート、その他SDKのTransportインターフェースを実装するあらゆるものの上で動作します。http-streamingテンプレートがその配線方法を示しています。

デフォルトで厳格モード。 テンプレートはstrict: trueおよびnoUncheckedIndexedAccessで提供されます。ライブラリ自体も同じ設定でコンパイルされます。型に穴を見つけた場合は、それはバグです。

リスナーエラーは飲み込まれる。 onEventハンドラーが例外を投げても、ツール呼び出しは動作し続けます。可観測性のバグが負荷を支えるべきではありません。

FAQ

mcpkitに永遠にロックインされますか? いいえ。すべてのヘルパーには脱出ハッチがあります。server.rawで基盤となるSDKのServerにアクセスでき、キットがまだモデル化していない機能が必要な場合は、直接setRequestHandlerを呼び出すことができます。このキットは上位レイヤーであり、代替品ではありません。

なぜZod 4ではなくZod 3なのですか? Zod 4は素晴らしいですが、エコシステム(特にzod-to-json-schema)がまだ追いついていません。本番環境で安定したら移行する予定です。すでにZod 4を使用している場合、スキーマインターフェースは十分に互換性があります。問題が発生した場合はIssueを報告してください。

ツールだけでなく、リソースやプロンプトもサポートしていますか? はい。defineResourceとdefinePromptはファーストクラスです。ツールほど頻繁には使用されないため、ほとんどの例ではツールを前面に出していますが、配線は同一です。

ストリーム可能なHTTP、SSE、両方ですか? ストリーム可能なHTTPです。古いHTTP+SSE形式はSDKに残っていますが、段階的に廃止されています。それが必要な理由がある場合は、defineServerはトランスポートに依存しないため、.connect()経由で任意のTransportインスタンスを渡すことができます。

本番環境で使用できますか? ライブラリは小さく、表面積は意図的に狭く設計されています。公式SDKが基盤の重い処理を行っています。バージョンを固定し、ツールのテストを書き(プロセス内クライアントがこれを容易にします)、準備完了です。

これではないもの

  • ホスト型サービスではありません。自分でビルドし、デプロイします。

  • エージェントフレームワークではありません。MCPのサーバー側を構築するものであり、クライアントではありません。

  • ドメインに関する意見を持ちません。ツールは関数であり、それが何をするかはあなたの問題です。

ロードマップ

  • さらなるテンプレート(OAuth保護、エッジランタイム、Drizzle/Postgres)。

  • lint + パッケージ化 + リリースタグ付けを行うmcpkit publishコマンド。

  • よりリッチなテストヘルパー(ツールの入力のファジング、ベースラインに対するスキーマ差分)。

  • onEvent用のオプションのOpenTelemetryアダプター。

不足しているものがあれば、Issueを開いて希望するAPIのスケッチを提示してください。

ライセンス

MIT。

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A TypeScript-based template for rapidly developing MCP servers with modular tool architecture, built-in validation using Zod schemas, and comprehensive error handling.
    2 npm
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A template for building MCP servers with automatic tool discovery using TypeScript and Zod schemas, supporting HTTP and STDIO transports.
    8,467 npm
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    A production-ready boilerplate for building MCP servers, featuring TypeScript, Zod validation, rate limiting, and example tools like echo and fetch_url, enabling quick setup of custom MCP servers.
    2
    1
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    A starter template for building MCP servers with Zod-validated tools, unit tests, and MCP Inspector integration. It enables developers to quickly scaffold and develop protocol-compliant servers with a one-command dev loop.
    2
    24 npm
    MIT