Created
October 18, 2025 00:33
-
-
Save kuc-arc-f/ae773bd07b4e4a6dc5e06e91661a9932 to your computer and use it in GitHub Desktop.
test-code , workers + remoto MCP Server JSON-RPC 2.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Cloudflare Workers - MCP Server with JSON-RPC 2.0 | |
* Model Context Protocol Remote Server Implementation | |
*/ | |
export default { | |
async fetch(request, env, ctx) { | |
// CORS headers | |
const corsHeaders = { | |
'Access-Control-Allow-Origin': '*', | |
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', | |
'Access-Control-Allow-Headers': 'Content-Type', | |
}; | |
// Handle CORS preflight | |
if (request.method === 'OPTIONS') { | |
return new Response(null, { headers: corsHeaders }); | |
} | |
// Only accept POST requests | |
if (request.method !== 'POST') { | |
return new Response('Method not allowed', { | |
status: 405, | |
headers: corsHeaders | |
}); | |
} | |
try { | |
const body = await request.json(); | |
const response = await handleJsonRpc(body, env); | |
return new Response(JSON.stringify(response), { | |
headers: { | |
'Content-Type': 'application/json', | |
...corsHeaders | |
} | |
}); | |
} catch (error) { | |
return new Response(JSON.stringify({ | |
jsonrpc: '2.0', | |
error: { | |
code: -32700, | |
message: 'Parse error', | |
data: error.message | |
}, | |
id: null | |
}), { | |
status: 400, | |
headers: { | |
'Content-Type': 'application/json', | |
...corsHeaders | |
} | |
}); | |
} | |
} | |
}; | |
/** | |
* Handle JSON-RPC 2.0 requests | |
*/ | |
async function handleJsonRpc(request, env) { | |
// Validate JSON-RPC 2.0 request | |
if (request.jsonrpc !== '2.0') { | |
return { | |
jsonrpc: '2.0', | |
error: { | |
code: -32600, | |
message: 'Invalid Request' | |
}, | |
id: request.id || null | |
}; | |
} | |
const { method, params, id } = request; | |
try { | |
let result; | |
switch (method) { | |
case 'initialize': | |
result = await handleInitialize(params); | |
break; | |
case 'tools/list': | |
result = await handleToolsList(params); | |
break; | |
case 'tools/call': | |
result = await handleToolsCall(params, env); | |
break; | |
case 'resources/list': | |
result = await handleResourcesList(params); | |
break; | |
case 'resources/read': | |
result = await handleResourcesRead(params, env); | |
break; | |
case 'prompts/list': | |
result = await handlePromptsList(params); | |
break; | |
case 'prompts/get': | |
result = await handlePromptsGet(params); | |
break; | |
default: | |
return { | |
jsonrpc: '2.0', | |
error: { | |
code: -32601, | |
message: 'Method not found', | |
data: { method } | |
}, | |
id | |
}; | |
} | |
return { | |
jsonrpc: '2.0', | |
result, | |
id | |
}; | |
} catch (error) { | |
return { | |
jsonrpc: '2.0', | |
error: { | |
code: -32603, | |
message: 'Internal error', | |
data: error.message | |
}, | |
id | |
}; | |
} | |
} | |
/** | |
* MCP Protocol Handlers | |
*/ | |
async function handleInitialize(params) { | |
return { | |
protocolVersion: '2024-11-05', | |
capabilities: { | |
tools: {}, | |
resources: {}, | |
prompts: {} | |
}, | |
serverInfo: { | |
name: 'cloudflare-mcp-server', | |
version: '1.0.0' | |
} | |
}; | |
} | |
async function handleToolsList(params) { | |
return { | |
tools: [ | |
{ | |
name: 'get_time', | |
description: 'Get current server time', | |
inputSchema: { | |
type: 'object', | |
properties: { | |
timezone: { | |
type: 'string', | |
description: 'Timezone (optional)', | |
default: 'UTC' | |
} | |
} | |
} | |
}, | |
{ | |
name: 'fetch_data', | |
description: 'Fetch data from external API', | |
inputSchema: { | |
type: 'object', | |
properties: { | |
url: { | |
type: 'string', | |
description: 'URL to fetch' | |
} | |
}, | |
required: ['url'] | |
} | |
} | |
] | |
}; | |
} | |
async function handleToolsCall(params, env) { | |
const { name, arguments: args } = params; | |
switch (name) { | |
case 'get_time': | |
return { | |
content: [ | |
{ | |
type: 'text', | |
text: `Current time: ${new Date().toISOString()}` | |
} | |
] | |
}; | |
case 'fetch_data': | |
try { | |
const response = await fetch(args.url); | |
const data = await response.text(); | |
return { | |
content: [ | |
{ | |
type: 'text', | |
text: data | |
} | |
] | |
}; | |
} catch (error) { | |
return { | |
content: [ | |
{ | |
type: 'text', | |
text: `Error fetching data: ${error.message}` | |
} | |
], | |
isError: true | |
}; | |
} | |
default: | |
throw new Error(`Unknown tool: ${name}`); | |
} | |
} | |
async function handleResourcesList(params) { | |
return { | |
resources: [ | |
{ | |
uri: 'cloudflare://worker/info', | |
name: 'Worker Information', | |
description: 'Information about this Cloudflare Worker', | |
mimeType: 'application/json' | |
} | |
] | |
}; | |
} | |
async function handleResourcesRead(params, env) { | |
const { uri } = params; | |
if (uri === 'cloudflare://worker/info') { | |
return { | |
contents: [ | |
{ | |
uri, | |
mimeType: 'application/json', | |
text: JSON.stringify({ | |
name: 'Cloudflare MCP Server', | |
runtime: 'Cloudflare Workers', | |
version: '1.0.0' | |
}, null, 2) | |
} | |
] | |
}; | |
} | |
throw new Error(`Resource not found: ${uri}`); | |
} | |
async function handlePromptsList(params) { | |
return { | |
prompts: [ | |
{ | |
name: 'greeting', | |
description: 'Generate a greeting message', | |
arguments: [ | |
{ | |
name: 'name', | |
description: 'Name to greet', | |
required: true | |
} | |
] | |
} | |
] | |
}; | |
} | |
async function handlePromptsGet(params) { | |
const { name, arguments: args } = params; | |
if (name === 'greeting') { | |
return { | |
messages: [ | |
{ | |
role: 'user', | |
content: { | |
type: 'text', | |
text: `Hello, ${args?.name || 'World'}!` | |
} | |
} | |
] | |
}; | |
} | |
throw new Error(`Prompt not found: ${name}`); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "workers26mcp", | |
"version": "0.0.0", | |
"type": "module", | |
"private": true, | |
"scripts": { | |
"build": "npx vite build --config vite.app.config.ts && npm run build:css", | |
"build:css": "npx tailwindcss -i ./src/input.css -o ./public/main.css", | |
"deploy": "wrangler deploy", | |
"dev": "wrangler dev", | |
"start": "wrangler dev", | |
"test": "vitest", | |
"cf-typegen": "wrangler types" | |
}, | |
"dependencies": { | |
"@libsql/client": "^0.15.15", | |
"@tailwindcss/cli": "^4.1.4", | |
"@tanstack/react-table": "^8.21.3", | |
"axios": "^1.12.2", | |
"react": "^19.0.0", | |
"react-dom": "^19.0.0", | |
"tailwindcss": "^4.1.4", | |
"vite": "^6.2.0", | |
"zod": "^3.24.2" | |
}, | |
"devDependencies": { | |
"@cloudflare/vitest-pool-workers": "^0.9.7", | |
"@cloudflare/workers-types": "^4.20250410.0", | |
"@types/react": "^19.0.10", | |
"@types/react-dom": "^19.0.4", | |
"@vitejs/plugin-react": "^4.3.4", | |
"nodemon": "^3.1.9", | |
"typescript": "^5.5.2", | |
"vitest": "~3.0.7", | |
"wrangler": "^4.10.0" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const start = async function() { | |
try{ | |
const item = { | |
"jsonrpc": "2.0", | |
"method": "tools/list", | |
"id": 1 | |
} | |
const response = await fetch("http://localhost:8787", { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': '', | |
}, | |
body: JSON.stringify(item), | |
}); | |
if (!response.ok) { | |
const text = await response.text(); | |
console.log(text); | |
throw new Error('Failed to create item'); | |
}else{ | |
console.log("OK"); | |
const json = await response.json(); | |
console.log(json); | |
console.log(json.result); | |
} | |
}catch(e){console.log(e)} | |
} | |
start(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const start = async function() { | |
try{ | |
const item = { | |
"jsonrpc": "2.0", | |
"method": "tools/call", | |
"params": { | |
"name": "get_time", | |
"arguments": {} | |
}, | |
"id": 2 | |
} | |
const response = await fetch("http://localhost:8787", { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': '', | |
}, | |
body: JSON.stringify(item), | |
}); | |
if (!response.ok) { | |
const text = await response.text(); | |
console.log(text); | |
throw new Error('Failed to create item'); | |
}else{ | |
console.log("OK"); | |
const json = await response.json(); | |
console.log(json); | |
console.log(json.result.content[0].text); | |
} | |
}catch(e){console.log(e)} | |
} | |
start(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment