OpenCodeでMCPサーバーを自作する方法:カスタムツール追加ガイド
OpenCodeのMCPサーバーをTypeScriptで自作し、カスタムツールを追加する方法を解説。実用的なコード例と手順で拡張機能を実現。
はじめに
OpenCodeは、AIアシスタントと連携してコード生成や編集を効率化するツールですが、標準機能だけでは足りない場面もあります。そこで役立つのがMCP(Model Context Protocol)サーバーの自作です。MCPサーバーを自作することで、OpenCodeにカスタムツールや外部サービスとの連携機能を追加できます。本記事では、TypeScriptを使用してMCPサーバーを一から作成し、OpenCodeにカスタムツールを追加する手順を詳しく解説します。
MCPサーバーとは
MCP(Model Context Protocol)は、AIモデル(OpenCodeのAIアシスタント)と外部ツールやデータソースを接続するためのプロトコルです。MCPサーバーを自作することで、以下のようなことが可能になります。
OpenCodeは標準でいくつかのMCPサーバーをサポートしていますが、カスタムツールを追加するには自分でサーバーを実装する必要があります。
前提条件
ステップ1:プロジェクトのセットアップ
まずは新しいディレクトリを作成し、TypeScriptプロジェクトを初期化します。
mkdir my-mcp-server
cd my-mcp-server
npm init -y
npm install typescript @types/node ts-node --save-dev
npm install @modelcontextprotocol/sdk
@modelcontextprotocol/sdkはMCPサーバーを構築するための公式SDKです。次にTypeScriptの設定ファイルを作成します。
npx tsc --init
tsconfig.jsonを開き、outDirを./dist、rootDirを./srcに設定します。
ステップ2:基本的なMCPサーバーの実装
src/index.tsを作成し、以下のコードを記述します。これは最小限のMCPサーバーで、"hello"というツールを提供します。
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
// サーバーインスタンスを作成
const server = new Server(
{
name: "my-mcp-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
// ツール一覧を返すハンドラー
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "hello",
description: "挨拶を返すツール",
inputSchema: {
type: "object",
properties: {
name: {
type: "string",
description: "名前",
},
},
required: ["name"],
},
},
],
};
});
// ツール実行ハンドラー
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "hello") {
const name = request.params.arguments?.name as string;
return {
content: [
{
type: "text",
text: こんにちは、${name}さん!,
},
],
};
}
throw new Error(Unknown tool: ${request.params.name});
});
// 標準入出力トランスポートでサーバーを起動
const transport = new StdioServerTransport();
await server.connect(transport);
ステップ3:カスタムツールの追加
次に、実際に役立つカスタムツールを追加しましょう。例として、ファイルの内容を読み取るツールread_fileを実装します。
src/index.tsを編集し、ListToolsRequestSchemaのハンドラー内のtools配列に新しいツール定義を追加します。
tools: [
{
name: "hello",
description: "挨拶を返すツール",
inputSchema: {
type: "object",
properties: {
name: {
type: "string",
description: "名前",
},
},
required: ["name"],
},
},
{
name: "read_file",
description: "指定されたファイルの内容を読み取ります",
inputSchema: {
type: "object",
properties: {
path: {
type: "string",
description: "ファイルのパス",
},
},
required: ["path"],
},
},
],
次に、CallToolRequestSchemaのハンドラーにread_fileの処理を追加します。
if (request.params.name === "hello") {
// 既存の処理
} else if (request.params.name === "read_file") {
const path = request.params.arguments?.path as string;
try {
const fs = await import("fs/promises");
const content = await fs.readFile(path, "utf-8");
return {
content: [
{
type: "text",
text: content,
},
],
};
} catch (error: any) {
return {
content: [
{
type: "text",
text: エラー: ${error.message},
},
],
isError: true,
};
}
}
同様に、他にも便利なツールを追加できます。例えば、現在の日時を返すget_current_timeや、簡単な計算を行うcalculateなどが考えられます。
ステップ4:ビルドと実行
TypeScriptをコンパイルします。
npx tsc
これでdist/index.jsが生成されます。サーバーをテストするには、以下のコマンドで直接実行できます。
node dist/index.js
ただし、MCPサーバーは標準入出力を介して通信するため、通常はOpenCodeから呼び出します。
ステップ5:OpenCodeへの接続
OpenCodeの設定ファイル(通常は~/.opencode/config.json)を編集し、MCPサーバーを追加します。
{
"mcpServers": {
"my-mcp-server": {
"command": "node",
"args": ["/absolute/path/to/my-mcp-server/dist/index.js"],
"env": {}
}
}
}
パスは絶対パスで指定してください。設定後、OpenCodeを再起動すると、AIアシスタントがカスタムツールを認識し、使用できるようになります。
高度なカスタマイズ
ツールの入力スキーマを詳細に設定する
JSON Schemaに従って、より複雑な入力スキーマを定義できます。例えば、read_fileにエンコーディングオプションを追加する場合:
inputSchema: {
type: "object",
properties: {
path: { type: "string" },
encoding: { type: "string", enum: ["utf-8", "ascii", "base64"] },
},
required: ["path"],
}
リソースの提供
ツールだけでなく、リソースを提供することもできます。リソースは読み取り専用のデータで、AIが参照できます。
import { ListResourcesRequestSchema, ReadResourceRequestSchema } from "@modelcontextprotocol/sdk/types.js";
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
resources: [
{
uri: "file:///config.json",
name: "設定ファイル",
mimeType: "application/json",
},
],
}));
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
if (request.params.uri === "file:///config.json") {
const content = JSON.stringify({ key: "value" });
return {
contents: [
{
uri: request.params.uri,
mimeType: "application/json",
text: content,
},
],
};
}
throw new Error("Resource not found");
});
エラーハンドリングの改善
ツール実行時にエラーが発生した場合、isError: trueを設定してエラーメッセージを返すことで、AIが適切に処理できます。
トラブルシューティング
サーバーが認識されない
~/.opencode/logs/)TypeScriptのエラー
@modelcontextprotocol/sdkのバージョンが最新か確認tsconfig.jsonでmoduleResolutionをnodeに設定まとめ
OpenCodeでMCPサーバーを自作することで、AIアシスタントの機能を大幅に拡張できます。TypeScriptとSDKを使えば、複雑なツールも比較的簡単に実装可能です。今回紹介した手順をベースに、あなたのワークフローに合わせたカスタムツールを開発してみてください。
次のステップとして、外部APIを呼び出すツールやデータベース操作ツールなどに挑戦すると、さらにOpenCodeの活用範囲が広がります。