Debug Log
diff --git a/examples/servers/cf-agents/package.json b/examples/servers/cf-agents/package.json
index a9f909a..180b46c 100644
--- a/examples/servers/cf-agents/package.json
+++ b/examples/servers/cf-agents/package.json
@@ -4,7 +4,7 @@
"private": true,
"scripts": {
"deploy": "wrangler deploy",
- "dev": "wrangler dev --port 5102",
+ "dev": "wrangler dev",
"format": "biome format --write",
"lint:fix": "biome lint --fix",
"start": "wrangler dev",
@@ -12,7 +12,7 @@
"type-check": "tsc --noEmit"
},
"dependencies": {
- "@modelcontextprotocol/sdk": "^1.13.3",
+ "@modelcontextprotocol/sdk": "^1.13.0",
"zod": "^3.25.67"
},
"devDependencies": {
@@ -22,6 +22,6 @@
"agents": "^0.0.100",
"hono": "^4.8.3",
"typescript": "^5.8.3",
- "wrangler": "^4.23.0"
+ "wrangler": "^4.22.0"
}
}
diff --git a/examples/servers/cf-agents/pnpm-lock.yaml b/examples/servers/cf-agents/pnpm-lock.yaml
index f0ff232..7c3d7be 100644
--- a/examples/servers/cf-agents/pnpm-lock.yaml
+++ b/examples/servers/cf-agents/pnpm-lock.yaml
@@ -9,8 +9,8 @@ importers:
.:
dependencies:
'@modelcontextprotocol/sdk':
- specifier: ^1.13.3
- version: 1.13.3
+ specifier: ^1.13.0
+ version: 1.13.2
zod:
specifier: ^3.25.67
version: 3.25.67
@@ -34,8 +34,8 @@ importers:
specifier: ^5.8.3
version: 5.8.3
wrangler:
- specifier: ^4.23.0
- version: 4.23.0(@cloudflare/workers-types@4.20250628.0)
+ specifier: ^4.22.0
+ version: 4.22.0(@cloudflare/workers-types@4.20250628.0)
packages:
@@ -443,8 +443,8 @@ packages:
'@jridgewell/trace-mapping@0.3.9':
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
- '@modelcontextprotocol/sdk@1.13.3':
- resolution: {integrity: sha512-bGwA78F/U5G2jrnsdRkPY3IwIwZeWUEfb5o764b79lb0rJmMT76TLwKhdNZOWakOQtedYefwIR4emisEMvInKA==}
+ '@modelcontextprotocol/sdk@1.13.2':
+ resolution: {integrity: sha512-Vx7qOcmoKkR3qhaQ9qf3GxiVKCEu+zfJddHv6x3dY/9P6+uIwJnmuAur5aB+4FDXf41rRrDnOEGkviX5oYZ67w==}
engines: {node: '>=18'}
'@opentelemetry/api@1.9.0':
@@ -765,8 +765,8 @@ packages:
engines: {node: '>=10.0.0'}
hasBin: true
- miniflare@4.20250617.5:
- resolution: {integrity: sha512-Qqn30jR6dCjXaKVizT6vH4KOb+GyLccoxLNOJEfu63yBPn8eoXa7PrdiSGTmjs2RY8/tr7eTO8Wu/Yr14k0xVA==}
+ miniflare@4.20250617.4:
+ resolution: {integrity: sha512-IAoApFKxOJlaaFkym5ETstVX3qWzVt3xyqCDj6vSSTgEH3zxZJ5417jZGg8iQfMHosKCcQH1doPPqqnOZm/yrw==}
engines: {node: '>=18.0.0'}
hasBin: true
@@ -1009,8 +1009,8 @@ packages:
engines: {node: '>=16'}
hasBin: true
- wrangler@4.23.0:
- resolution: {integrity: sha512-JSeDt3IwA4TEmg/V3tRblImPjdxynBt9PUVO/acQJ83XGlMMSwswDKL1FuwvbFzgX6+JXc3GMHeu7r8AQIxw9w==}
+ wrangler@4.22.0:
+ resolution: {integrity: sha512-m8qVO3YxhUTII+4U889G/f5UuLSvMkUkCNatupV2f/SJ+iqaWtP1QbuQII8bs2J/O4rqxsz46Wu2S50u7tKB5Q==}
engines: {node: '>=18.0.0'}
hasBin: true
peerDependencies:
@@ -1314,14 +1314,13 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.2
- '@modelcontextprotocol/sdk@1.13.3':
+ '@modelcontextprotocol/sdk@1.13.2':
dependencies:
ajv: 6.12.6
content-type: 1.0.5
cors: 2.8.5
cross-spawn: 7.0.6
eventsource: 3.0.7
- eventsource-parser: 3.0.3
express: 5.1.0
express-rate-limit: 7.5.1(express@5.1.0)
pkce-challenge: 5.0.0
@@ -1350,7 +1349,7 @@ snapshots:
agents@0.0.100(@cloudflare/workers-types@4.20250628.0)(react@19.1.0):
dependencies:
- '@modelcontextprotocol/sdk': 1.13.3
+ '@modelcontextprotocol/sdk': 1.13.2
ai: 4.3.16(react@19.1.0)(zod@3.25.67)
cron-schedule: 5.0.4
nanoid: 5.1.5
@@ -1673,7 +1672,7 @@ snapshots:
mime@3.0.0: {}
- miniflare@4.20250617.5:
+ miniflare@4.20250617.4:
dependencies:
'@cspotcode/source-map-support': 0.8.1
acorn: 8.14.0
@@ -1943,13 +1942,13 @@ snapshots:
'@cloudflare/workerd-linux-arm64': 1.20250617.0
'@cloudflare/workerd-windows-64': 1.20250617.0
- wrangler@4.23.0(@cloudflare/workers-types@4.20250628.0):
+ wrangler@4.22.0(@cloudflare/workers-types@4.20250628.0):
dependencies:
'@cloudflare/kv-asset-handler': 0.4.0
'@cloudflare/unenv-preset': 2.3.3(unenv@2.0.0-rc.17)(workerd@1.20250617.0)
blake3-wasm: 2.1.5
esbuild: 0.25.4
- miniflare: 4.20250617.5
+ miniflare: 4.20250617.4
path-to-regexp: 6.3.0
unenv: 2.0.0-rc.17
workerd: 1.20250617.0
diff --git a/examples/servers/cf-agents/src/index.ts b/examples/servers/cf-agents/src/index.ts
index 81f43ae..417e3b9 100644
--- a/examples/servers/cf-agents/src/index.ts
+++ b/examples/servers/cf-agents/src/index.ts
@@ -1,7 +1,7 @@
import { McpAgent } from 'agents/mcp'
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { z } from 'zod'
-import OAuthProvider, { type OAuthHelpers } from '@cloudflare/workers-oauth-provider'
+import OAuthProvider, { OAuthHelpers } from '@cloudflare/workers-oauth-provider'
import { Hono } from 'hono'
// Define our MCP agent with tools
@@ -53,95 +53,6 @@ export class MyMCP extends McpAgent {
return { content: [{ type: 'text', text: String(result) }] }
},
)
-
- // Register sample resources using the agents framework API
- this.server.resource('calc://history', 'Calculation History', async () => ({
- contents: [
- {
- uri: 'calc://history',
- mimeType: 'application/json',
- text: JSON.stringify(
- {
- calculations: [
- { operation: 'add', a: 5, b: 3, result: 8, timestamp: '2024-01-01T10:00:00Z' },
- { operation: 'multiply', a: 4, b: 7, result: 28, timestamp: '2024-01-01T10:01:00Z' },
- ],
- },
- null,
- 2,
- ),
- },
- ],
- }))
-
- this.server.resource('calc://settings', 'Calculator Settings', async () => ({
- contents: [
- {
- uri: 'calc://settings',
- mimeType: 'application/json',
- text: JSON.stringify(
- {
- precision: 2,
- allowNegative: true,
- maxValue: 1000000,
- },
- null,
- 2,
- ),
- },
- ],
- }))
-
- // Register a dynamic resource
- this.server.resource('calc://stats', 'Calculation Statistics', async () => ({
- contents: [
- {
- uri: 'calc://stats',
- mimeType: 'application/json',
- text: JSON.stringify(
- {
- totalCalculations: Math.floor(Math.random() * 100),
- lastUpdated: new Date().toISOString(),
- },
- null,
- 2,
- ),
- },
- ],
- }))
-
- // Register sample prompts using the agents framework API
- this.server.prompt(
- 'math_problem',
- 'Generate a math problem',
- {
- difficulty: z.string(),
- topic: z.string().optional(),
- },
- async ({ difficulty, topic }) => ({
- messages: [
- {
- role: 'user',
- content: {
- type: 'text',
- text: `Generate a ${difficulty} math problem${topic ? ` about ${topic}` : ''}`,
- },
- },
- ],
- }),
- )
-
- this.server.prompt('explain_calculation', 'Explain a calculation', { operation: z.string() }, async ({ operation }) => ({
- messages: [
- {
- role: 'user',
- content: {
- type: 'text',
- text: `Please explain how to perform ${operation} step by step with examples`,
- },
- },
- ],
- }))
}
}
@@ -155,53 +66,7 @@ const app = new Hono<{
app.get('/authorize', async (c) => {
const oauthReqInfo = await c.env.OAUTH_PROVIDER.parseAuthRequest(c.req.raw)
- const url = new URL(c.req.url)
-
- const approveHref = url.toString()
- return c.html(/*html*/ `
-
-
-
Authorize access
-
-
-
Authorize access
-
Allow Unknown client to access your calculator?
-
-
- Deny
-
-
User: example@dotcom.com
-
- `)
-})
-
-app.post('/authorize', async (c) => {
const email = 'example@dotcom.com'
- const formData = await c.req.formData()
- const oauthReqInfoRaw = formData.get('oauthReqInfo')
- if (!oauthReqInfoRaw || typeof oauthReqInfoRaw !== 'string') {
- return c.text('Missing oauthReqInfo', 400)
- }
- let oauthReqInfo
- try {
- oauthReqInfo = JSON.parse(decodeURIComponent(oauthReqInfoRaw))
- } catch (e) {
- return c.text('Invalid oauthReqInfo', 400)
- }
const { redirectTo } = await c.env.OAUTH_PROVIDER.completeAuthorization({
request: oauthReqInfo,
userId: email,
diff --git a/examples/servers/hono-mcp/package.json b/examples/servers/hono-mcp/package.json
index 6f91211..7e7adb3 100644
--- a/examples/servers/hono-mcp/package.json
+++ b/examples/servers/hono-mcp/package.json
@@ -1,7 +1,7 @@
{
"name": "vengabus",
"scripts": {
- "dev": "wrangler dev --port 5101",
+ "dev": "wrangler dev",
"deploy": "wrangler deploy --minify",
"cf-typegen": "wrangler types --env-interface CloudflareBindings"
},
@@ -10,8 +10,8 @@
},
"devDependencies": {
"@hono/mcp": "^0.1.0",
- "@modelcontextprotocol/sdk": "^1.13.3",
- "wrangler": "^4.23.0",
+ "@modelcontextprotocol/sdk": "^1.13.1",
+ "wrangler": "^4.21.0",
"zod": "^3.25.67"
}
}
diff --git a/examples/servers/hono-mcp/pnpm-lock.yaml b/examples/servers/hono-mcp/pnpm-lock.yaml
index 4139153..d03e141 100644
--- a/examples/servers/hono-mcp/pnpm-lock.yaml
+++ b/examples/servers/hono-mcp/pnpm-lock.yaml
@@ -14,13 +14,13 @@ importers:
devDependencies:
'@hono/mcp':
specifier: ^0.1.0
- version: 0.1.0(@modelcontextprotocol/sdk@1.13.3)(hono@4.8.2)
+ version: 0.1.0(@modelcontextprotocol/sdk@1.13.1)(hono@4.8.2)
'@modelcontextprotocol/sdk':
- specifier: ^1.13.3
- version: 1.13.3
+ specifier: ^1.13.1
+ version: 1.13.1
wrangler:
- specifier: ^4.23.0
- version: 4.23.0
+ specifier: ^4.21.0
+ version: 4.21.0
zod:
specifier: ^3.25.67
version: 3.25.67
@@ -352,8 +352,8 @@ packages:
'@jridgewell/trace-mapping@0.3.9':
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
- '@modelcontextprotocol/sdk@1.13.3':
- resolution: {integrity: sha512-bGwA78F/U5G2jrnsdRkPY3IwIwZeWUEfb5o764b79lb0rJmMT76TLwKhdNZOWakOQtedYefwIR4emisEMvInKA==}
+ '@modelcontextprotocol/sdk@1.13.1':
+ resolution: {integrity: sha512-8q6+9aF0yA39/qWT/uaIj6zTpC+Qu07DnN/lb9mjoquCJsAh6l3HyYqc9O3t2j7GilseOQOQimLg7W3By6jqvg==}
engines: {node: '>=18'}
accepts@2.0.0:
@@ -623,8 +623,8 @@ packages:
engines: {node: '>=10.0.0'}
hasBin: true
- miniflare@4.20250617.5:
- resolution: {integrity: sha512-Qqn30jR6dCjXaKVizT6vH4KOb+GyLccoxLNOJEfu63yBPn8eoXa7PrdiSGTmjs2RY8/tr7eTO8Wu/Yr14k0xVA==}
+ miniflare@4.20250617.3:
+ resolution: {integrity: sha512-j+LZycT11UdlVeNdaqD0XdNnYnqAL+wXmboz+tNPFgTq6zhD489Ujj3BfSDyEHDCA9UFBLbkc5ByGWBh+pYZ5Q==}
engines: {node: '>=18.0.0'}
hasBin: true
@@ -820,8 +820,8 @@ packages:
engines: {node: '>=16'}
hasBin: true
- wrangler@4.23.0:
- resolution: {integrity: sha512-JSeDt3IwA4TEmg/V3tRblImPjdxynBt9PUVO/acQJ83XGlMMSwswDKL1FuwvbFzgX6+JXc3GMHeu7r8AQIxw9w==}
+ wrangler@4.21.0:
+ resolution: {integrity: sha512-37xm0CG2qMvsJUNZYQKje6HbCsJFYuE8dQSnu7981iDRT4DLrEIL1DAUnZJG9HiXteKPvrSj96AkZyomi5sYHw==}
engines: {node: '>=18.0.0'}
hasBin: true
peerDependencies:
@@ -972,9 +972,9 @@ snapshots:
'@fastify/busboy@2.1.1': {}
- '@hono/mcp@0.1.0(@modelcontextprotocol/sdk@1.13.3)(hono@4.8.2)':
+ '@hono/mcp@0.1.0(@modelcontextprotocol/sdk@1.13.1)(hono@4.8.2)':
dependencies:
- '@modelcontextprotocol/sdk': 1.13.3
+ '@modelcontextprotocol/sdk': 1.13.1
hono: 4.8.2
'@img/sharp-darwin-arm64@0.33.5':
@@ -1061,14 +1061,13 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0
- '@modelcontextprotocol/sdk@1.13.3':
+ '@modelcontextprotocol/sdk@1.13.1':
dependencies:
ajv: 6.12.6
content-type: 1.0.5
cors: 2.8.5
cross-spawn: 7.0.6
eventsource: 3.0.7
- eventsource-parser: 3.0.2
express: 5.1.0
express-rate-limit: 7.5.1(express@5.1.0)
pkce-challenge: 5.0.0
@@ -1368,7 +1367,7 @@ snapshots:
mime@3.0.0: {}
- miniflare@4.20250617.5:
+ miniflare@4.20250617.3:
dependencies:
'@cspotcode/source-map-support': 0.8.1
acorn: 8.14.0
@@ -1605,13 +1604,13 @@ snapshots:
'@cloudflare/workerd-linux-arm64': 1.20250617.0
'@cloudflare/workerd-windows-64': 1.20250617.0
- wrangler@4.23.0:
+ wrangler@4.21.0:
dependencies:
'@cloudflare/kv-asset-handler': 0.4.0
'@cloudflare/unenv-preset': 2.3.3(unenv@2.0.0-rc.17)(workerd@1.20250617.0)
blake3-wasm: 2.1.5
esbuild: 0.25.4
- miniflare: 4.20250617.5
+ miniflare: 4.20250617.3
path-to-regexp: 6.3.0
unenv: 2.0.0-rc.17
workerd: 1.20250617.0
diff --git a/examples/servers/hono-mcp/src/index.ts b/examples/servers/hono-mcp/src/index.ts
index 74ece33..5fc2067 100644
--- a/examples/servers/hono-mcp/src/index.ts
+++ b/examples/servers/hono-mcp/src/index.ts
@@ -1,4 +1,4 @@
-import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'
+import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StreamableHTTPTransport } from '@hono/mcp'
import { Hono } from 'hono'
import { z } from 'zod'
@@ -17,27 +17,19 @@ app.use(
// Your MCP server implementation
const mcpServer = new McpServer({
- name: 'vengabus-mcp-server',
+ name: 'my-mcp-server',
version: '1.0.0',
})
mcpServer.registerTool(
- 'calculate_party_capacity',
+ 'add',
{
- title: 'Party Bus Capacity Calculator',
- description: 'Calculate how many people can fit on the Vengabus',
- inputSchema: {
- busCount: z.number().describe('Number of Vengabuses'),
- peoplePerBus: z.number().describe('People per bus'),
- },
+ title: 'Addition Tool',
+ description: 'Add two numbers',
+ inputSchema: { a: z.number(), b: z.number() },
},
- async ({ busCount, peoplePerBus }) => ({
- content: [
- {
- type: 'text',
- text: `đ ${busCount} Vengabuses can transport ${busCount * peoplePerBus} party people! The wheels of steel are turning! đ`,
- },
- ],
+ async ({ a, b }) => ({
+ content: [{ type: 'text', text: String(a + b) }],
}),
)
@@ -50,183 +42,18 @@ mcpServer.registerTool(
inputSchema: {},
},
async () => {
- // Simulate some async work
- await new Promise((resolve) => setTimeout(resolve, 100 + Math.random() * 100))
+ await scheduler.wait(100 + Math.random() * 100)
return {
content: [
{
type: 'text',
- text: `đ BOOM BOOM BOOM BOOM! Next Vengabus: IMMINENT! đ
-
-Current Route: "Intercity Disco Express"
-From: New York
-To: IBIZA - THE MAGIC ISLAND! â¨
-
-Schedule:
-- Departure: When the beat drops
-- Via: San Francisco (quick party stop)
-- Arrival: When the sun comes up
-
-Status: The party bus is jumping!
-Passengers: Maximum capacity!
-BPM: 142 and rising!
-
-We're going to Ibiza! Back to the island! đī¸`,
+ text: `Next Vengabus: imminent. Current user's route: New York to San Francisco. Route name: "Intercity Disco".`,
},
],
}
},
)
-// Register sample resources
-mcpServer.registerResource(
- 'config',
- 'config://vengabus',
- {
- title: 'Vengabus Fleet Configuration',
- description: 'Current Vengabus fleet settings and party parameters',
- mimeType: 'application/json',
- },
- async (uri: URL) => {
- const normalizedUri = uri.href.replace(/\/$/, '')
- return {
- contents: [
- {
- uri: normalizedUri,
- mimeType: 'application/json',
- text: JSON.stringify(
- {
- version: '1.0.0',
- fleet: 'intercity-disco',
- features: {
- bassBoost: true,
- strobeEnabled: true,
- maxBPM: 160,
- wheelsOfSteel: 'turning',
- },
- routes: ['New York to Ibiza', 'Back to the Magic Island', 'Like an Intercity Disco', 'The place to be'],
- },
- null,
- 2,
- ),
- },
- ],
- }
- },
-)
-
-mcpServer.registerResource(
- 'readme',
- 'docs://party-manual.md',
- {
- title: 'Vengabus Party Manual',
- description: 'Official guide to the Vengabus experience',
- mimeType: 'text/markdown',
- },
- () => ({
- contents: [
- {
- uri: 'docs://party-manual.md',
- mimeType: 'text/markdown',
- text: "# đ Vengabus MCP Server\n\nBOOM BOOM BOOM BOOM! Welcome aboard the Vengabus! We like to party!\n\n## Features\n- đ Party capacity calculator - How many can we take to Ibiza?\n- đ Vengabus schedule checker - Next stop: The Magic Island!\n- đĩ Fleet configuration with maximum bass boost\n- đ Party statistics tracker (BPM, passengers, energy levels)\n\n## Routes\n- New York to Ibiza (via San Francisco)\n- Back to the Magic Island\n- Like an Intercity Disco\n- The place to be\n\n## Current Status\nThe wheels of steel are turning, and traffic lights are burning!\nWe're going to Ibiza! Woah! We're going to Ibiza!\n\n*Up, up and away we go!*",
- },
- ],
- }),
-)
-
-// Register a resource template
-mcpServer.registerResource(
- 'stats',
- new ResourceTemplate('party://stats/{metric}', { list: undefined }),
- {
- title: 'Vengabus Party Statistics',
- description: 'Get party metrics (bpm, passengers, energy)',
- mimeType: 'application/json',
- },
- async (uri: URL, { metric }) => {
- return {
- contents: [
- {
- uri: uri.href,
- mimeType: 'application/json',
- text: JSON.stringify(
- {
- metric: metric,
- value:
- metric === 'bpm'
- ? 140 + Math.floor(Math.random() * 20)
- : metric === 'passengers'
- ? Math.floor(Math.random() * 50) + 20
- : metric === 'energy'
- ? Math.floor(Math.random() * 100)
- : 0,
- unit:
- metric === 'bpm'
- ? 'beats per minute'
- : metric === 'passengers'
- ? 'party people'
- : metric === 'energy'
- ? 'party power %'
- : 'unknown',
- status: 'The party is jumping!',
- lastUpdated: new Date().toISOString(),
- },
- null,
- 2,
- ),
- },
- ],
- }
- },
-)
-
-// Register sample prompts
-mcpServer.registerPrompt(
- 'party_invitation',
- {
- title: 'Vengabus Party Invitation',
- description: 'Generate a party invitation for the Vengabus',
- argsSchema: {
- name: z.string().describe('Name of the party person'),
- destination: z.string().optional().describe('Where the Vengabus is heading'),
- },
- },
- ({ name, destination }) => ({
- messages: [
- {
- role: 'user',
- content: {
- type: 'text',
- text: `Create a party invitation for ${name} to join the Vengabus${destination ? ` heading to ${destination}` : ''}`,
- },
- },
- ],
- }),
-)
-
-mcpServer.registerPrompt(
- 'party_announcement',
- {
- title: 'Party Bus Announcement',
- description: 'Generate party-themed announcements for various occasions',
- argsSchema: {
- event: z.string().describe('Type of event (deployment, release, milestone, etc.)'),
- details: z.string().optional().describe('Additional details about the event'),
- },
- },
- ({ event, details }) => ({
- messages: [
- {
- role: 'user',
- content: {
- type: 'text',
- text: `Create a party bus announcement for a ${event}${details ? `: ${details}` : ''}`,
- },
- },
- ],
- }),
-)
-
app.post('/mcp', async (c) => {
const transport = new StreamableHTTPTransport()
await mcpServer.connect(transport)
diff --git a/package.json b/package.json
index 6a7cd6b..11a9649 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "use-mcp",
"repository": "https://github.com/modelcontextprotocol/use-mcp",
- "version": "0.0.21",
+ "version": "0.0.15",
"type": "module",
"files": [
"dist",
@@ -21,27 +21,22 @@
}
},
"scripts": {
- "install:all": "concurrently 'pnpm install' 'cd examples/chat-ui && pnpm install' 'cd examples/inspector && pnpm install' 'cd examples/servers/hono-mcp && pnpm install' 'cd examples/servers/cf-agents && pnpm install'",
- "dev": "concurrently 'pnpm:build:watch' 'cd examples/chat-ui && pnpm dev' 'cd examples/inspector && pnpm dev' 'sleep 1 && cd examples/servers/hono-mcp && pnpm dev' 'sleep 2 && cd examples/servers/cf-agents && pnpm dev'",
- "deploy:all": "concurrently 'pnpm build:site && pnpm deploy:site' 'cd examples/chat-ui && pnpm run deploy' 'cd examples/inspector && pnpm run deploy'",
- "build:watch": "tsup --watch",
+ "dev": "tsup --watch",
"build": "tsup",
"check": "prettier --check . && tsc",
"prettier:fix": "prettier --write .",
"fix:oranda": "sed -i 's/```tsx/```ts/g' README.md",
"build:site": "npx @axodotdev/oranda build",
"deploy:site": "npx wrangler deploy",
- "prepare": "husky"
+ "postinstall": "ln -sf ../../scripts/pre-commit .git/hooks/pre-commit"
},
"dependencies": {
- "@modelcontextprotocol/sdk": "^1.13.3",
"strict-url-sanitise": "^0.0.1"
},
"devDependencies": {
"@axodotdev/oranda": "^0.6.5",
+ "@modelcontextprotocol/sdk": "^1.13.3",
"@types/react": "^19.0.12",
- "concurrently": "^9.2.0",
- "husky": "^9.1.7",
"prettier": "^3.5.3",
"react": "^19.0.0",
"tsup": "^8.4.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 36932dc..b26e6b1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,9 +8,6 @@ importers:
.:
dependencies:
- '@modelcontextprotocol/sdk':
- specifier: ^1.13.3
- version: 1.13.3
strict-url-sanitise:
specifier: ^0.0.1
version: 0.0.1
@@ -18,15 +15,12 @@ importers:
'@axodotdev/oranda':
specifier: ^0.6.5
version: 0.6.5
+ '@modelcontextprotocol/sdk':
+ specifier: ^1.13.3
+ version: 1.13.3
'@types/react':
specifier: ^19.0.12
version: 19.0.12
- concurrently:
- specifier: ^9.2.0
- version: 9.2.0
- husky:
- specifier: ^9.1.7
- version: 9.1.7
prettier:
specifier: ^3.5.3
version: 3.5.3
@@ -732,10 +726,6 @@ packages:
resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
engines: {node: '>= 0.4'}
- chalk@4.1.2:
- resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
- engines: {node: '>=10'}
-
chokidar@4.0.3:
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
engines: {node: '>= 14.16.0'}
@@ -744,10 +734,6 @@ packages:
resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
engines: {node: '>=18'}
- cliui@8.0.1:
- resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
- engines: {node: '>=12'}
-
clone@1.0.4:
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
engines: {node: '>=0.8'}
@@ -774,11 +760,6 @@ packages:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
- concurrently@9.2.0:
- resolution: {integrity: sha512-IsB/fiXTupmagMW4MNp2lx2cdSN2FfZq78vF90LBB+zZHArbIQZjQtzXCiXnvTxCZSvXanTqFLWBjw2UkLx1SQ==}
- engines: {node: '>=18'}
- hasBin: true
-
consola@3.4.0:
resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==}
engines: {node: ^14.18.0 || >=16.10.0}
@@ -893,10 +874,6 @@ packages:
engines: {node: '>=18'}
hasBin: true
- escalade@3.2.0:
- resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
- engines: {node: '>=6'}
-
escape-html@1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
@@ -980,10 +957,6 @@ packages:
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
- get-caller-file@2.0.5:
- resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
- engines: {node: 6.* || 8.* || >= 10.*}
-
get-intrinsic@1.3.0:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'}
@@ -1009,10 +982,6 @@ packages:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
- has-flag@4.0.0:
- resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
- engines: {node: '>=8'}
-
has-symbols@1.1.0:
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
engines: {node: '>= 0.4'}
@@ -1029,11 +998,6 @@ packages:
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
engines: {node: '>= 0.8'}
- husky@9.1.7:
- resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==}
- engines: {node: '>=18'}
- hasBin: true
-
iconv-lite@0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
@@ -1082,9 +1046,6 @@ packages:
lodash.sortby@4.7.0:
resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==}
- lodash@4.17.21:
- resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
-
lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
@@ -1272,10 +1233,6 @@ packages:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'}
- require-directory@2.1.1:
- resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
- engines: {node: '>=0.10.0'}
-
resolve-from@5.0.0:
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
engines: {node: '>=8'}
@@ -1296,9 +1253,6 @@ packages:
resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
engines: {node: '>= 18'}
- rxjs@7.8.2:
- resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==}
-
safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
@@ -1333,10 +1287,6 @@ packages:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
- shell-quote@1.8.3:
- resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==}
- engines: {node: '>= 0.4'}
-
side-channel-list@1.0.0:
resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
engines: {node: '>= 0.4'}
@@ -1407,14 +1357,6 @@ packages:
engines: {node: '>=16 || 14 >=14.17'}
hasBin: true
- supports-color@7.2.0:
- resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
- engines: {node: '>=8'}
-
- supports-color@8.1.1:
- resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
- engines: {node: '>=10'}
-
tar@7.4.3:
resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==}
engines: {node: '>=18'}
@@ -1560,22 +1502,10 @@ packages:
utf-8-validate:
optional: true
- y18n@5.0.8:
- resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
- engines: {node: '>=10'}
-
yallist@5.0.0:
resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
engines: {node: '>=18'}
- yargs-parser@21.1.1:
- resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
- engines: {node: '>=12'}
-
- yargs@17.7.2:
- resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
- engines: {node: '>=12'}
-
youch@3.3.4:
resolution: {integrity: sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==}
@@ -2069,23 +1999,12 @@ snapshots:
call-bind-apply-helpers: 1.0.2
get-intrinsic: 1.3.0
- chalk@4.1.2:
- dependencies:
- ansi-styles: 4.3.0
- supports-color: 7.2.0
-
chokidar@4.0.3:
dependencies:
readdirp: 4.1.2
chownr@3.0.0: {}
- cliui@8.0.1:
- dependencies:
- string-width: 4.2.3
- strip-ansi: 6.0.1
- wrap-ansi: 7.0.0
-
clone@1.0.4:
optional: true
@@ -2111,16 +2030,6 @@ snapshots:
commander@4.1.1: {}
- concurrently@9.2.0:
- dependencies:
- chalk: 4.1.2
- lodash: 4.17.21
- rxjs: 7.8.2
- shell-quote: 1.8.3
- supports-color: 8.1.1
- tree-kill: 1.2.2
- yargs: 17.7.2
-
consola@3.4.0: {}
console.table@0.10.0:
@@ -2260,8 +2169,6 @@ snapshots:
'@esbuild/win32-ia32': 0.25.4
'@esbuild/win32-x64': 0.25.4
- escalade@3.2.0: {}
-
escape-html@1.0.3: {}
etag@1.8.1: {}
@@ -2355,8 +2262,6 @@ snapshots:
function-bind@1.1.2: {}
- get-caller-file@2.0.5: {}
-
get-intrinsic@1.3.0:
dependencies:
call-bind-apply-helpers: 1.0.2
@@ -2397,8 +2302,6 @@ snapshots:
gopd@1.2.0: {}
- has-flag@4.0.0: {}
-
has-symbols@1.1.0: {}
has-tostringtag@1.0.2:
@@ -2417,8 +2320,6 @@ snapshots:
statuses: 2.0.1
toidentifier: 1.0.1
- husky@9.1.7: {}
-
iconv-lite@0.6.3:
dependencies:
safer-buffer: 2.1.2
@@ -2453,8 +2354,6 @@ snapshots:
lodash.sortby@4.7.0: {}
- lodash@4.17.21: {}
-
lru-cache@10.4.3: {}
math-intrinsics@1.1.0: {}
@@ -2594,8 +2493,6 @@ snapshots:
readdirp@4.1.2: {}
- require-directory@2.1.1: {}
-
resolve-from@5.0.0: {}
resolve-pkg-maps@1.0.0: {}
@@ -2639,10 +2536,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- rxjs@7.8.2:
- dependencies:
- tslib: 2.8.1
-
safe-buffer@5.2.1: {}
safer-buffer@2.1.2: {}
@@ -2708,8 +2601,6 @@ snapshots:
shebang-regex@3.0.0: {}
- shell-quote@1.8.3: {}
-
side-channel-list@1.0.0:
dependencies:
es-errors: 1.3.0
@@ -2793,14 +2684,6 @@ snapshots:
pirates: 4.0.6
ts-interface-checker: 0.1.13
- supports-color@7.2.0:
- dependencies:
- has-flag: 4.0.0
-
- supports-color@8.1.1:
- dependencies:
- has-flag: 4.0.0
-
tar@7.4.3:
dependencies:
'@isaacs/fs-minipass': 4.0.1
@@ -2835,7 +2718,8 @@ snapshots:
ts-interface-checker@0.1.13: {}
- tslib@2.8.1: {}
+ tslib@2.8.1:
+ optional: true
tsup@8.4.0(tsx@4.19.3)(typescript@5.8.2):
dependencies:
@@ -2959,22 +2843,8 @@ snapshots:
ws@8.18.0: {}
- y18n@5.0.8: {}
-
yallist@5.0.0: {}
- yargs-parser@21.1.1: {}
-
- yargs@17.7.2:
- dependencies:
- cliui: 8.0.1
- escalade: 3.2.0
- get-caller-file: 2.0.5
- require-directory: 2.1.1
- string-width: 4.2.3
- y18n: 5.0.8
- yargs-parser: 21.1.1
-
youch@3.3.4:
dependencies:
cookie: 0.7.1
diff --git a/src/auth/browser-provider.ts b/src/auth/browser-provider.ts
index 0d660bb..f644a0e 100644
--- a/src/auth/browser-provider.ts
+++ b/src/auth/browser-provider.ts
@@ -15,8 +15,6 @@ export class BrowserOAuthClientProvider implements OAuthClientProvider {
readonly clientName: string
readonly clientUri: string
readonly callbackUrl: string
- private preventAutoAuth?: boolean
- readonly onPopupWindow: ((url: string, features: string, window: Window | null) => void) | undefined
constructor(
serverUrl: string,
@@ -25,8 +23,6 @@ export class BrowserOAuthClientProvider implements OAuthClientProvider {
clientName?: string
clientUri?: string
callbackUrl?: string
- preventAutoAuth?: boolean
- onPopupWindow?: (url: string, features: string, window: Window | null) => void
} = {},
) {
this.serverUrl = serverUrl
@@ -38,8 +34,6 @@ export class BrowserOAuthClientProvider implements OAuthClientProvider {
options.callbackUrl ||
(typeof window !== 'undefined' ? new URL('/oauth/callback', window.location.origin).toString() : '/oauth/callback'),
)
- this.preventAutoAuth = options.preventAutoAuth
- this.onPopupWindow = options.onPopupWindow
}
// --- SDK Interface Methods ---
@@ -123,12 +117,11 @@ export class BrowserOAuthClientProvider implements OAuthClientProvider {
}
/**
- * Generates and stores the authorization URL with state, without opening a popup.
- * Used when preventAutoAuth is enabled to provide the URL for manual navigation.
+ * Redirects the user agent to the authorization URL, storing necessary state.
+ * This now adheres to the SDK's void return type expectation for the interface.
* @param authorizationUrl The fully constructed authorization URL from the SDK.
- * @returns The full authorization URL with state parameter.
*/
- async prepareAuthorizationUrl(authorizationUrl: URL): Promise
{
+ async redirectToAuthorization(authorizationUrl: URL): Promise {
// Generate a unique state parameter for this authorization request
const state = crypto.randomUUID()
const stateKey = `${this.storageKeyPrefix}:state_${state}`
@@ -158,31 +151,11 @@ export class BrowserOAuthClientProvider implements OAuthClientProvider {
// Persist the exact auth URL in case the popup fails and manual navigation is needed
localStorage.setItem(this.getKey('last_auth_url'), sanitizedAuthUrl)
- return sanitizedAuthUrl
- }
-
- /**
- * Redirects the user agent to the authorization URL, storing necessary state.
- * This now adheres to the SDK's void return type expectation for the interface.
- * @param authorizationUrl The fully constructed authorization URL from the SDK.
- */
- async redirectToAuthorization(authorizationUrl: URL): Promise {
- // Ideally we should catch things before we get here, but if we don't, let's not show everyone we are dum
- if (this.preventAutoAuth) return
-
- // Prepare the authorization URL with state
- const sanitizedAuthUrl = await this.prepareAuthorizationUrl(authorizationUrl)
-
// Attempt to open the popup
const popupFeatures = 'width=600,height=700,resizable=yes,scrollbars=yes,status=yes' // Make configurable if needed
try {
const popup = window.open(sanitizedAuthUrl, `mcp_auth_${this.serverUrlHash}`, popupFeatures)
- // If a callback is provided, invoke it after opening the popup
- if (this.onPopupWindow) {
- this.onPopupWindow(sanitizedAuthUrl, popupFeatures, popup)
- }
-
if (!popup || popup.closed || typeof popup.closed === 'undefined') {
console.warn(
`[${this.storageKeyPrefix}] Popup likely blocked by browser. Manual navigation might be required using the stored URL.`,
diff --git a/src/react/README.md b/src/react/README.md
index f523ea5..3e15c47 100644
--- a/src/react/README.md
+++ b/src/react/README.md
@@ -23,7 +23,7 @@ The useMcp hook manages the connection to an MCP server, handles authentication
```tsx
import { useMcp } from 'use-mcp'
// Optional: Import types if needed
-import type { UseMcpOptions, UseMcpResult, Tool, Resource, ResourceTemplate, Prompt } from 'use-mcp'
+import type { UseMcpOptions, UseMcpResult, Tool } from 'use-mcp'
```
## Usage
@@ -101,12 +101,7 @@ function MyChatComponent() {
)}
{mcp.state === 'authenticating' && Waiting for authentication...
}
- {mcp.state === 'ready' && (
-
- Connected! Tools: {mcp.tools.length}, Resources: {mcp.resources.length + mcp.resourceTemplates.length},
- Prompts: {mcp.prompts.length}
-
- )}
+ {mcp.state === 'ready' &&