0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ClineでSSE errorによりMCPサーバーと接続できない問題の解決方法

Posted at

ClineでMCPサーバーが接続できない問題の解決方法

概要

ClineでMCPサーバーを使用しようとした際に「SSE error: TypeError: fetch failed: connect ECONNREFUSED 127.0.0.1:*」エラーが発生する問題と、その解決方法について解説します。

問題の背景

ClineはModel Context Protocol (MCP)を使用して外部ツールと連携します。
WSL下にMCPサーバを作成し、起動が出来た段階で以下のような現象が発生しました。

  • コンソールからのcurlリクエストは成功するが、ClineのGUIからMCPサーバーに接続できない
  • エラーメッセージ: SSE error: TypeError: fetch failed: connect ECONNREFUSED 127.0.0.1:3000

原因

ClineのMCP統合は標準的なMCPプロトコル(JSON-RPC over stdio)を期待しているが、独自実装のHTTP APIサーバーとして作成されていたため、プロトコルの不一致が発生していました。

解決手順

1. プロジェクトの初期化

mkdir hello-mcp-server
cd hello-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk typescript @types/node

2. 標準的なMCPサーバーの実装

src/index.ts

#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ErrorCode,
  ListToolsRequestSchema,
  McpError,
} from '@modelcontextprotocol/sdk/types.js';

class HelloMCPServer {
  private server: Server;

  constructor() {
    this.server = new Server(
      {
        name: 'hello-mcp-server',
        version: '1.0.0',
      },
      {
        capabilities: {
          tools: {},
        },
      }
    );

    this.setupToolHandlers();
    
    // Error handling
    this.server.onerror = (error) => console.error('[MCP Error]', error);
    process.on('SIGINT', async () => {
      await this.server.close();
      process.exit(0);
    });
  }

  private setupToolHandlers() {
    // ツールリストの定義
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [
        {
          name: 'say_hello',
          description: 'Hello Worldメッセージを返します',
          inputSchema: {
            type: 'object',
            properties: {
              name: {
                type: 'string',
                description: '挨拶する相手の名前',
              },
            },
            required: ['name'],
          },
        },
        {
          name: 'get_time',
          description: '現在の時刻を返します',
          inputSchema: {
            type: 'object',
            properties: {},
          },
        },
      ],
    }));

    // ツール実行の処理
    this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
      try {
        switch (request.params.name) {
          case 'say_hello':
            if (!request.params.arguments) {
              throw new McpError(ErrorCode.InvalidParams, 'Missing arguments');
            }
            const args = request.params.arguments as { name: string };
            return {
              content: [
                {
                  type: 'text',
                  text: `Hello, ${args.name}! Welcome to MCP Server!`,
                },
              ],
            };

          case 'get_time':
            return {
              content: [
                {
                  type: 'text',
                  text: `Current time: ${new Date().toISOString()}`,
                },
              ],
            };

          default:
            throw new McpError(
              ErrorCode.MethodNotFound,
              `Unknown tool: ${request.params.name}`
            );
        }
      } catch (error: any) {
        console.error(`Tool execution error: ${error.message}`);
        return {
          content: [
            {
              type: 'text',
              text: `Error: ${error.message}`,
            },
          ],
          isError: true,
        };
      }
    });
  }

  async run() {
    const transport = new StdioServerTransport();
    await this.server.connect(transport);
    console.error('Hello MCP Server running on stdio');
  }
}

const server = new HelloMCPServer();
server.run().catch(console.error);

3. ビルド設定

package.json

{
  "type": "module",
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es2020",
    "module": "es2020",
    "moduleResolution": "node",
    "outDir": "dist",
    "rootDir": "src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  }
}

4. Cline設定ファイルの更新

ClineのMCP設定ファイルは、VSCodeの拡張機能データディレクトリに保存されます。
ここではWSLのVScode Serverで展開しているため以下の場所に設置しています。

設定ファイルパス:

~/.vscode-server/data/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json

注意: saoudrizwan.claude-devは、ClineのVSCode拡張機能のパッケージ名です(作者名.拡張機能名)。VSCodeの拡張機能は、この形式でデータを保存します。

変更前(HTTP/SSE):

{
  "mcpServers": {
    "hello-mcp-server": {
      "autoApprove": [],
      "disabled": false,
      "timeout": 60,
      "url": "http://localhost:3000",
      "transportType": "sse"
    }
  }
}

変更後(stdio):

{
  "mcpServers": {
    "hello-mcp-server": {
      "autoApprove": [],
      "disabled": false,
      "timeout": 60,
      "command": "node",
      "args": ["/path/to/hello-mcp-server/dist/index.js"]
    }
  }
}

重要なポイント

プロトコルの違い

  • HTTP/SSE: 独自実装のREST APIサーバー
  • stdio: 標準的なMCPプロトコル(JSON-RPC over stdio)

ClineのMCP統合では、標準的なMCPプロトコルを使用する必要があります。HTTP APIとして実装されたサーバーは、MCP SDKを使用してstdioベースの実装に変更する必要があります。

動作確認

1. ビルド

npm run build

2. ClineのGUIからのテスト

<!-- use_mcp_tool を使用してテスト -->
<use_mcp_tool>
<server_name>hello-mcp-server</server_name>
<tool_name>say_hello</tool_name>
<arguments>
{
  "name": "World"
}
</arguments>
</use_mcp_tool>

期待される結果:

Hello, World! Welcome to MCP Server!

まとめ

ClineでMCPサーバーを使用する際は、標準的なMCPプロトコル(JSON-RPC over stdio)に準拠した実装が必要です。HTTP APIサーバーとして実装されている場合は、MCP SDKを使用して標準的な実装に変更し、設定ファイルもstdioトランスポートを使用するように更新する必要があります。

参考情報


この記事が同様の問題に遭遇した方の参考になれば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?