メインコンテンツまでスキップ

MCP を拡張する方法

このページでは 2 つの拡張ガイドを提供します。1 つは Elftia に新しい MCP トランスポートタイプを追加する方法、もう 1 つは Elftia と連携するカスタム MCP サーバーを作成する方法です。

ガイド 1: 新しいトランスポートタイプを追加する

Stdio/SSE/HTTP 以外のトランスポート方式(WebSocket、gRPC など)をサポートする必要がある場合は、次のファイルを変更します。

変更チェックリスト

ステップファイル変更内容
1packages/desktop/app/shared/contracts/mcp-types.tsMcpServerTransport 型を拡張
2packages/desktop/app/main/services/capabilities/tools/mcp-users/McpService.tscreateTransport() に新しい分岐を追加
3packages/desktop/app/main/services/routers/McpRouter.tsmcpAddSchema の type enum を拡張
4packages/renderer/src/features/settings/components/tabs/tools-tab/types.tsフロントエンドの型を更新
5packages/renderer/src/features/settings/components/tabs/tools-tab/McpServerForm.tsxフォームオプションを追加
6i18n files新しいトランスポートタイプの表示名を追加

ステップ 1: 型を拡張する

mcp-types.ts に新しいトランスポートタイプの値を追加します。

export type McpServerTransport = 'stdio' | 'http' | 'sse' | 'websocket';

McpServerConfig に新しいフィールドが必要かどうかも確認します。

export type McpServerConfig = {
command?: string;
args?: string[];
env?: Record<string, string>;
url?: string;
headers?: Record<string, string>;
transport?: string;
// Add new fields if needed
wsProtocol?: string;
};

ステップ 2: トランスポート層を実装する

McpService.tscreateTransport() メソッドに新しい case 分岐を追加します。

private async createTransport(server: McpServerRecord) {
switch (server.type) {
case 'stdio':
// ...
case 'sse':
// ...
case 'http':
// ...
case 'websocket':
if (!server.config.url) {
throw new Error('WebSocket server requires url');
}
// Use your WebSocket transport implementation
return new WebSocketClientTransport(
new URL(server.config.url),
{ headers: server.config.headers || {} }
);
default:
throw new Error(`Unsupported transport type: ${server.type}`);
}
}

要件: トランスポート実装は MCP SDK の Transport インターフェイスに準拠し、Client.connect() と連携して動作する必要があります。

ステップ 3: IPC バリデーションを更新する

McpRouter.ts の Zod schema を拡張します。

const mcpAddSchema = z.object({
// ...
type: z.enum(['stdio', 'http', 'sse', 'websocket']),
// ...
});

ステップ 4-5: フロントエンドを更新する

McpServerForm.tsx のトランスポートタイプセレクターにオプションを追加します。

options={[
{ value: 'stdio', label: t('...stdio') },
{ value: 'sse', label: t('...sse') },
{ value: 'http', label: t('...http') },
{ value: 'websocket', label: t('...websocket') },
]}

新しいトランスポートタイプの要件に応じて、対応する設定フォームフィールド(URL、プロトコル選択など)を追加します。

ステップ 6: 国際化

locales/{en,zh,ja}/settings/tools.json に新しいトランスポートタイプの表示名を追加します。

ガイド 2: カスタム MCP サーバーを作成する

Elftia と連携する MCP サーバーを作成するには、MCP プロトコル仕様に従う必要があります。

最小構成の Stdio サーバー(Node.js)

import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

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

// Register tool list
server.setRequestHandler('tools/list', async () => ({
tools: [
{
name: 'hello',
description: 'Return a greeting',
inputSchema: {
type: 'object',
properties: {
name: { type: 'string', description: 'Name to greet' }
},
required: ['name']
}
}
]
}));

// Handle tool calls
server.setRequestHandler('tools/call', async (request) => {
if (request.params.name === 'hello') {
const name = request.params.arguments?.name ?? 'World';
return {
content: [
{ type: 'text', text: `Hello, ${name}!` }
]
};
}
return {
content: [{ type: 'text', text: 'Unknown tool' }],
isError: true
};
});

// Start
const transport = new StdioServerTransport();
await server.connect(transport);

Elftia で使用する

上記のサーバーを my-server.js として保存し、Elftia で Stdio サーバーを追加します。

フィールド
Namemy-custom-server
Transport TypeStdio
Commandnode
Arguments/path/to/my-server.js

ツール定義仕様

Elftia の MCP ツールには次の要件があります。

要件説明
Name必須です。ツール ID(mcp__server__name)の生成に使用されます
Description強く推奨されます。LLM は、いつ呼び出すかを判断するために説明に依存します
inputSchema有効な JSON Schema で、type: 'object' である必要があります
Return formatcontent 配列です。各項目には type と対応するデータが含まれます

返却コンテンツタイプ

// Text return
{ type: 'text', text: 'Result text' }

// Image return
{ type: 'image', mimeType: 'image/png', data: '<base64-encoded>' }

// Audio return
{ type: 'audio', mimeType: 'audio/wav', data: '<base64-encoded>' }

注記: Elftia の McpToolAdapter は画像と音声をプレースホルダーテキスト([Image: mime])に変換し、実際のバイナリデータは ToolCallDisplay コンポーネントがレンダリング用に処理します。

タイムアウトに関する考慮事項

Elftia は MCP ツール呼び出しに 120 秒のタイムアウト を設定しています。ツールがより長時間の操作を実行する可能性がある場合は、次を推奨します。

  • 非同期処理を実装し、まずタスク ID を返してポーリングインターフェイスを提供する
  • ツールの説明に想定される待ち時間を記載する
  • ストリーミング返却の使用を検討する(トランスポート層が対応している場合)

npm パッケージの公開

MCP サーバーを npm パッケージとして公開したい場合(npx によるワンクリック起動をサポートする場合)は、次のようにします。

  1. package.jsonbin フィールドを設定します。

    {
    "name": "@yourorg/mcp-server-example",
    "bin": {
    "mcp-server-example": "./dist/index.js"
    }
    }
  2. エントリファイルに shebang があることを確認します。

    #!/usr/bin/env node
  3. ユーザーは Elftia で次のように設定します。

    FieldValue
    Commandnpx
    Arguments-y , @yourorg/mcp-server-example

公式プリセットに追加する

MCP サーバーを Elftia の公式プリセット一覧に表示したい場合は、packages/desktop/app/shared/mcp-presets.ts に設定を追加します。

export const OFFICIAL_MCP_PRESETS: OfficialMcpPreset[] = [
// Existing presets...
{
id: 'your-server-id',
name: 'Your Server Name',
provider: 'your-org',
category: 'general', // search | vision | web-reading | code-repo | general
description: 'Server feature description',
tools: ['tool1', 'tool2'],
command: 'npx',
args: ['-y', '@yourorg/mcp-server@latest'],
requiresApiKey: true,
apiKeyEnvVar: 'YOUR_API_KEY',
linkedProviderIds: ['provider-id'],
documentationUrl: 'https://docs.example.com',
icon: 'icon-name',
},
];

プリセットフィールドの説明:

フィールド必須説明
idYes一意の識別子
nameYes表示名
providerYesプロバイダー識別子
categoryYesカテゴリ: search / vision / web-reading / code-repo / general
descriptionYes機能説明
toolsYes提供されるツール名の一覧
transportTypeNostdio(デフォルト)/ http
commandFor Stdio起動コマンド
argsFor Stdioコマンド引数
urlFor HTTPリモート URL
requiresApiKeyYesAPI Key が必要かどうか
apiKeyEnvVarNoAPI Key 用の環境変数名
linkedProviderIdsNo関連付けられた LLM プロバイダー ID(Key を自動取得)
extraEnvNo追加の固定環境変数
documentationUrlNoドキュメントリンク

DependencyCheckService の拡張

MCP サーバーが標準ではないコマンドラインツールに依存している場合は、DependencyCheckServiceinstallCommand() メソッドを拡張できます。

ファイルパス: packages/desktop/app/main/services/capabilities/tools/mcp-users/DependencyCheckService.ts

async installCommand(command: string): Promise<DependencyInstallResult> {
// ...
if (command === 'your-tool') {
return await this.installYourTool(command);
}
// ...
}

現在サポートされている自動インストールは次のとおりです。

コマンドインストール方法
npx / npm / nodeWindows: winget; macOS: Homebrew; Others: Download page
uv / uvx公式インストールスクリプト(Windows: PowerShell; Unix: curl + sh)

関連ファイル