Cloudflare リモートMCPサーバーを利用してAPIを叩くMCPツールを作る
はじめに
この記事は【LLM+RAG】自分自身と会話できるナレッジベースシステムを作ってみたのナレッジベースシステムのsearch API をMCPから叩けるようにした記事です。
画像赤枠の部分について書いています。

できること
- MCPからsearch APIを通じてナレッジベースにアクセスし、情報を返す
- リモートMCPサーバーをホストすることで誰でもアクセスできる
リモートMCPサーバーのホスティング
MCPですが、サーバーについてはローカル環境で構築することは簡単ですが、環境に捉われず誰でも利用できるMCPサーバーを立てたいです。
CloudflareがHTTPで接続しMCPを利用できるサービスを提供しているのでそれを使うことにしました。
以下ページに詳しい内容が載っています。
初期設定
Cloudflare DocsのBuild a Remote MCP serverに沿って作っていきます。
対象のリポジトリで以下を実行します。
$ npm create cloudflare@latest -- mcp-server
対話形式で設定を確認されるため以下のように進めていきます。
├ In which directory do you want to create your application?
│ dir ./mcp-server
│
╰ What would you like to start with?
● Hello World example <-選択
○ Framework Starter
○ Application Starter
○ Template from a GitHub repo
◁ Go back
╰ Which template would you like to use?
○ Worker only
○ Static site
○ SSR / full-stack app
● Worker + Durable Objects <-選択
○ Worker + Durable Objects + Assets
○ Workflow
○ Scheduled Worker (Cron Trigger)
○ Queue consumer & producer Worker
○ API starter (OpenAPI compliant)
◁ Go back
╰ Which language do you want to use?
● TypeScript <-選択
○ JavaScript
○ Python (beta)
◁ Go back
┐ Installing dependencies ..
╰ Do you want to use git for version control?
Yes / No <- 既に対象リポジトリがGit管理のためNo
╰ Do you want to deploy your application?
Yes / No <- 後程設定してdeployしたいのでNo
必要なライブラリをインストールします
$ npm install agents @modelcontextprotocol/sdk zod
MCPツールの実装
ナレッジベースのsearch APIを叩き、結果を返す内容を実装します。
以下のページをとても参考にしました。
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { McpAgent } from 'agents/mcp';
import { z } from 'zod';
export class MyMCP extends McpAgent {
server = new McpServer({
name: 'MyMCP Server',
version: '0.1.0',
});
async init() {
this.server.tool(
// ツールの名前
'quarkgabber-knowledge-base-search',
// ツールの説明
'QuarkgabberナレッジベースAPI searchにアクセスしレスポンスを受け取ります。',
// ツールの引数のスキーマ
{ query: z.string().describe('検索クエリ')},
// ツールの実行関数
async (args: any) => {
const { query } = args;
// search APIをPOSTリクエストする
const response = await fetch('https://home.quark-hardcore.com/personal-knowledge-base/api/v1/search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: query,
k: 10
})
});
const data = await response.json();
// 結果を返す
return {
content: [{ type: 'text', text: JSON.stringify(data, null, 2)}]
};
});
}
}
import { MyMCP } from './MyMcp.js';
// Durable Objects のエクスポート
export { MyMCP };
export default {
fetch(request: Request, env: Env, ctx: ExecutionContext) {
const url = new URL(request.url);
// /sse エンドポイントの場合は SSE で応答する
if (url.pathname === '/sse' || url.pathname === '/sse/message') {
// @ts-ignore
return MyMCP.serveSSE('/sse').fetch(request, env, ctx);
}
// /mcp エンドポイントの場合は Streamable HTTP で応答する
if (url.pathname === '/mcp') {
// @ts-ignore
return MyMCP.serve('/mcp').fetch(request, env, ctx);
}
return new Response('Not found', { status: 404 });
},
};
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "mcp-server",
"main": "src/index.ts",
"compatibility_date": "2025-09-02",
"compatibility_flags": ["nodejs_compat"],
"migrations": [
{
"new_sqlite_classes": [
"MyMCP"
],
"tag": "v1"
}
],
"durable_objects": {
"bindings": [
{
"class_name": "MyMCP",
"name": "MCP_OBJECT"
}
]
}
}
動作チェック
まずはローカル環境で確認します。
サーバーを立ち上げます。
$ npm run dev
[wrangler:info] Ready on http://localhost:8787
ブラウザからMCPサーバーに接続してツールを呼び出せるMCP Inspectorを実行します。
$ npx @modelcontextprotocol/inspector@latest

ブラウザからこのような画面が開く
デフォルトではlocalhost:6274でブラウザが開き、リクエストはlocalhost:6277でプロキシしているみたいです。
Transport Type -> SSEURL -> http://localhost:8787/sse
と設定しconnectを押します。

右上のTools→List Toolsボタンを押します。

queryに質問文を入れて、Run Toolを押します。

成功しました!

Transport Type -> SSE
URL -> http://localhost:8787/sse
と設定しconnectを押します。
こちらの設定ですが、リモートMCPクライアントではSSE(Server-Sent Events)かStreamable HTTPで通信します。
Transport Type -> Streamable HTTPURL -> http://localhost:8787/mcp
でも同様に成功することを確認します。

成功したら変更を対象リポジトリにPushしておきます。
CloudflareにDeploy
Cloudflareにアカウントを作ります。
npm run deployコマンドをwrangler.jsoncがあるディレクトリで実行します。初回はOAuthブラウザ認証が入ります。
$ npm run deploy
Total Upload: 1237.91 KiB / gzip: 198.40 KiB
Worker Startup Time: 30 ms
Your Worker has access to the following bindings:
Binding Resource
env.MCP_OBJECT (MyMCP) Durable Object
Uploaded mcp-server (4.35 sec)
Deployed mcp-server triggers (0.30 sec)
https://mcp-server.quark-hardcore.workers.dev
Cloudflareのダッシュボード「コンピューティング」→「Workers & Pages」をみるとWorkerが作られています。

Workers AI LLM PlaygroundでDeployしたMCPサーバーを試すことができます。
npm run deployで発行されたURL + /sse を「Enter MCP server URL」にいれてconnectします。(URLはCloudflare対象workerの設定タブからも確認できます。)

このMCPはsearch APIでOpenSearchから類似コンテンツを返すもので、その後の解釈はAIが行うので、AIの能力に依存します。
Workers AI LLM Playgroundで提供されているモデルでは、あまり思ったような返事にはなりませんでした。

GPT5やSonnet 4ではtimestampを使って答えてくれる
Claude DesktopからリモートMCPサーバーに接続して使う
Claude DesktopはMCPに対応しているのでそちらで使ってみます。
「設定」→「コネクタ」→「カスタムコネクタを追加」をクリック

名前とURLを設定します。

検索とツールでツールを有効にします。

チャットから誕生日を聞いてみます

うまくいきました!
参考
Discussion