@phake/mcp 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,19 +1,33 @@
|
|
|
1
1
|
# @phake/mcp
|
|
2
2
|
|
|
3
|
-
A TypeScript library for building MCP (Model Context Protocol) servers
|
|
3
|
+
A TypeScript library for building [MCP (Model Context Protocol)](https://modelcontextprotocol.io) servers on Cloudflare Workers.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@phake/mcp)
|
|
6
|
+
[](LICENSE)
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
---
|
|
8
9
|
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
10
|
+
- [Requirements](#requirements)
|
|
11
|
+
- [Installation](#installation)
|
|
12
|
+
- [Getting Started](#getting-started)
|
|
13
|
+
- [Usage](#usage)
|
|
14
|
+
- [Defining Tools](#defining-tools)
|
|
15
|
+
- [Authenticated Tools](#authenticated-tools)
|
|
16
|
+
- [Authentication Strategies](#authentication-strategies)
|
|
17
|
+
- [Storage Backends](#storage-backends)
|
|
18
|
+
- [API Reference](#api-reference)
|
|
19
|
+
- [Endpoints](#endpoints)
|
|
20
|
+
- [Configuration](#configuration)
|
|
21
|
+
- [Contributing](#contributing)
|
|
22
|
+
- [License](#license)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Requirements
|
|
27
|
+
|
|
28
|
+
- [Bun](https://bun.sh) or Node.js 20+
|
|
29
|
+
- [Wrangler](https://developers.cloudflare.com/workers/wrangler/) CLI
|
|
30
|
+
- A Cloudflare account with Workers and KV access
|
|
17
31
|
|
|
18
32
|
## Installation
|
|
19
33
|
|
|
@@ -21,80 +35,84 @@ A TypeScript library for building MCP (Model Context Protocol) servers, designed
|
|
|
21
35
|
bun add @phake/mcp
|
|
22
36
|
```
|
|
23
37
|
|
|
24
|
-
##
|
|
38
|
+
## Getting Started
|
|
25
39
|
|
|
26
|
-
###
|
|
40
|
+
### 1. Create the KV namespace
|
|
27
41
|
|
|
28
|
-
```
|
|
29
|
-
|
|
42
|
+
```bash
|
|
43
|
+
wrangler kv namespace create TOKENS
|
|
44
|
+
```
|
|
30
45
|
|
|
31
|
-
|
|
32
|
-
adapter: "worker",
|
|
33
|
-
tools: [
|
|
34
|
-
// your tool definitions
|
|
35
|
-
],
|
|
36
|
-
});
|
|
46
|
+
### 2. Bind it in your Wrangler config
|
|
37
47
|
|
|
38
|
-
|
|
48
|
+
Use the namespace ID printed in the previous step.
|
|
49
|
+
|
|
50
|
+
`wrangler.toml`
|
|
51
|
+
```toml
|
|
52
|
+
[[kv_namespaces]]
|
|
53
|
+
binding = "TOKENS"
|
|
54
|
+
id = "<your-kv-namespace-id>"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
`wrangler.jsonc`
|
|
58
|
+
```jsonc
|
|
59
|
+
{
|
|
60
|
+
"kv_namespaces": [
|
|
61
|
+
{
|
|
62
|
+
"binding": "TOKENS",
|
|
63
|
+
"id": "<your-kv-namespace-id>"
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
39
67
|
```
|
|
40
68
|
|
|
41
|
-
###
|
|
69
|
+
### 3. Generate an encryption key
|
|
42
70
|
|
|
43
|
-
|
|
44
|
-
import { createHttpApp, createAuthApp } from "@phake/mcp/runtime/node";
|
|
71
|
+
Tokens at rest are encrypted with AES-256-GCM. Generate a 32-byte key:
|
|
45
72
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
],
|
|
50
|
-
});
|
|
73
|
+
```bash
|
|
74
|
+
# OpenSSL
|
|
75
|
+
openssl rand -base64 32 | tr '+/' '-_' | tr -d '='
|
|
51
76
|
|
|
52
|
-
|
|
77
|
+
# Node.js
|
|
78
|
+
node -e "const {randomBytes}=require('crypto'); console.log(randomBytes(32).toString('base64url'))"
|
|
53
79
|
```
|
|
54
80
|
|
|
55
|
-
|
|
81
|
+
### 4. Set the encryption key
|
|
56
82
|
|
|
57
|
-
|
|
83
|
+
**Production** - add as a Wrangler secret:
|
|
58
84
|
|
|
59
|
-
|
|
85
|
+
```bash
|
|
86
|
+
wrangler secret put RS_TOKENS_ENC_KEY
|
|
87
|
+
# paste the generated key when prompted
|
|
88
|
+
```
|
|
60
89
|
|
|
61
|
-
|
|
62
|
-
|--------|------|-------------|
|
|
63
|
-
| `adapter` | `"worker" \| "node"` | Runtime adapter |
|
|
64
|
-
| `tools` | `SharedToolDefinition[]` | Array of tool definitions to register |
|
|
90
|
+
**Local development** - add to `.dev.vars`:
|
|
65
91
|
|
|
66
|
-
|
|
92
|
+
```ini
|
|
93
|
+
RS_TOKENS_ENC_KEY=<your-generated-key>
|
|
94
|
+
```
|
|
67
95
|
|
|
68
|
-
|
|
69
|
-
|--------|------|
|
|
70
|
-
| Core | `@phake/mcp` |
|
|
71
|
-
| Node runtime | `@phake/mcp/runtime/node` |
|
|
72
|
-
| Worker runtime | `@phake/mcp/runtime/worker` |
|
|
96
|
+
### 5. Create your Worker
|
|
73
97
|
|
|
74
|
-
|
|
98
|
+
```typescript
|
|
99
|
+
import { createMCPServer } from "@phake/mcp";
|
|
75
100
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
| `none` | No authentication required | - |
|
|
101
|
+
const server = createMCPServer({
|
|
102
|
+
adapter: "worker",
|
|
103
|
+
tools: [
|
|
104
|
+
// your tool definitions
|
|
105
|
+
],
|
|
106
|
+
});
|
|
83
107
|
|
|
84
|
-
|
|
108
|
+
export default server;
|
|
109
|
+
```
|
|
85
110
|
|
|
86
|
-
|
|
87
|
-
|---------|--------|--------------|
|
|
88
|
-
| `MemoryTokenStore` | Tokens, transactions, codes | TTL expiration, size limits (10K tokens), LRU eviction |
|
|
89
|
-
| `MemorySessionStore` | Sessions | TTL (24h), size limit (10K), per-API-key limits (5) |
|
|
90
|
-
| `KvTokenStore` | Tokens, transactions, codes | Cloudflare KV + memory fallback, AES-256-GCM encryption |
|
|
91
|
-
| `KvSessionStore` | Sessions | Cloudflare KV + memory fallback, encryption, API-key indexing |
|
|
92
|
-
| `FileTokenStore` | RS token mappings | JSON file persistence, AES-256-GCM encryption, secure permissions (0600) |
|
|
93
|
-
| `SqliteSessionStore` | Sessions | SQLite via better-sqlite3 + Drizzle ORM, WAL mode, atomic transactions |
|
|
111
|
+
## Usage
|
|
94
112
|
|
|
95
|
-
|
|
113
|
+
### Defining Tools
|
|
96
114
|
|
|
97
|
-
Use `defineTool` to create a type-safe tool
|
|
115
|
+
Use `defineTool` to create a type-safe tool, then pass it to `createMCPServer`.
|
|
98
116
|
|
|
99
117
|
```typescript
|
|
100
118
|
import { z } from "zod";
|
|
@@ -125,14 +143,24 @@ const greetTool = defineTool({
|
|
|
125
143
|
});
|
|
126
144
|
```
|
|
127
145
|
|
|
146
|
+
**Tool definition fields:**
|
|
147
|
+
|
|
148
|
+
| Field | Type | Required | Description |
|
|
149
|
+
|-------|------|----------|-------------|
|
|
150
|
+
| `name` | `string` | Yes | Unique tool identifier |
|
|
151
|
+
| `description` | `string` | Yes | Description shown to the LLM |
|
|
152
|
+
| `inputSchema` | `ZodObject` | Yes | Zod schema for input validation |
|
|
153
|
+
| `outputSchema` | `ZodRawShape` | No | Zod schema for structured output |
|
|
154
|
+
| `handler` | `function` | Yes | `(args, context) => Promise<ToolResult>` |
|
|
155
|
+
| `requiresAuth` | `boolean` | No | Reject calls without a provider token |
|
|
156
|
+
| `title` | `string` | No | Human-readable display title |
|
|
157
|
+
| `annotations` | `object` | No | MCP hints (`readOnlyHint`, `destructiveHint`, etc.) |
|
|
158
|
+
|
|
128
159
|
### Authenticated Tools
|
|
129
160
|
|
|
130
|
-
Set `requiresAuth: true` to have the dispatcher automatically reject calls
|
|
161
|
+
Set `requiresAuth: true` to have the dispatcher automatically reject unauthenticated calls. Use `context.resolvedHeaders` to forward auth to external APIs.
|
|
131
162
|
|
|
132
163
|
```typescript
|
|
133
|
-
import { defineTool } from "@phake/mcp";
|
|
134
|
-
import { z } from "zod";
|
|
135
|
-
|
|
136
164
|
const profileTool = defineTool({
|
|
137
165
|
name: "get_profile",
|
|
138
166
|
description: "Fetch the authenticated user's profile",
|
|
@@ -150,7 +178,44 @@ const profileTool = defineTool({
|
|
|
150
178
|
});
|
|
151
179
|
```
|
|
152
180
|
|
|
153
|
-
|
|
181
|
+
**Available context properties:**
|
|
182
|
+
|
|
183
|
+
| Property | Description |
|
|
184
|
+
|----------|-------------|
|
|
185
|
+
| `sessionId` | Current MCP session ID |
|
|
186
|
+
| `providerToken` | Access token for external API calls |
|
|
187
|
+
| `resolvedHeaders` | Ready-to-use auth headers for `fetch` |
|
|
188
|
+
| `authStrategy` | Active auth strategy |
|
|
189
|
+
| `signal` | `AbortSignal` for cancellation |
|
|
190
|
+
|
|
191
|
+
### Authentication Strategies
|
|
192
|
+
|
|
193
|
+
Set `AUTH_STRATEGY` in your environment (or let it be inferred from which keys are present):
|
|
194
|
+
|
|
195
|
+
| Strategy | Description | Required env vars |
|
|
196
|
+
|----------|-------------|-------------------|
|
|
197
|
+
| `oauth` | Full OAuth 2.1 PKCE flow with RS token => provider token mapping | `OAUTH_CLIENT_ID`, `OAUTH_CLIENT_SECRET`, `OAUTH_SCOPES`, `OAUTH_REDIRECT_URI`, `PROVIDER_CLIENT_ID`, `PROVIDER_CLIENT_SECRET`, `PROVIDER_ACCOUNTS_URL` |
|
|
198
|
+
| `bearer` | Static Bearer token | `BEARER_TOKEN` |
|
|
199
|
+
| `api_key` | Static API key via header (default: `x-api-key`) | `API_KEY`, `API_KEY_HEADER` |
|
|
200
|
+
| `custom` | Arbitrary custom request headers | `CUSTOM_HEADERS` |
|
|
201
|
+
| `none` | No authentication | - |
|
|
202
|
+
|
|
203
|
+
### Storage Backends
|
|
204
|
+
|
|
205
|
+
| Backend | Use case | Notes |
|
|
206
|
+
|---------|----------|-------|
|
|
207
|
+
| `KvTokenStore` | Tokens, transactions, codes | Cloudflare KV + memory fallback, AES-256-GCM encryption |
|
|
208
|
+
| `KvSessionStore` | Sessions | Cloudflare KV + memory fallback, encryption, API-key indexing |
|
|
209
|
+
| `MemoryTokenStore` | Tokens, transactions, codes | TTL expiration, 10K token limit, LRU eviction |
|
|
210
|
+
| `MemorySessionStore` | Sessions | TTL (24h), 10K limit, per-API-key limit (5) |
|
|
211
|
+
| `FileTokenStore` | RS token mappings | File persistence, AES-256-GCM - **experimental** |
|
|
212
|
+
| `SqliteSessionStore` | Sessions | SQLite + Drizzle ORM, WAL mode - **experimental** |
|
|
213
|
+
|
|
214
|
+
## API Reference
|
|
215
|
+
|
|
216
|
+
### `createMCPServer(options)`
|
|
217
|
+
|
|
218
|
+
Creates an MCP server instance.
|
|
154
219
|
|
|
155
220
|
```typescript
|
|
156
221
|
import { createMCPServer } from "@phake/mcp";
|
|
@@ -159,79 +224,34 @@ const server = createMCPServer({
|
|
|
159
224
|
adapter: "worker",
|
|
160
225
|
tools: [greetTool, profileTool],
|
|
161
226
|
});
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### Tool Handler Reference
|
|
165
227
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
| `name` | `string` | Yes | Unique tool name |
|
|
169
|
-
| `description` | `string` | Yes | Description shown to the LLM |
|
|
170
|
-
| `inputSchema` | `ZodObject` | Yes | Zod schema for input validation |
|
|
171
|
-
| `outputSchema` | `ZodRawShape` | No | Zod schema for structured output |
|
|
172
|
-
| `handler` | `function` | Yes | `(args, context) => Promise<ToolResult>` |
|
|
173
|
-
| `requiresAuth` | `boolean` | No | Reject calls without a provider token |
|
|
174
|
-
| `title` | `string` | No | Human-readable display title |
|
|
175
|
-
| `annotations` | `object` | No | MCP hints (`readOnlyHint`, `destructiveHint`, etc.) |
|
|
176
|
-
|
|
177
|
-
The `context` object provides:
|
|
228
|
+
export default server;
|
|
229
|
+
```
|
|
178
230
|
|
|
179
|
-
|
|
|
180
|
-
|
|
181
|
-
| `
|
|
182
|
-
| `
|
|
183
|
-
| `resolvedHeaders` | Ready-to-use auth headers for `fetch` |
|
|
184
|
-
| `authStrategy` | Active auth strategy |
|
|
185
|
-
| `signal` | `AbortSignal` for cancellation |
|
|
231
|
+
| Option | Type | Description |
|
|
232
|
+
|--------|------|-------------|
|
|
233
|
+
| `adapter` | `"worker"` | Runtime adapter |
|
|
234
|
+
| `tools` | `SharedToolDefinition[]` | Tools to register |
|
|
186
235
|
|
|
187
|
-
|
|
236
|
+
### Built-in Tools
|
|
188
237
|
|
|
189
238
|
| Tool | Input | Output | Description |
|
|
190
239
|
|------|-------|--------|-------------|
|
|
191
|
-
| `echo` | `{ message, uppercase? }` | `{ echoed, length }` | Echoes back a message
|
|
192
|
-
| `health` | `{ verbose? }` | `{ status, timestamp, runtime, uptime? }` | Reports server health
|
|
240
|
+
| `echo` | `{ message, uppercase? }` | `{ echoed, length }` | Echoes back a message |
|
|
241
|
+
| `health` | `{ verbose? }` | `{ status, timestamp, runtime, uptime? }` | Reports server health |
|
|
193
242
|
|
|
194
|
-
|
|
243
|
+
### Package Exports
|
|
195
244
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
│ └── http-worker/ # Cloudflare Workers adapter (itty-router)
|
|
205
|
-
│ ├── index.ts
|
|
206
|
-
│ ├── mcp.handler.ts
|
|
207
|
-
│ ├── routes.discovery.ts
|
|
208
|
-
│ ├── routes.oauth.ts
|
|
209
|
-
│ └── security.ts
|
|
210
|
-
├── runtime/
|
|
211
|
-
│ └── node/
|
|
212
|
-
│ ├── capabilities.ts
|
|
213
|
-
│ ├── context.ts
|
|
214
|
-
│ ├── mcp.ts
|
|
215
|
-
│ └── storage/
|
|
216
|
-
│ ├── file.ts
|
|
217
|
-
│ └── sqlite.ts
|
|
218
|
-
├── shared/
|
|
219
|
-
│ ├── auth/ # Authentication strategies
|
|
220
|
-
│ ├── config/ # Environment configuration (40+ fields)
|
|
221
|
-
│ ├── crypto/ # AES-256-GCM utilities
|
|
222
|
-
│ ├── http/ # CORS, JSON-RPC responses
|
|
223
|
-
│ ├── mcp/ # Protocol dispatcher, security, server internals
|
|
224
|
-
│ ├── oauth/ # Full OAuth 2.0 implementation (PKCE, CIMD, discovery)
|
|
225
|
-
│ ├── services/ # HTTP client
|
|
226
|
-
│ ├── storage/ # Token/session store interfaces and implementations
|
|
227
|
-
│ ├── tools/ # Tool definitions, registry, execution
|
|
228
|
-
│ ├── types/ # Shared type definitions
|
|
229
|
-
│ └── utils/ # Base64, cancellation, logger, pagination, etc.
|
|
230
|
-
├── mcp-server.ts # Server factory
|
|
231
|
-
└── index.ts # Main entry point
|
|
232
|
-
```
|
|
245
|
+
| Export | Path |
|
|
246
|
+
|--------|------|
|
|
247
|
+
| Core | `@phake/mcp` |
|
|
248
|
+
| Worker runtime | `@phake/mcp/runtime/worker` |
|
|
249
|
+
|
|
250
|
+
> **Node.js runtime** (`@phake/mcp/runtime/node`) is available but experimental and untested.
|
|
251
|
+
|
|
252
|
+
## Endpoints
|
|
233
253
|
|
|
234
|
-
|
|
254
|
+
### MCP
|
|
235
255
|
|
|
236
256
|
| Method | Path | Description |
|
|
237
257
|
|--------|------|-------------|
|
|
@@ -240,7 +260,7 @@ src/
|
|
|
240
260
|
| `DELETE` | `/mcp` | Session termination |
|
|
241
261
|
| `GET` | `/health` | Health check |
|
|
242
262
|
|
|
243
|
-
|
|
263
|
+
### OAuth
|
|
244
264
|
|
|
245
265
|
| Path | Description |
|
|
246
266
|
|------|-------------|
|
|
@@ -253,27 +273,57 @@ src/
|
|
|
253
273
|
| `/revoke` | Token revocation |
|
|
254
274
|
| `/register` | Dynamic client registration |
|
|
255
275
|
|
|
256
|
-
##
|
|
276
|
+
## Configuration
|
|
257
277
|
|
|
258
|
-
|
|
259
|
-
|---------|-------------|
|
|
260
|
-
| `bun run build` | Build with Bun |
|
|
261
|
-
| `bun run typecheck` | Run TypeScript type checking |
|
|
278
|
+
All configuration is read from environment variables / Wrangler bindings.
|
|
262
279
|
|
|
263
|
-
|
|
280
|
+
| Variable | Required | Description |
|
|
281
|
+
|----------|----------|-------------|
|
|
282
|
+
| `TOKENS` | Yes | Cloudflare KV namespace binding for token/session storage |
|
|
283
|
+
| `RS_TOKENS_ENC_KEY` | Yes | Base64url-encoded 32-byte AES-256-GCM encryption key |
|
|
284
|
+
| `AUTH_STRATEGY` | No | `oauth` \| `bearer` \| `api_key` \| `custom` \| `none` (inferred if unset) |
|
|
285
|
+
| `OAUTH_CLIENT_ID` | OAuth only | OAuth client ID |
|
|
286
|
+
| `OAUTH_CLIENT_SECRET` | OAuth only | OAuth client secret |
|
|
287
|
+
| `OAUTH_SCOPES` | OAuth only | Space-separated OAuth scopes |
|
|
288
|
+
| `OAUTH_REDIRECT_URI` | OAuth only | Redirect URI after authorization |
|
|
289
|
+
| `API_KEY` | api_key only | Static API key value |
|
|
290
|
+
| `BEARER_TOKEN` | bearer only | Static Bearer token value |
|
|
291
|
+
| `BASE_URL` | No | Base URL override (for reverse proxies) |
|
|
292
|
+
| `LOG_LEVEL` | No | `debug` \| `info` \| `warning` \| `error` (default: `info`) |
|
|
264
293
|
|
|
265
|
-
|
|
266
|
-
- `zod` - Schema validation
|
|
267
|
-
- `jose` - JWT and JWS/JWE
|
|
268
|
-
- `oauth4webapi` - OAuth 2.0 for Web API
|
|
269
|
-
- `itty-router` - Lightweight router (Workers)
|
|
270
|
-
- `hono` / `@hono/node-server` - Node.js HTTP framework (optional)
|
|
271
|
-
- `drizzle-orm` / `better-sqlite3` - Database layer (optional)
|
|
294
|
+
## Contributing
|
|
272
295
|
|
|
273
|
-
|
|
296
|
+
```bash
|
|
297
|
+
# Install dependencies
|
|
298
|
+
bun install
|
|
299
|
+
|
|
300
|
+
# Build
|
|
301
|
+
bun run build
|
|
302
|
+
|
|
303
|
+
# Type check
|
|
304
|
+
bun run typecheck
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
**Project structure:**
|
|
308
|
+
|
|
309
|
+
```
|
|
310
|
+
src/
|
|
311
|
+
├── adapters/
|
|
312
|
+
│ └── http-worker/ # Cloudflare Workers adapter
|
|
313
|
+
├── shared/
|
|
314
|
+
│ ├── auth/ # Authentication strategies
|
|
315
|
+
│ ├── config/ # Environment configuration
|
|
316
|
+
│ ├── crypto/ # AES-256-GCM utilities
|
|
317
|
+
│ ├── mcp/ # Protocol dispatcher and server internals
|
|
318
|
+
│ ├── oauth/ # OAuth 2.0 (PKCE, CIMD, discovery)
|
|
319
|
+
│ ├── storage/ # Token/session store interfaces and implementations
|
|
320
|
+
│ └── tools/ # Tool definitions, registry, execution
|
|
321
|
+
├── mcp-server.ts # Server factory
|
|
322
|
+
└── index.ts # Package entry point
|
|
323
|
+
```
|
|
274
324
|
|
|
275
|
-
|
|
325
|
+
Inspired by [streamable-mcp-server-template](https://github.com/iceener/streamable-mcp-server-template).
|
|
276
326
|
|
|
277
327
|
## License
|
|
278
328
|
|
|
279
|
-
|
|
329
|
+
[MIT](LICENSE)
|
|
@@ -1278,7 +1278,6 @@ function registerTools(server, contextResolver) {
|
|
|
1278
1278
|
|
|
1279
1279
|
// src/shared/mcp/dispatcher.ts
|
|
1280
1280
|
import { z as z3 } from "zod";
|
|
1281
|
-
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
1282
1281
|
|
|
1283
1282
|
// src/runtime/node/capabilities.ts
|
|
1284
1283
|
function buildCapabilities() {
|
|
@@ -1351,9 +1350,9 @@ async function handleToolsList(ctx) {
|
|
|
1351
1350
|
const tools = (ctx.tools ?? sharedTools).map((tool) => ({
|
|
1352
1351
|
name: tool.name,
|
|
1353
1352
|
description: tool.description,
|
|
1354
|
-
inputSchema:
|
|
1353
|
+
inputSchema: z3.toJSONSchema(tool.inputSchema),
|
|
1355
1354
|
...tool.outputSchema && {
|
|
1356
|
-
outputSchema:
|
|
1355
|
+
outputSchema: z3.toJSONSchema(z3.object(tool.outputSchema))
|
|
1357
1356
|
},
|
|
1358
1357
|
...tool.annotations && { annotations: tool.annotations }
|
|
1359
1358
|
}));
|
|
@@ -1760,7 +1759,7 @@ function buildUnauthorizedChallenge(args) {
|
|
|
1760
1759
|
return {
|
|
1761
1760
|
status: 401,
|
|
1762
1761
|
headers: {
|
|
1763
|
-
"WWW-Authenticate": `Bearer realm="MCP",
|
|
1762
|
+
"WWW-Authenticate": `Bearer realm="MCP", resource_metadata="${resourceMd}"`,
|
|
1764
1763
|
"Mcp-Session-Id": args.sid
|
|
1765
1764
|
},
|
|
1766
1765
|
body: {
|
|
@@ -2942,6 +2941,12 @@ function attachDiscoveryRoutes(router, config) {
|
|
|
2942
2941
|
const metadata = protectedResourceMetadata(here, sid);
|
|
2943
2942
|
return jsonResponse(metadata);
|
|
2944
2943
|
});
|
|
2944
|
+
router.get("/.well-known/oauth-protected-resource/*", async (request) => {
|
|
2945
|
+
const here = new URL(request.url);
|
|
2946
|
+
const sid = here.searchParams.get("sid") ?? undefined;
|
|
2947
|
+
const metadata = protectedResourceMetadata(here, sid);
|
|
2948
|
+
return jsonResponse(metadata);
|
|
2949
|
+
});
|
|
2945
2950
|
}
|
|
2946
2951
|
|
|
2947
2952
|
// src/adapters/http-worker/routes.oauth.ts
|
package/dist/index.js
CHANGED
|
@@ -82,7 +82,7 @@ import {
|
|
|
82
82
|
withCancellation,
|
|
83
83
|
withCors,
|
|
84
84
|
workerDiscoveryStrategy
|
|
85
|
-
} from "./index-
|
|
85
|
+
} from "./index-qmejk5tj.js";
|
|
86
86
|
// src/shared/config/env.ts
|
|
87
87
|
function parseBoolean(value) {
|
|
88
88
|
return String(value || "false").toLowerCase() === "true";
|
package/dist/mcp-server.d.ts
CHANGED
|
@@ -14,5 +14,9 @@ export interface MCPServer {
|
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
16
|
* Create an MCP server instance.
|
|
17
|
+
* @param {MCPServerOptions} options - Configuration options
|
|
18
|
+
* @param {string} options.adapter - Runtime adapter: 'worker' (Cloudflare Workers) or 'node' (Hono/Node.js)
|
|
19
|
+
* @param {SharedToolDefinition<any>[]} [options.tools] - Array of tools to register
|
|
20
|
+
* @returns {MCPServer} - MCP server instance
|
|
17
21
|
*/
|
|
18
22
|
export declare function createMCPServer(options: MCPServerOptions): MCPServer;
|
|
@@ -108,8 +108,8 @@ export interface ElicitResult {
|
|
|
108
108
|
}
|
|
109
109
|
export declare const ElicitResultSchema: z.ZodObject<{
|
|
110
110
|
action: z.ZodEnum<{
|
|
111
|
-
cancel: "cancel";
|
|
112
111
|
accept: "accept";
|
|
112
|
+
cancel: "cancel";
|
|
113
113
|
decline: "decline";
|
|
114
114
|
}>;
|
|
115
115
|
content: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodArray<z.ZodString>]>>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phake/mcp",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/fuongz/phake-mcp"
|
|
@@ -37,8 +37,7 @@
|
|
|
37
37
|
"itty-router": "^5.0.23",
|
|
38
38
|
"jose": "^6.2.2",
|
|
39
39
|
"oauth4webapi": "^3.8.5",
|
|
40
|
-
"zod": "^4.3.6"
|
|
41
|
-
"zod-to-json-schema": "^3.25.2"
|
|
40
|
+
"zod": "^4.3.6"
|
|
42
41
|
},
|
|
43
42
|
"optionalDependencies": {
|
|
44
43
|
"@hono/node-server": "^1.19.12",
|
|
@@ -47,7 +46,6 @@
|
|
|
47
46
|
"hono": "^4.12.9"
|
|
48
47
|
},
|
|
49
48
|
"devDependencies": {
|
|
50
|
-
"@cloudflare/workers-types": "^4.20260401.1",
|
|
51
49
|
"@types/better-sqlite3": "^7.6.13",
|
|
52
50
|
"bun-types": "^1.3.11",
|
|
53
51
|
"typescript": "^6.0.2"
|