TypeScriptでMCPサーバーを自作してClaudeに繋ぐ

TypeScriptでMCPサーバーを自作してClaudeに繋ぐ

※本記事にはプロモーション(広告・アフィリエイトリンク)を含みます。

MCPサーバーを自作して Claude に繋ぐと、Claude が直接触れないデータや外部システムを会話の中で操作できるようになります。この記事では TypeScript で最小構成の MCP サーバーを作り、Claude Desktop から接続するまでを手順を追って説明します。

MCPとは何か、なぜ自作するのか

MCP(Model Context Protocol)は Anthropic が策定したオープンプロトコルで、Claude などの AI モデルが外部ツール・データソースと標準的な方法でやり取りするための仕様です。公式 SDK(TypeScript 版・Python 版)が公開されており、コミュニティ製サーバーも多数あります。

ただし既製サーバーでは自分のシステムに繋げないケースがあります。社内 API・ローカルの SQLite・独自フォーマットのファイル群など、手元に固有データがある場合は自作するしかありません。

MCP サーバーが提供できるのは公式仕様上、以下の3種類です。

種別 概要 典型的な用途
Tools Claude が呼び出せる関数 API 呼び出し、DB 検索、ファイル操作
Resources Claude が参照できるデータ ドキュメント、ログ
Prompts 再利用可能なテンプレート よく使う指示のセット

この記事では最も基本的な Tools を1つ実装します。

事前準備

  • Node.js 18 以上
  • Claude Desktop(無料プランでも MCP 接続は利用できます。執筆時点での仕様です)
  • TypeScript の基本的な読み書き
mkdir my-mcp-server && cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk
npm install -D typescript tsx @types/node

tsx を使うのはコンパイルせずに TypeScript を直接実行するためです。本番運用では tsc でビルドして node dist/server.js 起動が安定しますが、まず動かすことを優先します。

MCPサーバーを実装する

src/server.ts を作成します。「指定したファイルの内容を返す」ツールを1つ実装します。

import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { readFileSync } from 'fs';
import { resolve } from 'path';

const server = new Server(
  { name: 'my-mcp-server', version: '1.0.0' },
  { capabilities: { tools: {} } }
);

server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: 'read_file',
      description: '指定したパスのファイル内容を返す',
      inputSchema: {
        type: 'object' as const,
        properties: {
          path: { type: 'string', description: '読み込むファイルの絶対パス' },
        },
        required: ['path'],
      },
    },
  ],
}));

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;
  if (name === 'read_file') {
    const content = readFileSync(resolve(args?.path as string), 'utf-8');
    return { content: [{ type: 'text' as const, text: content }] };
  }
  throw new Error(`未知のツール: ${name}`);
});

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
}
main().catch(console.error);

重要:console.log は stdout に書き出すため stdio トランスポートを壊します。 デバッグログは必ず console.error を使ってください。

Claude Desktopに接続する

Claude Desktop の設定ファイルにサーバーを登録します。

  • macOS:~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows:%APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "my-mcp-server": {
      "command": "npx",
      "args": ["tsx", "/Users/yourname/my-mcp-server/src/server.ts"]
    }
  }
}

パスは絶対パスで指定してください。 相対パスは動きません。設定を保存したら Claude Desktop を完全に終了(Cmd+Q / タスクトレイから Quit)してから再起動します。入力欄にハンマーアイコンが出れば接続成功です。

よくあるつまずきポイント

サーバーが認識されない

Claude Desktop を完全終了してから再起動してください。設定ファイルの JSON に構文エラー(末尾コンマなど)があっても Claude Desktop はエラーを出さず無視することがあります。JSONLint で確認してから再起動するのが確実です。

ツール呼び出しでエラーになる

@modelcontextprotocol/sdk が古いとスキーマが異なる場合があります。npm list @modelcontextprotocol/sdk でバージョンを確認し、npm の最新版に揃えてください。inputSchema の type に as const が必要かどうかは TypeScript の設定によって異なります。コンパイルエラーが出た場合は付け外しして確認してください。

Claude Code CLIと組み合わせる

claude CLI(Claude Code)でも MCP サーバーを利用できます。プロジェクトの .claude/ ディレクトリ配下に設定を置く方法がありますが、バージョンによって詳細が変わるため公式ドキュメントを参照してください。

まとめ

ステップ 内容
1 @modelcontextprotocol/sdk と tsx をインストール
2 ListToolsRequestSchema と CallToolRequestSchema のハンドラを実装
3 claude_desktop_config.json に絶対パスで登録
4 Claude Desktop を完全終了→再起動
5 ハンマーアイコンを確認してツール呼び出しをテスト

read_file ツールが動いたら、自分のシステムに合わせてツールを追加していきます。たとえば Prisma + SQLite を自動バックアップしながら運用している DB に接続するツールを追加すれば、Claude との会話でデータを直接参照・操作できるようになります。

この記事で触れたもの

よくある質問

MCPサーバーを自作するのにClaude APIキーは必要ですか?

Claude Desktopを使う場合、APIキーは不要です。Claude Desktopのアカウントがあれば接続できます。Claude Code CLIの場合も同様ですが、環境によって異なるため使用バージョンの公式ドキュメントをご確認ください。

PythonでMCPサーバーを書くことはできますか?

可能です。公式の `mcp` Pythonパッケージが提供されており、TypeScript版と同等の機能を持ちます。設定ファイルへの登録方法は同じで、commandに `python` または `uv run` を指定します。

MCPサーバーをリモートで動かすことはできますか?

公式仕様ではSSEトランスポートを使ったリモート接続もサポートされています。ただしClaude Desktopのバージョンによって対応状況が異なるため、執筆時点ではstdio(ローカル起動)が最も安定した方法です。