@mcphero/mcp 1.1.6 → 1.3.0
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/.turbo/turbo-build.log +17 -18
- package/.turbo/turbo-check.log +3 -3
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-prepack.log +8 -8
- package/README.md +91 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +186 -145
- package/build/index.js.map +1 -1
- package/package.json +4 -3
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
DTS Build
|
|
17
|
-
DTS
|
|
18
|
-
DTS build/index.d.ts 521.00 B
|
|
1
|
+
|
|
2
|
+
> @mcphero/mcp@1.2.0 build /Users/atomic/projects/ai/mcphero/packages/mcp
|
|
3
|
+
> tsup
|
|
4
|
+
|
|
5
|
+
CLI Building entry: src/index.ts
|
|
6
|
+
CLI Using tsconfig: tsconfig.json
|
|
7
|
+
CLI tsup v8.5.1
|
|
8
|
+
CLI Using tsup config: /Users/atomic/projects/ai/mcphero/packages/mcp/tsup.config.ts
|
|
9
|
+
CLI Target: es2022
|
|
10
|
+
CLI Cleaning output folder
|
|
11
|
+
ESM Build start
|
|
12
|
+
ESM build/index.js 16.84 KB
|
|
13
|
+
ESM build/index.js.map 29.10 KB
|
|
14
|
+
ESM ⚡️ Build success in 11ms
|
|
15
|
+
DTS Build start
|
|
16
|
+
DTS ⚡️ Build success in 812ms
|
|
17
|
+
DTS build/index.d.ts 588.00 B
|
package/.turbo/turbo-check.log
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
|
|
2
|
-
> @mcphero/mcp@1.
|
|
2
|
+
> @mcphero/mcp@1.2.0 check /Users/atomic/projects/ai/mcphero/packages/mcp
|
|
3
3
|
> pnpm lint && pnpm typecheck
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @mcphero/mcp@1.
|
|
6
|
+
> @mcphero/mcp@1.2.0 lint /Users/atomic/projects/ai/mcphero/packages/mcp
|
|
7
7
|
> eslint
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
> @mcphero/mcp@1.
|
|
10
|
+
> @mcphero/mcp@1.2.0 typecheck /Users/atomic/projects/ai/mcphero/packages/mcp
|
|
11
11
|
> tsc --noEmit
|
|
12
12
|
|
package/.turbo/turbo-lint.log
CHANGED
package/.turbo/turbo-prepack.log
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> @mcphero/mcp@1.
|
|
3
|
+
> @mcphero/mcp@1.2.0 prepack /Users/atomic/projects/ai/mcphero/packages/mcp
|
|
4
4
|
> pnpm clean && pnpm build
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
> @mcphero/mcp@1.
|
|
7
|
+
> @mcphero/mcp@1.2.0 clean /Users/atomic/projects/ai/mcphero/packages/mcp
|
|
8
8
|
> rimraf build
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
> @mcphero/mcp@1.
|
|
11
|
+
> @mcphero/mcp@1.2.0 build /Users/atomic/projects/ai/mcphero/packages/mcp
|
|
12
12
|
> tsup
|
|
13
13
|
|
|
14
14
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
[34mCLI[39m Target: es2022
|
|
19
19
|
[34mCLI[39m Cleaning output folder
|
|
20
20
|
[34mESM[39m Build start
|
|
21
|
-
[32mESM[39m [1mbuild/index.js [22m[
|
|
22
|
-
[32mESM[39m [1mbuild/index.js.map [22m[
|
|
23
|
-
[32mESM[39m ⚡️ Build success in
|
|
21
|
+
[32mESM[39m [1mbuild/index.js [22m[32m16.84 KB[39m
|
|
22
|
+
[32mESM[39m [1mbuild/index.js.map [22m[32m29.10 KB[39m
|
|
23
|
+
[32mESM[39m ⚡️ Build success in 16ms
|
|
24
24
|
DTS Build start
|
|
25
|
-
DTS ⚡️ Build success in
|
|
26
|
-
DTS build/index.d.ts
|
|
25
|
+
DTS ⚡️ Build success in 987ms
|
|
26
|
+
DTS build/index.d.ts 588.00 B
|
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# @mcphero/mcp
|
|
2
|
+
|
|
3
|
+
MCP transport adapters for [MCPHero](https://github.com/atomicbi/mcphero) — expose your actions as MCP tools over stdio, Streamable HTTP, or via a CLI proxy client.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @mcphero/core @mcphero/mcp
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Adapters
|
|
12
|
+
|
|
13
|
+
### stdio
|
|
14
|
+
|
|
15
|
+
Standard MCP transport for local tool servers. Communicates over stdin/stdout.
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { mcphero } from '@mcphero/core'
|
|
19
|
+
import { stdio } from '@mcphero/mcp'
|
|
20
|
+
|
|
21
|
+
await mcphero({ name: 'my-tools', description: 'My Tools', version: '1.0.0' })
|
|
22
|
+
.adapter(stdio())
|
|
23
|
+
.action(MyAction)
|
|
24
|
+
.start()
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Configure in Claude Desktop or Claude Code:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"mcpServers": {
|
|
32
|
+
"my-tools": {
|
|
33
|
+
"command": "node",
|
|
34
|
+
"args": ["server.js"]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### http
|
|
41
|
+
|
|
42
|
+
Session-based MCP transport over HTTP with SSE streaming and resumability.
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { mcphero } from '@mcphero/core'
|
|
46
|
+
import { http } from '@mcphero/mcp'
|
|
47
|
+
|
|
48
|
+
await mcphero({ name: 'my-tools', description: 'My Tools', version: '1.0.0' })
|
|
49
|
+
.adapter(http({ host: 'localhost', port: 8080, allowedHosts: ['localhost'] }))
|
|
50
|
+
.action(MyAction)
|
|
51
|
+
.start()
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Exposes `POST /mcp` (invoke tools), `GET /mcp` (SSE stream), and `DELETE /mcp` (terminate session). Built on Express with `StreamableHTTPServerTransport` from the MCP SDK.
|
|
55
|
+
|
|
56
|
+
| Option | Type | Description |
|
|
57
|
+
|--------|------|-------------|
|
|
58
|
+
| `host` | `string` | Bind address |
|
|
59
|
+
| `port` | `number` | Listen port |
|
|
60
|
+
| `allowedHosts` | `string[]` | Allowed hosts for DNS rebinding protection |
|
|
61
|
+
|
|
62
|
+
### cliProxy
|
|
63
|
+
|
|
64
|
+
MCP CLI proxy client — connects to a running HTTP MCP server and invokes tools from the command line.
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { mcphero } from '@mcphero/core'
|
|
68
|
+
import { cliProxy } from '@mcphero/mcp'
|
|
69
|
+
|
|
70
|
+
await mcphero({ name: 'my-tools', description: 'My Tools', version: '1.0.0' })
|
|
71
|
+
.adapter(cliProxy({ url: 'http://localhost:8080/mcp' }))
|
|
72
|
+
.start()
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## How Actions Become MCP Tools
|
|
76
|
+
|
|
77
|
+
| Action property | MCP tool property |
|
|
78
|
+
|-----------------|-------------------|
|
|
79
|
+
| `name: 'searchDocs'` | Tool name: `SearchDocs` (PascalCase) |
|
|
80
|
+
| `description` | Tool description |
|
|
81
|
+
| `input` (Zod schema) | `inputSchema` (JSON Schema) |
|
|
82
|
+
| Return value | `TextContent` JSON response |
|
|
83
|
+
| Thrown errors | Structured error response |
|
|
84
|
+
|
|
85
|
+
Logging notifications (`logger.info()`, `logger.progress()`) are sent to the MCP client as `notifications/message` and `notifications/progress`.
|
|
86
|
+
|
|
87
|
+
## See Also
|
|
88
|
+
|
|
89
|
+
- [MCPHero README](https://github.com/atomicbi/mcphero) — Full documentation
|
|
90
|
+
- [`@mcphero/core`](https://www.npmjs.com/package/@mcphero/core) — Core library
|
|
91
|
+
- [`@mcphero/vercel`](https://www.npmjs.com/package/@mcphero/vercel) — Stateless MCP for Vercel
|
package/build/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AdapterFactory } from '@mcphero/core';
|
|
2
|
+
import { AuthConfig } from '@mcphero/auth';
|
|
2
3
|
import { CreateMcpExpressAppOptions } from '@modelcontextprotocol/sdk/server/express.js';
|
|
3
4
|
|
|
4
5
|
interface CliProxyOptions {
|
|
@@ -9,6 +10,7 @@ declare const cliProxy: AdapterFactory<CliProxyOptions>;
|
|
|
9
10
|
interface HttpAdapterOptions extends CreateMcpExpressAppOptions {
|
|
10
11
|
host: string;
|
|
11
12
|
port: number;
|
|
13
|
+
auth?: AuthConfig;
|
|
12
14
|
}
|
|
13
15
|
declare const http: AdapterFactory<HttpAdapterOptions>;
|
|
14
16
|
|
package/build/index.js
CHANGED
|
@@ -84,6 +84,7 @@ var cliProxy = ({ url }) => {
|
|
|
84
84
|
};
|
|
85
85
|
|
|
86
86
|
// src/adapter/http.ts
|
|
87
|
+
import { generateProtectedResourceMetadata, validateToken } from "@mcphero/auth";
|
|
87
88
|
import { toolResponse } from "@mcphero/core";
|
|
88
89
|
import { createLogger } from "@mcphero/logger";
|
|
89
90
|
import { InMemoryEventStore } from "@modelcontextprotocol/sdk/examples/shared/inMemoryEventStore.js";
|
|
@@ -94,61 +95,197 @@ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
|
94
95
|
import { capitalCase, pascalCase } from "change-case";
|
|
95
96
|
import cors from "cors";
|
|
96
97
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
98
|
+
import express from "express";
|
|
97
99
|
import { readFile } from "fs/promises";
|
|
98
|
-
|
|
100
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
101
|
+
var authStorage = new AsyncLocalStorage();
|
|
102
|
+
function mountOAuthRoutes(app, auth) {
|
|
103
|
+
const provider = auth.provider;
|
|
104
|
+
const callbackPath = auth.callbackPath ?? "/auth/callback";
|
|
105
|
+
const toOAuthReq = (req) => ({
|
|
106
|
+
method: req.method,
|
|
107
|
+
url: new URL(req.url, `${req.protocol}://${req.get("host")}`),
|
|
108
|
+
headers: Object.fromEntries(Object.entries(req.headers).map(([k, v]) => [k, Array.isArray(v) ? v[0] : v])),
|
|
109
|
+
body: req.body
|
|
110
|
+
});
|
|
111
|
+
const sendOAuth = (res, oauthRes) => {
|
|
112
|
+
for (const [key, value] of Object.entries(oauthRes.headers)) {
|
|
113
|
+
res.header(key, value);
|
|
114
|
+
}
|
|
115
|
+
if (oauthRes.body) {
|
|
116
|
+
res.status(oauthRes.status).send(typeof oauthRes.body === "string" ? oauthRes.body : JSON.stringify(oauthRes.body));
|
|
117
|
+
} else {
|
|
118
|
+
res.status(oauthRes.status).end();
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
app.get("/.well-known/oauth-authorization-server", (_req, res) => {
|
|
122
|
+
sendOAuth(res, provider.metadata());
|
|
123
|
+
});
|
|
124
|
+
app.get("/authorize", async (req, res) => {
|
|
125
|
+
sendOAuth(res, await provider.authorize(toOAuthReq(req)));
|
|
126
|
+
});
|
|
127
|
+
app.get(callbackPath, async (req, res) => {
|
|
128
|
+
sendOAuth(res, await provider.callback(toOAuthReq(req)));
|
|
129
|
+
});
|
|
130
|
+
app.post("/token", express.urlencoded({ extended: false }), async (req, res) => {
|
|
131
|
+
sendOAuth(res, await provider.token(toOAuthReq(req)));
|
|
132
|
+
});
|
|
133
|
+
app.post("/register", express.json(), async (req, res) => {
|
|
134
|
+
sendOAuth(res, await provider.register(toOAuthReq(req)));
|
|
135
|
+
});
|
|
136
|
+
return /* @__PURE__ */ new Set(["/.well-known/oauth-authorization-server", "/authorize", callbackPath, "/token", "/register"]);
|
|
137
|
+
}
|
|
138
|
+
function mountAuthMiddleware(app, auth, oauthPaths) {
|
|
139
|
+
app.use(async (req, res, next) => {
|
|
140
|
+
if (req.path.startsWith("/.well-known/") || oauthPaths.has(req.path)) {
|
|
141
|
+
return next();
|
|
142
|
+
}
|
|
143
|
+
const result = await validateToken(req.headers.authorization, auth);
|
|
144
|
+
if (result.error) {
|
|
145
|
+
for (const [key, value] of Object.entries(result.error.headers)) {
|
|
146
|
+
res.header(key, value);
|
|
147
|
+
}
|
|
148
|
+
res.status(result.error.statusCode).json(result.error.body);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (result.auth) {
|
|
152
|
+
authStorage.run(result.auth, () => {
|
|
153
|
+
next();
|
|
154
|
+
});
|
|
155
|
+
} else {
|
|
156
|
+
next();
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
function createMcpServer(options, actions, context) {
|
|
161
|
+
const server = new McpServer({
|
|
162
|
+
name: options.name,
|
|
163
|
+
description: options.description,
|
|
164
|
+
version: options.version
|
|
165
|
+
}, {
|
|
166
|
+
capabilities: { tools: {}, logging: {} }
|
|
167
|
+
});
|
|
168
|
+
for (const action of actions) {
|
|
169
|
+
server.registerTool(pascalCase(action.name), {
|
|
170
|
+
title: capitalCase(action.name),
|
|
171
|
+
description: action.description,
|
|
172
|
+
inputSchema: action.input
|
|
173
|
+
}, async (input, extra) => {
|
|
174
|
+
const logger = createLogger({
|
|
175
|
+
stream: process.stderr,
|
|
176
|
+
onLog: (level, data) => {
|
|
177
|
+
extra.sendNotification({ method: "notifications/message", params: { level, data } });
|
|
178
|
+
},
|
|
179
|
+
onProgress: ({ progress, total, message }) => {
|
|
180
|
+
if (!extra._meta?.progressToken) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
extra.sendNotification({
|
|
184
|
+
method: "notifications/progress",
|
|
185
|
+
params: {
|
|
186
|
+
progress,
|
|
187
|
+
total,
|
|
188
|
+
message,
|
|
189
|
+
progressToken: extra._meta.progressToken
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
const currentAuth = authStorage.getStore();
|
|
195
|
+
return action.run(input, context.fork({ logger, extra, ...currentAuth ? { auth: currentAuth } : {} })).then((result) => {
|
|
196
|
+
return toolResponse(result);
|
|
197
|
+
}).catch((error) => {
|
|
198
|
+
if (error instanceof Error) {
|
|
199
|
+
return toolResponse({ success: false, name: error.name, message: error.message, stack: error.stack });
|
|
200
|
+
} else {
|
|
201
|
+
return toolResponse({ success: false, name: "Unknown Error", message: "An unknown error occured", error });
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
return server;
|
|
207
|
+
}
|
|
208
|
+
function mountMcpTransport(app, transports, createServer) {
|
|
209
|
+
app.post("/mcp", async (req, res) => {
|
|
210
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
211
|
+
try {
|
|
212
|
+
let transport;
|
|
213
|
+
if (sessionId && transports[sessionId]) {
|
|
214
|
+
transport = transports[sessionId];
|
|
215
|
+
} else if (isInitializeRequest(req.body)) {
|
|
216
|
+
const eventStore = new InMemoryEventStore();
|
|
217
|
+
transport = new StreamableHTTPServerTransport({
|
|
218
|
+
sessionIdGenerator: () => randomUUID2(),
|
|
219
|
+
enableJsonResponse: false,
|
|
220
|
+
eventStore,
|
|
221
|
+
onsessioninitialized: (sId) => {
|
|
222
|
+
console.log(`Session initialized with ID: ${sId}`);
|
|
223
|
+
transports[sId] = transport;
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
transport.onerror = (error) => {
|
|
227
|
+
console.error(error);
|
|
228
|
+
};
|
|
229
|
+
transport.onclose = () => {
|
|
230
|
+
const sid = transport.sessionId;
|
|
231
|
+
if (sid && transports[sid]) {
|
|
232
|
+
console.log(`Transport closed for session ${sid}, removing from transports map`);
|
|
233
|
+
delete transports[sid];
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
await createServer().connect(transport);
|
|
237
|
+
await transport.handleRequest(req, res, req.body);
|
|
238
|
+
return;
|
|
239
|
+
} else {
|
|
240
|
+
res.status(404).json({
|
|
241
|
+
jsonrpc: "2.0",
|
|
242
|
+
error: { code: -32e3, message: "Session not found" },
|
|
243
|
+
id: null
|
|
244
|
+
});
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
await transport.handleRequest(req, res, req.body);
|
|
248
|
+
} catch (error) {
|
|
249
|
+
console.error("Error handling MCP request:", error);
|
|
250
|
+
if (!res.headersSent) {
|
|
251
|
+
res.status(500).json({
|
|
252
|
+
jsonrpc: "2.0",
|
|
253
|
+
error: { code: -32603, message: "Internal server error" },
|
|
254
|
+
id: null
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
const handleSessionStream = async (req, res) => {
|
|
260
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
261
|
+
if (!sessionId || !transports[sessionId]) {
|
|
262
|
+
res.status(400).send("Invalid or missing session ID");
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const transport = transports[sessionId];
|
|
266
|
+
await transport.handleRequest(req, res);
|
|
267
|
+
};
|
|
268
|
+
app.get("/mcp", handleSessionStream);
|
|
269
|
+
app.delete("/mcp", handleSessionStream);
|
|
270
|
+
app.get("/mcp/resource/:id", handleSessionStream);
|
|
271
|
+
}
|
|
272
|
+
var http = ({ host, port, auth, ...mcpOptions }) => {
|
|
99
273
|
return (options, baseContext) => {
|
|
100
274
|
const context = baseContext.fork({ adapter: "http" });
|
|
101
275
|
const app = createMcpExpressApp({ ...mcpOptions, host });
|
|
102
276
|
app.use(cors({ exposedHeaders: ["WWW-Authenticate", "Mcp-Session-Id", "Last-Event-Id", "Mcp-Protocol-Version"], origin: "*" }));
|
|
277
|
+
if (auth?.authorizationServers?.length && auth.resourceUrl) {
|
|
278
|
+
app.get("/.well-known/oauth-protected-resource", (_req, res) => {
|
|
279
|
+
const metadata = generateProtectedResourceMetadata(auth.resourceUrl, auth.authorizationServers);
|
|
280
|
+
res.json(metadata);
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
const oauthPaths = auth?.provider ? mountOAuthRoutes(app, auth) : /* @__PURE__ */ new Set();
|
|
284
|
+
if (auth) {
|
|
285
|
+
mountAuthMiddleware(app, auth, oauthPaths);
|
|
286
|
+
}
|
|
103
287
|
const transports = {};
|
|
104
288
|
let mountedActions = [];
|
|
105
|
-
const createServer = () => {
|
|
106
|
-
const server = new McpServer({
|
|
107
|
-
name: options.name,
|
|
108
|
-
description: options.description,
|
|
109
|
-
version: options.version
|
|
110
|
-
}, {
|
|
111
|
-
capabilities: { tools: {}, logging: {} }
|
|
112
|
-
});
|
|
113
|
-
for (const action of mountedActions) {
|
|
114
|
-
server.registerTool(pascalCase(action.name), {
|
|
115
|
-
title: capitalCase(action.name),
|
|
116
|
-
description: action.description,
|
|
117
|
-
inputSchema: action.input
|
|
118
|
-
}, async (input, extra) => {
|
|
119
|
-
const logger = createLogger({
|
|
120
|
-
stream: process.stderr,
|
|
121
|
-
onLog: (level, data) => {
|
|
122
|
-
extra.sendNotification({ method: "notifications/message", params: { level, data } });
|
|
123
|
-
},
|
|
124
|
-
onProgress: ({ progress, total, message }) => {
|
|
125
|
-
if (!extra._meta?.progressToken) {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
extra.sendNotification({
|
|
129
|
-
method: "notifications/progress",
|
|
130
|
-
params: {
|
|
131
|
-
progress,
|
|
132
|
-
total,
|
|
133
|
-
message,
|
|
134
|
-
progressToken: extra._meta.progressToken
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
return action.run(input, context.fork({ logger, extra })).then((result) => {
|
|
140
|
-
return toolResponse(result);
|
|
141
|
-
}).catch((error) => {
|
|
142
|
-
if (error instanceof Error) {
|
|
143
|
-
return toolResponse({ success: false, name: error.name, message: error.message, stack: error.stack });
|
|
144
|
-
} else {
|
|
145
|
-
return toolResponse({ success: false, name: "Unknown Error", message: "An unknown error occured", error });
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
return server;
|
|
151
|
-
};
|
|
152
289
|
app.get("/resource/:id", async (req, res) => {
|
|
153
290
|
const id = req.params.id;
|
|
154
291
|
if (!id || typeof id !== "string") {
|
|
@@ -160,103 +297,7 @@ var http = ({ host, port, ...mcpOptions }) => {
|
|
|
160
297
|
res.header("Content-Type", resourceMeta.contentType);
|
|
161
298
|
res.send(buffer);
|
|
162
299
|
});
|
|
163
|
-
app
|
|
164
|
-
const sessionId = req.headers["mcp-session-id"];
|
|
165
|
-
try {
|
|
166
|
-
let transport;
|
|
167
|
-
if (sessionId && transports[sessionId]) {
|
|
168
|
-
transport = transports[sessionId];
|
|
169
|
-
} else if (!sessionId && isInitializeRequest(req.body)) {
|
|
170
|
-
const eventStore = new InMemoryEventStore();
|
|
171
|
-
transport = new StreamableHTTPServerTransport({
|
|
172
|
-
sessionIdGenerator: () => randomUUID2(),
|
|
173
|
-
enableJsonResponse: false,
|
|
174
|
-
eventStore,
|
|
175
|
-
onsessioninitialized: (sId) => {
|
|
176
|
-
console.log(`Session initialized with ID: ${sId}`);
|
|
177
|
-
transports[sId] = transport;
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
transport.onerror = (error) => {
|
|
181
|
-
console.error(error);
|
|
182
|
-
};
|
|
183
|
-
transport.onclose = () => {
|
|
184
|
-
const sid = transport.sessionId;
|
|
185
|
-
if (sid && transports[sid]) {
|
|
186
|
-
console.log(`Transport closed for session ${sid}, removing from transports map`);
|
|
187
|
-
delete transports[sid];
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
await createServer().connect(transport);
|
|
191
|
-
await transport.handleRequest(req, res, req.body);
|
|
192
|
-
return;
|
|
193
|
-
} else {
|
|
194
|
-
res.status(400).json({
|
|
195
|
-
jsonrpc: "2.0",
|
|
196
|
-
error: { code: -32e3, message: "Bad Request: No valid session ID provided" },
|
|
197
|
-
id: null
|
|
198
|
-
});
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
await transport.handleRequest(req, res, req.body);
|
|
202
|
-
} catch (error) {
|
|
203
|
-
console.error("Error handling MCP request:", error);
|
|
204
|
-
if (!res.headersSent) {
|
|
205
|
-
res.status(500).json({
|
|
206
|
-
jsonrpc: "2.0",
|
|
207
|
-
error: { code: -32603, message: "Internal server error" },
|
|
208
|
-
id: null
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
app.get("/mcp", async (req, res) => {
|
|
214
|
-
const sessionId = req.headers["mcp-session-id"];
|
|
215
|
-
if (!sessionId || !transports[sessionId]) {
|
|
216
|
-
res.status(400).send("Invalid or missing session ID");
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
const lastEventId = req.headers["last-event-id"];
|
|
220
|
-
if (lastEventId) {
|
|
221
|
-
console.log(`Client reconnecting with Last-Event-ID: ${lastEventId}`);
|
|
222
|
-
} else {
|
|
223
|
-
console.log(`Establishing new SSE stream for session ${sessionId}`);
|
|
224
|
-
}
|
|
225
|
-
const transport = transports[sessionId];
|
|
226
|
-
await transport.handleRequest(req, res);
|
|
227
|
-
});
|
|
228
|
-
app.delete("/mcp", async (req, res) => {
|
|
229
|
-
const sessionId = req.headers["mcp-session-id"];
|
|
230
|
-
if (!sessionId || !transports[sessionId]) {
|
|
231
|
-
res.status(400).send("Invalid or missing session ID");
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
console.log(`Received session termination request for session ${sessionId}`);
|
|
235
|
-
try {
|
|
236
|
-
const transport = transports[sessionId];
|
|
237
|
-
await transport.handleRequest(req, res);
|
|
238
|
-
} catch (error) {
|
|
239
|
-
console.error("Error handling session termination:", error);
|
|
240
|
-
if (!res.headersSent) {
|
|
241
|
-
res.status(500).send("Error processing session termination");
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
app.get("/mcp/resource/:id", async (req, res) => {
|
|
246
|
-
const sessionId = req.headers["mcp-session-id"];
|
|
247
|
-
if (!sessionId || !transports[sessionId]) {
|
|
248
|
-
res.status(400).send("Invalid or missing session ID");
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
const lastEventId = req.headers["last-event-id"];
|
|
252
|
-
if (lastEventId) {
|
|
253
|
-
console.log(`Client reconnecting with Last-Event-ID: ${lastEventId}`);
|
|
254
|
-
} else {
|
|
255
|
-
console.log(`Establishing new SSE stream for session ${sessionId}`);
|
|
256
|
-
}
|
|
257
|
-
const transport = transports[sessionId];
|
|
258
|
-
await transport.handleRequest(req, res);
|
|
259
|
-
});
|
|
300
|
+
mountMcpTransport(app, transports, () => createMcpServer(options, mountedActions, context));
|
|
260
301
|
let httpServer;
|
|
261
302
|
return {
|
|
262
303
|
context,
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapter/cliProxy.ts","../src/adapter/http.ts","../src/adapter/stdio.ts"],"sourcesContent":["import { intro } from '@clack/prompts'\nimport { AdapterFactory, parseToolResponse, ToolResponse, unwrap } from '@mcphero/core'\nimport { createCLILogger } from '@mcphero/logger'\nimport { Client } from '@modelcontextprotocol/sdk/client'\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'\nimport { LoggingMessageNotificationSchema, ProgressNotificationSchema } from '@modelcontextprotocol/sdk/types'\nimport { kebabCase } from 'change-case'\nimport { Command } from 'commander'\nimport { randomUUID } from 'crypto'\nimport { z } from 'zod'\nimport { JSONSchema } from 'zod/v4/core'\n\nexport interface CliProxyOptions {\n url: URL\n}\n\nexport const cliProxy: AdapterFactory<CliProxyOptions> = ({ url }) => {\n return (options, baseContext) => {\n const context = baseContext.fork({ adapter: 'cliProxy' })\n const program = new Command()\n .name(options.name)\n .description(options.description)\n .version(options.version)\n .option('-s, --silent', 'Silent mode, prevent log messages', false)\n\n return {\n context,\n start: async () => {\n const client = new Client({\n name: options.name,\n description: options.description,\n version: options.version\n })\n const transport = new StreamableHTTPClientTransport(url)\n await client.connect(transport)\n const { tools } = await client.listTools()\n for (const tool of tools) {\n const name = kebabCase(tool.name)\n const command = program.command(name)\n if (tool.description) { command.description(tool.description) }\n const schema = z.fromJSONSchema(tool.inputSchema as JSONSchema.JSONSchema)\n if (!(schema instanceof z.ZodObject)) { throw new Error('Invalid schema') }\n const shape = schema.shape\n const keys = Object.keys(shape)\n for (const key of keys) {\n const [type, { defaultValue }] = unwrap(shape[key])\n const description = type.description\n if (type instanceof z.ZodBoolean) {\n command.option(`--${kebabCase(key)}`, description, defaultValue)\n command.option(`--no-${kebabCase(key)}`)\n } else if (type instanceof z.ZodNumber) {\n command.option(`--${kebabCase(key)} <number>`, description, defaultValue)\n } else if (type instanceof z.ZodString || type instanceof z.ZodEnum) {\n command.option(`--${kebabCase(key)} <string>`, description, defaultValue)\n } else if (type instanceof z.ZodObject || type instanceof z.ZodRecord || type instanceof z.ZodArray) {\n command.option(`--${kebabCase(key)} <json>`, description ?? '', JSON.parse, defaultValue)\n } else {\n throw new Error(`Invalid zod type: ${type.def.type}`)\n }\n }\n command.action(async (args) => {\n const { silent } = program.opts<{ silent: boolean }>()\n const logger = createCLILogger()\n if (!silent) {\n intro(`${options.name} - ${tool.name}`)\n client.setNotificationHandler(LoggingMessageNotificationSchema, ({ params: { level, data } }) => {\n logger[level](data)\n })\n client.setNotificationHandler(ProgressNotificationSchema, ({ params: { progress, total, message } }) => {\n logger.info({ progress, total, message })\n })\n }\n const input = await schema.parseAsync(args)\n const response = await client.callTool({\n name: tool.name,\n arguments: input,\n _meta: { progressToken: randomUUID() }\n })\n const result = parseToolResponse(response as ToolResponse)\n process.stdout.write(JSON.stringify(result, null, 2))\n })\n }\n await program.parseAsync()\n await transport.close()\n },\n stop: async () => { }\n }\n }\n}\n","import { Action, AdapterFactory, SideloadResource, toolResponse } from '@mcphero/core'\nimport { createLogger } from '@mcphero/logger'\nimport { InMemoryEventStore } from '@modelcontextprotocol/sdk/examples/shared/inMemoryEventStore.js'\nimport { createMcpExpressApp, CreateMcpExpressAppOptions } from '@modelcontextprotocol/sdk/server/express.js'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'\nimport { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js'\nimport { capitalCase, pascalCase } from 'change-case'\nimport cors from 'cors'\nimport { randomUUID } from 'crypto'\nimport { Request, Response } from 'express'\nimport { readFile } from 'fs/promises'\nimport { Server } from 'http'\n\nexport interface HttpAdapterOptions extends CreateMcpExpressAppOptions {\n host: string\n port: number\n}\n\nexport const http: AdapterFactory<HttpAdapterOptions> = ({ host, port, ...mcpOptions }) => {\n return (options, baseContext) => {\n const context = baseContext.fork({ adapter: 'http' })\n const app = createMcpExpressApp({ ...mcpOptions, host })\n app.use(cors({ exposedHeaders: ['WWW-Authenticate', 'Mcp-Session-Id', 'Last-Event-Id', 'Mcp-Protocol-Version'], origin: '*' }))\n const transports: Record<string, StreamableHTTPServerTransport> = {}\n let mountedActions: Action[] = []\n\n const createServer = () => {\n const server = new McpServer({\n name: options.name,\n description: options.description,\n version: options.version\n }, {\n capabilities: { tools: {}, logging: {} }\n })\n for (const action of mountedActions) {\n server.registerTool(pascalCase(action.name), {\n title: capitalCase(action.name),\n description: action.description,\n inputSchema: action.input\n }, async (input, extra) => {\n const logger = createLogger({\n stream: process.stderr,\n onLog: (level, data) => {\n extra.sendNotification({ method: 'notifications/message', params: { level, data } })\n },\n onProgress: ({ progress, total, message }) => {\n if (!extra._meta?.progressToken) { return }\n extra.sendNotification({\n method: 'notifications/progress',\n params: {\n progress,\n total,\n message,\n progressToken: extra._meta.progressToken\n }\n })\n }\n })\n return action.run(input, context.fork({ logger, extra })).then((result) => {\n return toolResponse(result)\n }).catch((error) => {\n if (error instanceof Error) {\n return toolResponse({ success: false, name: error.name, message: error.message, stack: error.stack })\n } else {\n return toolResponse({ success: false, name: 'Unknown Error', message: 'An unknown error occured', error })\n }\n })\n })\n }\n return server\n }\n\n app.get('/resource/:id', async (req: Request, res: Response) => {\n const id = req.params.id\n if (!id || typeof id !== 'string') { throw new Error('Invalid ID') }\n const resourceMeta: SideloadResource = JSON.parse(await readFile(`resources/${id}.json`, 'utf-8'))\n const buffer = await readFile(`resources/${id}`)\n res.status(200)\n res.header('Content-Type', resourceMeta.contentType)\n res.send(buffer)\n })\n\n app.post('/mcp', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined\n try {\n let transport: StreamableHTTPServerTransport\n if (sessionId && transports[sessionId]) {\n transport = transports[sessionId]\n } else if (!sessionId && isInitializeRequest(req.body)) {\n const eventStore = new InMemoryEventStore()\n transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n enableJsonResponse: false,\n eventStore,\n onsessioninitialized: (sId) => {\n console.log(`Session initialized with ID: ${sId}`)\n transports[sId] = transport\n }\n })\n transport.onerror = (error) => {\n console.error(error)\n }\n transport.onclose = () => {\n const sid = transport.sessionId\n if (sid && transports[sid]) {\n console.log(`Transport closed for session ${sid}, removing from transports map`)\n delete transports[sid]\n }\n }\n await createServer().connect(transport)\n await transport.handleRequest(req, res, req.body)\n return\n } else {\n res.status(400).json({\n jsonrpc: '2.0',\n error: { code: -32_000, message: 'Bad Request: No valid session ID provided' },\n id: null\n })\n return\n }\n\n // Handle the request with existing transport - no need to reconnect\n // The existing transport is already connected to the server\n await transport.handleRequest(req, res, req.body)\n } catch (error) {\n console.error('Error handling MCP request:', error)\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: { code: -32_603, message: 'Internal server error' },\n id: null\n })\n }\n }\n })\n\n app.get('/mcp', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined\n if (!sessionId || !transports[sessionId]) {\n res.status(400).send('Invalid or missing session ID')\n return\n }\n\n // Check for Last-Event-ID header for resumability\n const lastEventId = req.headers['last-event-id'] as string | undefined\n if (lastEventId) {\n console.log(`Client reconnecting with Last-Event-ID: ${lastEventId}`)\n } else {\n console.log(`Establishing new SSE stream for session ${sessionId}`)\n }\n\n const transport = transports[sessionId]\n await transport.handleRequest(req, res)\n })\n\n app.delete('/mcp', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined\n if (!sessionId || !transports[sessionId]) {\n res.status(400).send('Invalid or missing session ID')\n return\n }\n\n console.log(`Received session termination request for session ${sessionId}`)\n\n try {\n const transport = transports[sessionId]\n await transport.handleRequest(req, res)\n } catch (error) {\n console.error('Error handling session termination:', error)\n if (!res.headersSent) {\n res.status(500).send('Error processing session termination')\n }\n }\n })\n\n app.get('/mcp/resource/:id', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined\n if (!sessionId || !transports[sessionId]) {\n res.status(400).send('Invalid or missing session ID')\n return\n }\n\n // Check for Last-Event-ID header for resumability\n const lastEventId = req.headers['last-event-id'] as string | undefined\n if (lastEventId) {\n console.log(`Client reconnecting with Last-Event-ID: ${lastEventId}`)\n } else {\n console.log(`Establishing new SSE stream for session ${sessionId}`)\n }\n\n const transport = transports[sessionId]\n await transport.handleRequest(req, res)\n })\n\n let httpServer: Server | undefined\n return {\n context,\n start: async (actions) => {\n mountedActions = actions\n\n httpServer = app.listen(port, host, (error) => {\n if (error) {\n console.error('Failed to start server:', error)\n process.exit(1)\n }\n console.log(`MCP Streamable HTTP Server listening on http://${host}:${port}/mcp`)\n })\n },\n stop: async () => {\n if (httpServer) {\n await new Promise<void>((resolve, reject) => {\n return httpServer!.close((err) => {\n if (err) {\n reject(err)\n } else {\n resolve()\n }\n })\n })\n }\n httpServer = undefined\n }\n }\n }\n}\n","import { AdapterFactory, toolResponse } from '@mcphero/core'\nimport { createLogger } from '@mcphero/logger'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { capitalCase, pascalCase } from 'change-case'\n\nexport const stdio: AdapterFactory = () => {\n return (options, baseContext) => {\n const context = baseContext.fork({ adapter: 'stdio' })\n const server = new McpServer({\n name: options.name,\n description: options.description,\n version: options.version\n }, {\n capabilities: { tools: {}, logging: {} }\n })\n return {\n context,\n start: async (actions) => {\n for (const action of actions) {\n server.registerTool(pascalCase(action.name), {\n title: capitalCase(action.name),\n description: action.description,\n inputSchema: action.input\n }, async (input, extra) => {\n const logger = createLogger({\n stream: false,\n onLog: (level, data) => {\n extra.sendNotification({ method: 'notifications/message', params: { level, data } })\n },\n onProgress: ({ progress, total, message }) => {\n if (!extra._meta?.progressToken) { return }\n extra.sendNotification({\n method: 'notifications/progress',\n params: {\n progress,\n total,\n message,\n progressToken: extra._meta.progressToken\n }\n })\n }\n })\n return action.run(input, context.fork({ logger, extra })).then((result) => {\n return toolResponse(result)\n }).catch((error) => {\n if (error instanceof Error) {\n return toolResponse({\n success: false,\n name: error.name,\n message: error.message,\n stack: error.stack\n })\n } else {\n return toolResponse({\n success: false,\n name: 'Unknown Error',\n message: 'An unknown error occured',\n error\n })\n }\n })\n })\n }\n const transport = new StdioServerTransport()\n await server.connect(transport)\n },\n stop: async () => {\n await server?.close()\n }\n }\n }\n}\n"],"mappings":"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","names":["randomUUID","toolResponse","createLogger","McpServer","capitalCase","pascalCase"]}
|
|
1
|
+
{"version":3,"sources":["../src/adapter/cliProxy.ts","../src/adapter/http.ts","../src/adapter/stdio.ts"],"sourcesContent":["import { intro } from '@clack/prompts'\nimport { AdapterFactory, parseToolResponse, ToolResponse, unwrap } from '@mcphero/core'\nimport { createCLILogger } from '@mcphero/logger'\nimport { Client } from '@modelcontextprotocol/sdk/client'\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'\nimport { LoggingMessageNotificationSchema, ProgressNotificationSchema } from '@modelcontextprotocol/sdk/types'\nimport { kebabCase } from 'change-case'\nimport { Command } from 'commander'\nimport { randomUUID } from 'crypto'\nimport { z } from 'zod'\nimport { JSONSchema } from 'zod/v4/core'\n\nexport interface CliProxyOptions {\n url: URL\n}\n\nexport const cliProxy: AdapterFactory<CliProxyOptions> = ({ url }) => {\n return (options, baseContext) => {\n const context = baseContext.fork({ adapter: 'cliProxy' })\n const program = new Command()\n .name(options.name)\n .description(options.description)\n .version(options.version)\n .option('-s, --silent', 'Silent mode, prevent log messages', false)\n\n return {\n context,\n start: async () => {\n const client = new Client({\n name: options.name,\n description: options.description,\n version: options.version\n })\n const transport = new StreamableHTTPClientTransport(url)\n await client.connect(transport)\n const { tools } = await client.listTools()\n for (const tool of tools) {\n const name = kebabCase(tool.name)\n const command = program.command(name)\n if (tool.description) { command.description(tool.description) }\n const schema = z.fromJSONSchema(tool.inputSchema as JSONSchema.JSONSchema)\n if (!(schema instanceof z.ZodObject)) { throw new Error('Invalid schema') }\n const shape = schema.shape\n const keys = Object.keys(shape)\n for (const key of keys) {\n const [type, { defaultValue }] = unwrap(shape[key])\n const description = type.description\n if (type instanceof z.ZodBoolean) {\n command.option(`--${kebabCase(key)}`, description, defaultValue)\n command.option(`--no-${kebabCase(key)}`)\n } else if (type instanceof z.ZodNumber) {\n command.option(`--${kebabCase(key)} <number>`, description, defaultValue)\n } else if (type instanceof z.ZodString || type instanceof z.ZodEnum) {\n command.option(`--${kebabCase(key)} <string>`, description, defaultValue)\n } else if (type instanceof z.ZodObject || type instanceof z.ZodRecord || type instanceof z.ZodArray) {\n command.option(`--${kebabCase(key)} <json>`, description ?? '', JSON.parse, defaultValue)\n } else {\n throw new Error(`Invalid zod type: ${type.def.type}`)\n }\n }\n command.action(async (args) => {\n const { silent } = program.opts<{ silent: boolean }>()\n const logger = createCLILogger()\n if (!silent) {\n intro(`${options.name} - ${tool.name}`)\n client.setNotificationHandler(LoggingMessageNotificationSchema, ({ params: { level, data } }) => {\n logger[level](data)\n })\n client.setNotificationHandler(ProgressNotificationSchema, ({ params: { progress, total, message } }) => {\n logger.info({ progress, total, message })\n })\n }\n const input = await schema.parseAsync(args)\n const response = await client.callTool({\n name: tool.name,\n arguments: input,\n _meta: { progressToken: randomUUID() }\n })\n const result = parseToolResponse(response as ToolResponse)\n process.stdout.write(JSON.stringify(result, null, 2))\n })\n }\n await program.parseAsync()\n await transport.close()\n },\n stop: async () => { }\n }\n }\n}\n","import { AuthConfig, AuthInfo, generateProtectedResourceMetadata, OAuthRequest, OAuthResponse, validateToken } from '@mcphero/auth'\nimport { Action, AdapterFactory, MCPHeroContext, MCPHeroOptions, SideloadResource, toolResponse } from '@mcphero/core'\nimport { createLogger } from '@mcphero/logger'\nimport { InMemoryEventStore } from '@modelcontextprotocol/sdk/examples/shared/inMemoryEventStore.js'\nimport { createMcpExpressApp, CreateMcpExpressAppOptions } from '@modelcontextprotocol/sdk/server/express.js'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'\nimport { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js'\nimport { capitalCase, pascalCase } from 'change-case'\nimport cors from 'cors'\nimport { randomUUID } from 'crypto'\nimport express, { Express, Request, Response } from 'express'\nimport { readFile } from 'fs/promises'\nimport { Server } from 'http'\nimport { AsyncLocalStorage } from 'node:async_hooks'\n\nconst authStorage = new AsyncLocalStorage<AuthInfo>()\n\nexport interface HttpAdapterOptions extends CreateMcpExpressAppOptions {\n host: string\n port: number\n auth?: AuthConfig\n}\n\nfunction mountOAuthRoutes(app: Express, auth: AuthConfig): Set<string> {\n const provider = auth.provider!\n const callbackPath = auth.callbackPath ?? '/auth/callback'\n\n const toOAuthReq = (req: Request): OAuthRequest => ({\n method: req.method,\n url: new URL(req.url, `${req.protocol}://${req.get('host')}`),\n headers: Object.fromEntries(Object.entries(req.headers).map(([k, v]) => [k, Array.isArray(v) ? v[0] : v])),\n body: req.body as Record<string, string> | undefined\n })\n\n const sendOAuth = (res: Response, oauthRes: OAuthResponse) => {\n for (const [key, value] of Object.entries(oauthRes.headers)) { res.header(key, value) }\n if (oauthRes.body) {\n res.status(oauthRes.status).send(typeof oauthRes.body === 'string' ? oauthRes.body : JSON.stringify(oauthRes.body))\n } else {\n res.status(oauthRes.status).end()\n }\n }\n\n app.get('/.well-known/oauth-authorization-server', (_req: Request, res: Response) => {\n sendOAuth(res, provider.metadata())\n })\n app.get('/authorize', async (req: Request, res: Response) => {\n sendOAuth(res, await provider.authorize(toOAuthReq(req)))\n })\n app.get(callbackPath, async (req: Request, res: Response) => {\n sendOAuth(res, await provider.callback(toOAuthReq(req)))\n })\n app.post('/token', express.urlencoded({ extended: false }), async (req: Request, res: Response) => {\n sendOAuth(res, await provider.token(toOAuthReq(req)))\n })\n app.post('/register', express.json(), async (req: Request, res: Response) => {\n sendOAuth(res, await provider.register(toOAuthReq(req)))\n })\n\n return new Set(['/.well-known/oauth-authorization-server', '/authorize', callbackPath, '/token', '/register'])\n}\n\nfunction mountAuthMiddleware(app: Express, auth: AuthConfig, oauthPaths: Set<string>) {\n app.use(async (req: Request, res: Response, next: (err?: unknown) => void) => {\n if (req.path.startsWith('/.well-known/') || oauthPaths.has(req.path)) { return next() }\n const result = await validateToken(req.headers.authorization, auth)\n if (result.error) {\n for (const [key, value] of Object.entries(result.error.headers)) {\n res.header(key, value)\n }\n res.status(result.error.statusCode).json(result.error.body)\n return\n }\n if (result.auth) {\n authStorage.run(result.auth, () => { next() })\n } else {\n next()\n }\n })\n}\n\nfunction createMcpServer(options: MCPHeroOptions, actions: Action[], context: MCPHeroContext): McpServer {\n const server = new McpServer({\n name: options.name,\n description: options.description,\n version: options.version\n }, {\n capabilities: { tools: {}, logging: {} }\n })\n\n for (const action of actions) {\n server.registerTool(pascalCase(action.name), {\n title: capitalCase(action.name),\n description: action.description,\n inputSchema: action.input\n }, async (input, extra) => {\n const logger = createLogger({\n stream: process.stderr,\n onLog: (level, data) => {\n extra.sendNotification({ method: 'notifications/message', params: { level, data } })\n },\n onProgress: ({ progress, total, message }) => {\n if (!extra._meta?.progressToken) { return }\n extra.sendNotification({\n method: 'notifications/progress',\n params: {\n progress,\n total,\n message,\n progressToken: extra._meta.progressToken\n }\n })\n }\n })\n const currentAuth = authStorage.getStore()\n return action.run(input, context.fork({ logger, extra, ...(currentAuth ? { auth: currentAuth } : {}) })).then((result) => {\n return toolResponse(result)\n }).catch((error) => {\n if (error instanceof Error) {\n return toolResponse({ success: false, name: error.name, message: error.message, stack: error.stack })\n } else {\n return toolResponse({ success: false, name: 'Unknown Error', message: 'An unknown error occured', error })\n }\n })\n })\n }\n\n return server\n}\n\nfunction mountMcpTransport(\n app: Express,\n transports: Record<string, StreamableHTTPServerTransport>,\n createServer: () => McpServer\n) {\n app.post('/mcp', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined\n try {\n let transport: StreamableHTTPServerTransport\n if (sessionId && transports[sessionId]) {\n transport = transports[sessionId]\n } else if (isInitializeRequest(req.body)) {\n const eventStore = new InMemoryEventStore()\n transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n enableJsonResponse: false,\n eventStore,\n onsessioninitialized: (sId) => {\n console.log(`Session initialized with ID: ${sId}`)\n transports[sId] = transport\n }\n })\n transport.onerror = (error) => {\n console.error(error)\n }\n transport.onclose = () => {\n const sid = transport.sessionId\n if (sid && transports[sid]) {\n console.log(`Transport closed for session ${sid}, removing from transports map`)\n delete transports[sid]\n }\n }\n await createServer().connect(transport)\n await transport.handleRequest(req, res, req.body)\n return\n } else {\n res.status(404).json({\n jsonrpc: '2.0',\n error: { code: -32_000, message: 'Session not found' },\n id: null\n })\n return\n }\n await transport.handleRequest(req, res, req.body)\n } catch (error) {\n console.error('Error handling MCP request:', error)\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: { code: -32_603, message: 'Internal server error' },\n id: null\n })\n }\n }\n })\n\n const handleSessionStream = async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined\n if (!sessionId || !transports[sessionId]) {\n res.status(400).send('Invalid or missing session ID')\n return\n }\n const transport = transports[sessionId]\n await transport.handleRequest(req, res)\n }\n\n app.get('/mcp', handleSessionStream)\n app.delete('/mcp', handleSessionStream)\n app.get('/mcp/resource/:id', handleSessionStream)\n}\n\nexport const http: AdapterFactory<HttpAdapterOptions> = ({ host, port, auth, ...mcpOptions }) => {\n return (options, baseContext) => {\n const context = baseContext.fork({ adapter: 'http' })\n const app = createMcpExpressApp({ ...mcpOptions, host })\n app.use(cors({ exposedHeaders: ['WWW-Authenticate', 'Mcp-Session-Id', 'Last-Event-Id', 'Mcp-Protocol-Version'], origin: '*' }))\n\n if (auth?.authorizationServers?.length && auth.resourceUrl) {\n app.get('/.well-known/oauth-protected-resource', (_req: Request, res: Response) => {\n const metadata = generateProtectedResourceMetadata(auth.resourceUrl!, auth.authorizationServers!)\n res.json(metadata)\n })\n }\n\n const oauthPaths = auth?.provider ? mountOAuthRoutes(app, auth) : new Set<string>()\n\n if (auth) {\n mountAuthMiddleware(app, auth, oauthPaths)\n }\n\n const transports: Record<string, StreamableHTTPServerTransport> = {}\n let mountedActions: Action[] = []\n\n app.get('/resource/:id', async (req: Request, res: Response) => {\n const id = req.params.id\n if (!id || typeof id !== 'string') { throw new Error('Invalid ID') }\n const resourceMeta: SideloadResource = JSON.parse(await readFile(`resources/${id}.json`, 'utf-8'))\n const buffer = await readFile(`resources/${id}`)\n res.status(200)\n res.header('Content-Type', resourceMeta.contentType)\n res.send(buffer)\n })\n\n mountMcpTransport(app, transports, () => createMcpServer(options, mountedActions, context))\n\n let httpServer: Server | undefined\n return {\n context,\n start: async (actions) => {\n mountedActions = actions\n httpServer = app.listen(port, host, (error) => {\n if (error) {\n console.error('Failed to start server:', error)\n process.exit(1)\n }\n console.log(`MCP Streamable HTTP Server listening on http://${host}:${port}/mcp`)\n })\n },\n stop: async () => {\n if (httpServer) {\n await new Promise<void>((resolve, reject) => {\n return httpServer!.close((err) => {\n if (err) {\n reject(err)\n } else {\n resolve()\n }\n })\n })\n }\n httpServer = undefined\n }\n }\n }\n}\n","import { AdapterFactory, toolResponse } from '@mcphero/core'\nimport { createLogger } from '@mcphero/logger'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { capitalCase, pascalCase } from 'change-case'\n\nexport const stdio: AdapterFactory = () => {\n return (options, baseContext) => {\n const context = baseContext.fork({ adapter: 'stdio' })\n const server = new McpServer({\n name: options.name,\n description: options.description,\n version: options.version\n }, {\n capabilities: { tools: {}, logging: {} }\n })\n return {\n context,\n start: async (actions) => {\n for (const action of actions) {\n server.registerTool(pascalCase(action.name), {\n title: capitalCase(action.name),\n description: action.description,\n inputSchema: action.input\n }, async (input, extra) => {\n const logger = createLogger({\n stream: false,\n onLog: (level, data) => {\n extra.sendNotification({ method: 'notifications/message', params: { level, data } })\n },\n onProgress: ({ progress, total, message }) => {\n if (!extra._meta?.progressToken) { return }\n extra.sendNotification({\n method: 'notifications/progress',\n params: {\n progress,\n total,\n message,\n progressToken: extra._meta.progressToken\n }\n })\n }\n })\n return action.run(input, context.fork({ logger, extra })).then((result) => {\n return toolResponse(result)\n }).catch((error) => {\n if (error instanceof Error) {\n return toolResponse({\n success: false,\n name: error.name,\n message: error.message,\n stack: error.stack\n })\n } else {\n return toolResponse({\n success: false,\n name: 'Unknown Error',\n message: 'An unknown error occured',\n error\n })\n }\n })\n })\n }\n const transport = new StdioServerTransport()\n await server.connect(transport)\n },\n stop: async () => {\n await server?.close()\n }\n }\n }\n}\n"],"mappings":"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","names":["randomUUID","toolResponse","createLogger","McpServer","capitalCase","pascalCase"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcphero/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "MCP Hero MCP Package",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -18,8 +18,9 @@
|
|
|
18
18
|
"cors": "^2.8.6",
|
|
19
19
|
"express": "^5.2.1",
|
|
20
20
|
"zod": "^4.3.6",
|
|
21
|
-
"@mcphero/core": "1.
|
|
22
|
-
"@mcphero/
|
|
21
|
+
"@mcphero/core": "1.3.0",
|
|
22
|
+
"@mcphero/auth": "1.3.0",
|
|
23
|
+
"@mcphero/logger": "1.3.0"
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
25
26
|
"@eslint/js": "^10.0.1",
|