@mcphero/mcp 1.1.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/.turbo/turbo-build.log +18 -0
- package/.turbo/turbo-check.log +12 -0
- package/.turbo/turbo-lint.log +5 -0
- package/.turbo/turbo-prepack.log +26 -0
- package/build/index.d.ts +17 -0
- package/build/index.js +371 -0
- package/build/index.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @mcphero/mcp@1.1.6 build /Users/atomic/projects/ai/mcphero/packages/mcp
|
|
4
|
+
> tsup
|
|
5
|
+
|
|
6
|
+
[34mCLI[39m Building entry: src/index.ts
|
|
7
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
8
|
+
[34mCLI[39m tsup v8.5.1
|
|
9
|
+
[34mCLI[39m Using tsup config: /Users/atomic/projects/ai/mcphero/packages/mcp/tsup.config.ts
|
|
10
|
+
[34mCLI[39m Target: es2022
|
|
11
|
+
[34mCLI[39m Cleaning output folder
|
|
12
|
+
[34mESM[39m Build start
|
|
13
|
+
[32mESM[39m [1mbuild/index.js [22m[32m13.98 KB[39m
|
|
14
|
+
[32mESM[39m [1mbuild/index.js.map [22m[32m23.82 KB[39m
|
|
15
|
+
[32mESM[39m ⚡️ Build success in 9ms
|
|
16
|
+
DTS Build start
|
|
17
|
+
DTS ⚡️ Build success in 712ms
|
|
18
|
+
DTS build/index.d.ts 521.00 B
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
> @mcphero/mcp@1.1.6 check /Users/atomic/projects/ai/mcphero/packages/mcp
|
|
3
|
+
> pnpm lint && pnpm typecheck
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
> @mcphero/mcp@1.1.6 lint /Users/atomic/projects/ai/mcphero/packages/mcp
|
|
7
|
+
> eslint
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
> @mcphero/mcp@1.1.6 typecheck /Users/atomic/projects/ai/mcphero/packages/mcp
|
|
11
|
+
> tsc --noEmit
|
|
12
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @mcphero/mcp@1.1.6 prepack /Users/atomic/projects/ai/mcphero/packages/mcp
|
|
4
|
+
> pnpm clean && pnpm build
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
> @mcphero/mcp@1.1.6 clean /Users/atomic/projects/ai/mcphero/packages/mcp
|
|
8
|
+
> rimraf build
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
> @mcphero/mcp@1.1.6 build /Users/atomic/projects/ai/mcphero/packages/mcp
|
|
12
|
+
> tsup
|
|
13
|
+
|
|
14
|
+
[34mCLI[39m Building entry: src/index.ts
|
|
15
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
16
|
+
[34mCLI[39m tsup v8.5.1
|
|
17
|
+
[34mCLI[39m Using tsup config: /Users/atomic/projects/ai/mcphero/packages/mcp/tsup.config.ts
|
|
18
|
+
[34mCLI[39m Target: es2022
|
|
19
|
+
[34mCLI[39m Cleaning output folder
|
|
20
|
+
[34mESM[39m Build start
|
|
21
|
+
[32mESM[39m [1mbuild/index.js [22m[32m13.98 KB[39m
|
|
22
|
+
[32mESM[39m [1mbuild/index.js.map [22m[32m23.82 KB[39m
|
|
23
|
+
[32mESM[39m ⚡️ Build success in 10ms
|
|
24
|
+
DTS Build start
|
|
25
|
+
DTS ⚡️ Build success in 886ms
|
|
26
|
+
DTS build/index.d.ts 521.00 B
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AdapterFactory } from '@mcphero/core';
|
|
2
|
+
import { CreateMcpExpressAppOptions } from '@modelcontextprotocol/sdk/server/express.js';
|
|
3
|
+
|
|
4
|
+
interface CliProxyOptions {
|
|
5
|
+
url: URL;
|
|
6
|
+
}
|
|
7
|
+
declare const cliProxy: AdapterFactory<CliProxyOptions>;
|
|
8
|
+
|
|
9
|
+
interface HttpAdapterOptions extends CreateMcpExpressAppOptions {
|
|
10
|
+
host: string;
|
|
11
|
+
port: number;
|
|
12
|
+
}
|
|
13
|
+
declare const http: AdapterFactory<HttpAdapterOptions>;
|
|
14
|
+
|
|
15
|
+
declare const stdio: AdapterFactory;
|
|
16
|
+
|
|
17
|
+
export { type CliProxyOptions, type HttpAdapterOptions, cliProxy, http, stdio };
|
package/build/index.js
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
// src/adapter/cliProxy.ts
|
|
2
|
+
import { intro } from "@clack/prompts";
|
|
3
|
+
import { parseToolResponse, unwrap } from "@mcphero/core";
|
|
4
|
+
import { createCLILogger } from "@mcphero/logger";
|
|
5
|
+
import { Client } from "@modelcontextprotocol/sdk/client";
|
|
6
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
7
|
+
import { LoggingMessageNotificationSchema, ProgressNotificationSchema } from "@modelcontextprotocol/sdk/types";
|
|
8
|
+
import { kebabCase } from "change-case";
|
|
9
|
+
import { Command } from "commander";
|
|
10
|
+
import { randomUUID } from "crypto";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
var cliProxy = ({ url }) => {
|
|
13
|
+
return (options, baseContext) => {
|
|
14
|
+
const context = baseContext.fork({ adapter: "cliProxy" });
|
|
15
|
+
const program = new Command().name(options.name).description(options.description).version(options.version).option("-s, --silent", "Silent mode, prevent log messages", false);
|
|
16
|
+
return {
|
|
17
|
+
context,
|
|
18
|
+
start: async () => {
|
|
19
|
+
const client = new Client({
|
|
20
|
+
name: options.name,
|
|
21
|
+
description: options.description,
|
|
22
|
+
version: options.version
|
|
23
|
+
});
|
|
24
|
+
const transport = new StreamableHTTPClientTransport(url);
|
|
25
|
+
await client.connect(transport);
|
|
26
|
+
const { tools } = await client.listTools();
|
|
27
|
+
for (const tool of tools) {
|
|
28
|
+
const name = kebabCase(tool.name);
|
|
29
|
+
const command = program.command(name);
|
|
30
|
+
if (tool.description) {
|
|
31
|
+
command.description(tool.description);
|
|
32
|
+
}
|
|
33
|
+
const schema = z.fromJSONSchema(tool.inputSchema);
|
|
34
|
+
if (!(schema instanceof z.ZodObject)) {
|
|
35
|
+
throw new Error("Invalid schema");
|
|
36
|
+
}
|
|
37
|
+
const shape = schema.shape;
|
|
38
|
+
const keys = Object.keys(shape);
|
|
39
|
+
for (const key of keys) {
|
|
40
|
+
const [type, { defaultValue }] = unwrap(shape[key]);
|
|
41
|
+
const description = type.description;
|
|
42
|
+
if (type instanceof z.ZodBoolean) {
|
|
43
|
+
command.option(`--${kebabCase(key)}`, description, defaultValue);
|
|
44
|
+
command.option(`--no-${kebabCase(key)}`);
|
|
45
|
+
} else if (type instanceof z.ZodNumber) {
|
|
46
|
+
command.option(`--${kebabCase(key)} <number>`, description, defaultValue);
|
|
47
|
+
} else if (type instanceof z.ZodString || type instanceof z.ZodEnum) {
|
|
48
|
+
command.option(`--${kebabCase(key)} <string>`, description, defaultValue);
|
|
49
|
+
} else if (type instanceof z.ZodObject || type instanceof z.ZodRecord || type instanceof z.ZodArray) {
|
|
50
|
+
command.option(`--${kebabCase(key)} <json>`, description ?? "", JSON.parse, defaultValue);
|
|
51
|
+
} else {
|
|
52
|
+
throw new Error(`Invalid zod type: ${type.def.type}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
command.action(async (args) => {
|
|
56
|
+
const { silent } = program.opts();
|
|
57
|
+
const logger = createCLILogger();
|
|
58
|
+
if (!silent) {
|
|
59
|
+
intro(`${options.name} - ${tool.name}`);
|
|
60
|
+
client.setNotificationHandler(LoggingMessageNotificationSchema, ({ params: { level, data } }) => {
|
|
61
|
+
logger[level](data);
|
|
62
|
+
});
|
|
63
|
+
client.setNotificationHandler(ProgressNotificationSchema, ({ params: { progress, total, message } }) => {
|
|
64
|
+
logger.info({ progress, total, message });
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
const input = await schema.parseAsync(args);
|
|
68
|
+
const response = await client.callTool({
|
|
69
|
+
name: tool.name,
|
|
70
|
+
arguments: input,
|
|
71
|
+
_meta: { progressToken: randomUUID() }
|
|
72
|
+
});
|
|
73
|
+
const result = parseToolResponse(response);
|
|
74
|
+
process.stdout.write(JSON.stringify(result, null, 2));
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
await program.parseAsync();
|
|
78
|
+
await transport.close();
|
|
79
|
+
},
|
|
80
|
+
stop: async () => {
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// src/adapter/http.ts
|
|
87
|
+
import { toolResponse } from "@mcphero/core";
|
|
88
|
+
import { createLogger } from "@mcphero/logger";
|
|
89
|
+
import { InMemoryEventStore } from "@modelcontextprotocol/sdk/examples/shared/inMemoryEventStore.js";
|
|
90
|
+
import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
|
|
91
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
92
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
93
|
+
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
94
|
+
import { capitalCase, pascalCase } from "change-case";
|
|
95
|
+
import cors from "cors";
|
|
96
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
97
|
+
import { readFile } from "fs/promises";
|
|
98
|
+
var http = ({ host, port, ...mcpOptions }) => {
|
|
99
|
+
return (options, baseContext) => {
|
|
100
|
+
const context = baseContext.fork({ adapter: "http" });
|
|
101
|
+
const app = createMcpExpressApp({ ...mcpOptions, host });
|
|
102
|
+
app.use(cors({ exposedHeaders: ["WWW-Authenticate", "Mcp-Session-Id", "Last-Event-Id", "Mcp-Protocol-Version"], origin: "*" }));
|
|
103
|
+
const transports = {};
|
|
104
|
+
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
|
+
app.get("/resource/:id", async (req, res) => {
|
|
153
|
+
const id = req.params.id;
|
|
154
|
+
if (!id || typeof id !== "string") {
|
|
155
|
+
throw new Error("Invalid ID");
|
|
156
|
+
}
|
|
157
|
+
const resourceMeta = JSON.parse(await readFile(`resources/${id}.json`, "utf-8"));
|
|
158
|
+
const buffer = await readFile(`resources/${id}`);
|
|
159
|
+
res.status(200);
|
|
160
|
+
res.header("Content-Type", resourceMeta.contentType);
|
|
161
|
+
res.send(buffer);
|
|
162
|
+
});
|
|
163
|
+
app.post("/mcp", async (req, res) => {
|
|
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
|
+
});
|
|
260
|
+
let httpServer;
|
|
261
|
+
return {
|
|
262
|
+
context,
|
|
263
|
+
start: async (actions) => {
|
|
264
|
+
mountedActions = actions;
|
|
265
|
+
httpServer = app.listen(port, host, (error) => {
|
|
266
|
+
if (error) {
|
|
267
|
+
console.error("Failed to start server:", error);
|
|
268
|
+
process.exit(1);
|
|
269
|
+
}
|
|
270
|
+
console.log(`MCP Streamable HTTP Server listening on http://${host}:${port}/mcp`);
|
|
271
|
+
});
|
|
272
|
+
},
|
|
273
|
+
stop: async () => {
|
|
274
|
+
if (httpServer) {
|
|
275
|
+
await new Promise((resolve, reject) => {
|
|
276
|
+
return httpServer.close((err) => {
|
|
277
|
+
if (err) {
|
|
278
|
+
reject(err);
|
|
279
|
+
} else {
|
|
280
|
+
resolve();
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
httpServer = void 0;
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
};
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
// src/adapter/stdio.ts
|
|
292
|
+
import { toolResponse as toolResponse2 } from "@mcphero/core";
|
|
293
|
+
import { createLogger as createLogger2 } from "@mcphero/logger";
|
|
294
|
+
import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
295
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
296
|
+
import { capitalCase as capitalCase2, pascalCase as pascalCase2 } from "change-case";
|
|
297
|
+
var stdio = () => {
|
|
298
|
+
return (options, baseContext) => {
|
|
299
|
+
const context = baseContext.fork({ adapter: "stdio" });
|
|
300
|
+
const server = new McpServer2({
|
|
301
|
+
name: options.name,
|
|
302
|
+
description: options.description,
|
|
303
|
+
version: options.version
|
|
304
|
+
}, {
|
|
305
|
+
capabilities: { tools: {}, logging: {} }
|
|
306
|
+
});
|
|
307
|
+
return {
|
|
308
|
+
context,
|
|
309
|
+
start: async (actions) => {
|
|
310
|
+
for (const action of actions) {
|
|
311
|
+
server.registerTool(pascalCase2(action.name), {
|
|
312
|
+
title: capitalCase2(action.name),
|
|
313
|
+
description: action.description,
|
|
314
|
+
inputSchema: action.input
|
|
315
|
+
}, async (input, extra) => {
|
|
316
|
+
const logger = createLogger2({
|
|
317
|
+
stream: false,
|
|
318
|
+
onLog: (level, data) => {
|
|
319
|
+
extra.sendNotification({ method: "notifications/message", params: { level, data } });
|
|
320
|
+
},
|
|
321
|
+
onProgress: ({ progress, total, message }) => {
|
|
322
|
+
if (!extra._meta?.progressToken) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
extra.sendNotification({
|
|
326
|
+
method: "notifications/progress",
|
|
327
|
+
params: {
|
|
328
|
+
progress,
|
|
329
|
+
total,
|
|
330
|
+
message,
|
|
331
|
+
progressToken: extra._meta.progressToken
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
return action.run(input, context.fork({ logger, extra })).then((result) => {
|
|
337
|
+
return toolResponse2(result);
|
|
338
|
+
}).catch((error) => {
|
|
339
|
+
if (error instanceof Error) {
|
|
340
|
+
return toolResponse2({
|
|
341
|
+
success: false,
|
|
342
|
+
name: error.name,
|
|
343
|
+
message: error.message,
|
|
344
|
+
stack: error.stack
|
|
345
|
+
});
|
|
346
|
+
} else {
|
|
347
|
+
return toolResponse2({
|
|
348
|
+
success: false,
|
|
349
|
+
name: "Unknown Error",
|
|
350
|
+
message: "An unknown error occured",
|
|
351
|
+
error
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
const transport = new StdioServerTransport();
|
|
358
|
+
await server.connect(transport);
|
|
359
|
+
},
|
|
360
|
+
stop: async () => {
|
|
361
|
+
await server?.close();
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
};
|
|
365
|
+
};
|
|
366
|
+
export {
|
|
367
|
+
cliProxy,
|
|
368
|
+
http,
|
|
369
|
+
stdio
|
|
370
|
+
};
|
|
371
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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":";AAAA,SAAS,aAAa;AACtB,SAAyB,mBAAiC,cAAc;AACxE,SAAS,uBAAuB;AAChC,SAAS,cAAc;AACvB,SAAS,qCAAqC;AAC9C,SAAS,kCAAkC,kCAAkC;AAC7E,SAAS,iBAAiB;AAC1B,SAAS,eAAe;AACxB,SAAS,kBAAkB;AAC3B,SAAS,SAAS;AAOX,IAAM,WAA4C,CAAC,EAAE,IAAI,MAAM;AACpE,SAAO,CAAC,SAAS,gBAAgB;AAC/B,UAAM,UAAU,YAAY,KAAK,EAAE,SAAS,WAAW,CAAC;AACxD,UAAM,UAAU,IAAI,QAAQ,EACzB,KAAK,QAAQ,IAAI,EACjB,YAAY,QAAQ,WAAW,EAC/B,QAAQ,QAAQ,OAAO,EACvB,OAAO,gBAAgB,qCAAqC,KAAK;AAEpE,WAAO;AAAA,MACL;AAAA,MACA,OAAO,YAAY;AACjB,cAAM,SAAS,IAAI,OAAO;AAAA,UACxB,MAAM,QAAQ;AAAA,UACd,aAAa,QAAQ;AAAA,UACrB,SAAS,QAAQ;AAAA,QACnB,CAAC;AACD,cAAM,YAAY,IAAI,8BAA8B,GAAG;AACvD,cAAM,OAAO,QAAQ,SAAS;AAC9B,cAAM,EAAE,MAAM,IAAI,MAAM,OAAO,UAAU;AACzC,mBAAW,QAAQ,OAAO;AACxB,gBAAM,OAAO,UAAU,KAAK,IAAI;AAChC,gBAAM,UAAU,QAAQ,QAAQ,IAAI;AACpC,cAAI,KAAK,aAAa;AAAE,oBAAQ,YAAY,KAAK,WAAW;AAAA,UAAE;AAC9D,gBAAM,SAAS,EAAE,eAAe,KAAK,WAAoC;AACzE,cAAI,EAAE,kBAAkB,EAAE,YAAY;AAAE,kBAAM,IAAI,MAAM,gBAAgB;AAAA,UAAE;AAC1E,gBAAM,QAAQ,OAAO;AACrB,gBAAM,OAAO,OAAO,KAAK,KAAK;AAC9B,qBAAW,OAAO,MAAM;AACtB,kBAAM,CAAC,MAAM,EAAE,aAAa,CAAC,IAAI,OAAO,MAAM,GAAG,CAAC;AAClD,kBAAM,cAAc,KAAK;AACzB,gBAAI,gBAAgB,EAAE,YAAY;AAChC,sBAAQ,OAAO,KAAK,UAAU,GAAG,CAAC,IAAI,aAAa,YAAY;AAC/D,sBAAQ,OAAO,QAAQ,UAAU,GAAG,CAAC,EAAE;AAAA,YACzC,WAAW,gBAAgB,EAAE,WAAW;AACtC,sBAAQ,OAAO,KAAK,UAAU,GAAG,CAAC,aAAa,aAAa,YAAY;AAAA,YAC1E,WAAW,gBAAgB,EAAE,aAAa,gBAAgB,EAAE,SAAS;AACnE,sBAAQ,OAAO,KAAK,UAAU,GAAG,CAAC,aAAa,aAAa,YAAY;AAAA,YAC1E,WAAW,gBAAgB,EAAE,aAAa,gBAAgB,EAAE,aAAa,gBAAgB,EAAE,UAAU;AACnG,sBAAQ,OAAO,KAAK,UAAU,GAAG,CAAC,WAAW,eAAe,IAAI,KAAK,OAAO,YAAY;AAAA,YAC1F,OAAO;AACL,oBAAM,IAAI,MAAM,qBAAqB,KAAK,IAAI,IAAI,EAAE;AAAA,YACtD;AAAA,UACF;AACA,kBAAQ,OAAO,OAAO,SAAS;AAC7B,kBAAM,EAAE,OAAO,IAAI,QAAQ,KAA0B;AACrD,kBAAM,SAAS,gBAAgB;AAC/B,gBAAI,CAAC,QAAQ;AACX,oBAAM,GAAG,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE;AACtC,qBAAO,uBAAuB,kCAAkC,CAAC,EAAE,QAAQ,EAAE,OAAO,KAAK,EAAE,MAAM;AAC/F,uBAAO,KAAK,EAAE,IAAI;AAAA,cACpB,CAAC;AACD,qBAAO,uBAAuB,4BAA4B,CAAC,EAAE,QAAQ,EAAE,UAAU,OAAO,QAAQ,EAAE,MAAM;AACtG,uBAAO,KAAK,EAAE,UAAU,OAAO,QAAQ,CAAC;AAAA,cAC1C,CAAC;AAAA,YACH;AACA,kBAAM,QAAQ,MAAM,OAAO,WAAW,IAAI;AAC1C,kBAAM,WAAW,MAAM,OAAO,SAAS;AAAA,cACrC,MAAM,KAAK;AAAA,cACX,WAAW;AAAA,cACX,OAAO,EAAE,eAAe,WAAW,EAAE;AAAA,YACvC,CAAC;AACD,kBAAM,SAAS,kBAAkB,QAAwB;AACzD,oBAAQ,OAAO,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,UACtD,CAAC;AAAA,QACH;AACA,cAAM,QAAQ,WAAW;AACzB,cAAM,UAAU,MAAM;AAAA,MACxB;AAAA,MACA,MAAM,YAAY;AAAA,MAAE;AAAA,IACtB;AAAA,EACF;AACF;;;ACxFA,SAAmD,oBAAoB;AACvE,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,2BAAuD;AAChE,SAAS,iBAAiB;AAC1B,SAAS,qCAAqC;AAC9C,SAAS,2BAA2B;AACpC,SAAS,aAAa,kBAAkB;AACxC,OAAO,UAAU;AACjB,SAAS,cAAAA,mBAAkB;AAE3B,SAAS,gBAAgB;AAQlB,IAAM,OAA2C,CAAC,EAAE,MAAM,MAAM,GAAG,WAAW,MAAM;AACzF,SAAO,CAAC,SAAS,gBAAgB;AAC/B,UAAM,UAAU,YAAY,KAAK,EAAE,SAAS,OAAO,CAAC;AACpD,UAAM,MAAM,oBAAoB,EAAE,GAAG,YAAY,KAAK,CAAC;AACvD,QAAI,IAAI,KAAK,EAAE,gBAAgB,CAAC,oBAAoB,kBAAkB,iBAAiB,sBAAsB,GAAG,QAAQ,IAAI,CAAC,CAAC;AAC9H,UAAM,aAA4D,CAAC;AACnE,QAAI,iBAA2B,CAAC;AAEhC,UAAM,eAAe,MAAM;AACzB,YAAM,SAAS,IAAI,UAAU;AAAA,QAC3B,MAAM,QAAQ;AAAA,QACd,aAAa,QAAQ;AAAA,QACrB,SAAS,QAAQ;AAAA,MACnB,GAAG;AAAA,QACD,cAAc,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,EAAE;AAAA,MACzC,CAAC;AACD,iBAAW,UAAU,gBAAgB;AACnC,eAAO,aAAa,WAAW,OAAO,IAAI,GAAG;AAAA,UAC3C,OAAO,YAAY,OAAO,IAAI;AAAA,UAC9B,aAAa,OAAO;AAAA,UACpB,aAAa,OAAO;AAAA,QACtB,GAAG,OAAO,OAAO,UAAU;AACzB,gBAAM,SAAS,aAAa;AAAA,YAC1B,QAAQ,QAAQ;AAAA,YAChB,OAAO,CAAC,OAAO,SAAS;AACtB,oBAAM,iBAAiB,EAAE,QAAQ,yBAAyB,QAAQ,EAAE,OAAO,KAAK,EAAE,CAAC;AAAA,YACrF;AAAA,YACA,YAAY,CAAC,EAAE,UAAU,OAAO,QAAQ,MAAM;AAC5C,kBAAI,CAAC,MAAM,OAAO,eAAe;AAAE;AAAA,cAAO;AAC1C,oBAAM,iBAAiB;AAAA,gBACrB,QAAQ;AAAA,gBACR,QAAQ;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,eAAe,MAAM,MAAM;AAAA,gBAC7B;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF,CAAC;AACD,iBAAO,OAAO,IAAI,OAAO,QAAQ,KAAK,EAAE,QAAQ,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW;AACzE,mBAAO,aAAa,MAAM;AAAA,UAC5B,CAAC,EAAE,MAAM,CAAC,UAAU;AAClB,gBAAI,iBAAiB,OAAO;AAC1B,qBAAO,aAAa,EAAE,SAAS,OAAO,MAAM,MAAM,MAAM,SAAS,MAAM,SAAS,OAAO,MAAM,MAAM,CAAC;AAAA,YACtG,OAAO;AACL,qBAAO,aAAa,EAAE,SAAS,OAAO,MAAM,iBAAiB,SAAS,4BAA4B,MAAM,CAAC;AAAA,YAC3G;AAAA,UACF,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT;AAEA,QAAI,IAAI,iBAAiB,OAAO,KAAc,QAAkB;AAC9D,YAAM,KAAK,IAAI,OAAO;AACtB,UAAI,CAAC,MAAM,OAAO,OAAO,UAAU;AAAE,cAAM,IAAI,MAAM,YAAY;AAAA,MAAE;AACnE,YAAM,eAAiC,KAAK,MAAM,MAAM,SAAS,aAAa,EAAE,SAAS,OAAO,CAAC;AACjG,YAAM,SAAS,MAAM,SAAS,aAAa,EAAE,EAAE;AAC/C,UAAI,OAAO,GAAG;AACd,UAAI,OAAO,gBAAgB,aAAa,WAAW;AACnD,UAAI,KAAK,MAAM;AAAA,IACjB,CAAC;AAED,QAAI,KAAK,QAAQ,OAAO,KAAc,QAAkB;AACtD,YAAM,YAAY,IAAI,QAAQ,gBAAgB;AAC9C,UAAI;AACF,YAAI;AACJ,YAAI,aAAa,WAAW,SAAS,GAAG;AACtC,sBAAY,WAAW,SAAS;AAAA,QAClC,WAAW,CAAC,aAAa,oBAAoB,IAAI,IAAI,GAAG;AACtD,gBAAM,aAAa,IAAI,mBAAmB;AAC1C,sBAAY,IAAI,8BAA8B;AAAA,YAC5C,oBAAoB,MAAMA,YAAW;AAAA,YACrC,oBAAoB;AAAA,YACpB;AAAA,YACA,sBAAsB,CAAC,QAAQ;AAC7B,sBAAQ,IAAI,gCAAgC,GAAG,EAAE;AACjD,yBAAW,GAAG,IAAI;AAAA,YACpB;AAAA,UACF,CAAC;AACD,oBAAU,UAAU,CAAC,UAAU;AAC7B,oBAAQ,MAAM,KAAK;AAAA,UACrB;AACA,oBAAU,UAAU,MAAM;AACxB,kBAAM,MAAM,UAAU;AACtB,gBAAI,OAAO,WAAW,GAAG,GAAG;AAC1B,sBAAQ,IAAI,gCAAgC,GAAG,gCAAgC;AAC/E,qBAAO,WAAW,GAAG;AAAA,YACvB;AAAA,UACF;AACA,gBAAM,aAAa,EAAE,QAAQ,SAAS;AACtC,gBAAM,UAAU,cAAc,KAAK,KAAK,IAAI,IAAI;AAChD;AAAA,QACF,OAAO;AACL,cAAI,OAAO,GAAG,EAAE,KAAK;AAAA,YACnB,SAAS;AAAA,YACT,OAAO,EAAE,MAAM,OAAS,SAAS,4CAA4C;AAAA,YAC7E,IAAI;AAAA,UACN,CAAC;AACD;AAAA,QACF;AAIA,cAAM,UAAU,cAAc,KAAK,KAAK,IAAI,IAAI;AAAA,MAClD,SAAS,OAAO;AACd,gBAAQ,MAAM,+BAA+B,KAAK;AAClD,YAAI,CAAC,IAAI,aAAa;AACpB,cAAI,OAAO,GAAG,EAAE,KAAK;AAAA,YACnB,SAAS;AAAA,YACT,OAAO,EAAE,MAAM,QAAS,SAAS,wBAAwB;AAAA,YACzD,IAAI;AAAA,UACN,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAED,QAAI,IAAI,QAAQ,OAAO,KAAc,QAAkB;AACrD,YAAM,YAAY,IAAI,QAAQ,gBAAgB;AAC9C,UAAI,CAAC,aAAa,CAAC,WAAW,SAAS,GAAG;AACxC,YAAI,OAAO,GAAG,EAAE,KAAK,+BAA+B;AACpD;AAAA,MACF;AAGA,YAAM,cAAc,IAAI,QAAQ,eAAe;AAC/C,UAAI,aAAa;AACf,gBAAQ,IAAI,2CAA2C,WAAW,EAAE;AAAA,MACtE,OAAO;AACL,gBAAQ,IAAI,2CAA2C,SAAS,EAAE;AAAA,MACpE;AAEA,YAAM,YAAY,WAAW,SAAS;AACtC,YAAM,UAAU,cAAc,KAAK,GAAG;AAAA,IACxC,CAAC;AAED,QAAI,OAAO,QAAQ,OAAO,KAAc,QAAkB;AACxD,YAAM,YAAY,IAAI,QAAQ,gBAAgB;AAC9C,UAAI,CAAC,aAAa,CAAC,WAAW,SAAS,GAAG;AACxC,YAAI,OAAO,GAAG,EAAE,KAAK,+BAA+B;AACpD;AAAA,MACF;AAEA,cAAQ,IAAI,oDAAoD,SAAS,EAAE;AAE3E,UAAI;AACF,cAAM,YAAY,WAAW,SAAS;AACtC,cAAM,UAAU,cAAc,KAAK,GAAG;AAAA,MACxC,SAAS,OAAO;AACd,gBAAQ,MAAM,uCAAuC,KAAK;AAC1D,YAAI,CAAC,IAAI,aAAa;AACpB,cAAI,OAAO,GAAG,EAAE,KAAK,sCAAsC;AAAA,QAC7D;AAAA,MACF;AAAA,IACF,CAAC;AAED,QAAI,IAAI,qBAAqB,OAAO,KAAc,QAAkB;AAClE,YAAM,YAAY,IAAI,QAAQ,gBAAgB;AAC9C,UAAI,CAAC,aAAa,CAAC,WAAW,SAAS,GAAG;AACxC,YAAI,OAAO,GAAG,EAAE,KAAK,+BAA+B;AACpD;AAAA,MACF;AAGA,YAAM,cAAc,IAAI,QAAQ,eAAe;AAC/C,UAAI,aAAa;AACf,gBAAQ,IAAI,2CAA2C,WAAW,EAAE;AAAA,MACtE,OAAO;AACL,gBAAQ,IAAI,2CAA2C,SAAS,EAAE;AAAA,MACpE;AAEA,YAAM,YAAY,WAAW,SAAS;AACtC,YAAM,UAAU,cAAc,KAAK,GAAG;AAAA,IACxC,CAAC;AAED,QAAI;AACJ,WAAO;AAAA,MACL;AAAA,MACA,OAAO,OAAO,YAAY;AACxB,yBAAiB;AAEjB,qBAAa,IAAI,OAAO,MAAM,MAAM,CAAC,UAAU;AAC7C,cAAI,OAAO;AACT,oBAAQ,MAAM,2BAA2B,KAAK;AAC9C,oBAAQ,KAAK,CAAC;AAAA,UAChB;AACA,kBAAQ,IAAI,kDAAkD,IAAI,IAAI,IAAI,MAAM;AAAA,QAClF,CAAC;AAAA,MACH;AAAA,MACA,MAAM,YAAY;AAChB,YAAI,YAAY;AACd,gBAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,mBAAO,WAAY,MAAM,CAAC,QAAQ;AAChC,kBAAI,KAAK;AACP,uBAAO,GAAG;AAAA,cACZ,OAAO;AACL,wBAAQ;AAAA,cACV;AAAA,YACF,CAAC;AAAA,UACH,CAAC;AAAA,QACH;AACA,qBAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;;;ACjOA,SAAyB,gBAAAC,qBAAoB;AAC7C,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,aAAAC,kBAAiB;AAC1B,SAAS,4BAA4B;AACrC,SAAS,eAAAC,cAAa,cAAAC,mBAAkB;AAEjC,IAAM,QAAwB,MAAM;AACzC,SAAO,CAAC,SAAS,gBAAgB;AAC/B,UAAM,UAAU,YAAY,KAAK,EAAE,SAAS,QAAQ,CAAC;AACrD,UAAM,SAAS,IAAIF,WAAU;AAAA,MAC3B,MAAM,QAAQ;AAAA,MACd,aAAa,QAAQ;AAAA,MACrB,SAAS,QAAQ;AAAA,IACnB,GAAG;AAAA,MACD,cAAc,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,EAAE;AAAA,IACzC,CAAC;AACD,WAAO;AAAA,MACL;AAAA,MACA,OAAO,OAAO,YAAY;AACxB,mBAAW,UAAU,SAAS;AAC5B,iBAAO,aAAaE,YAAW,OAAO,IAAI,GAAG;AAAA,YAC3C,OAAOD,aAAY,OAAO,IAAI;AAAA,YAC9B,aAAa,OAAO;AAAA,YACpB,aAAa,OAAO;AAAA,UACtB,GAAG,OAAO,OAAO,UAAU;AACzB,kBAAM,SAASF,cAAa;AAAA,cAC1B,QAAQ;AAAA,cACR,OAAO,CAAC,OAAO,SAAS;AACtB,sBAAM,iBAAiB,EAAE,QAAQ,yBAAyB,QAAQ,EAAE,OAAO,KAAK,EAAE,CAAC;AAAA,cACrF;AAAA,cACA,YAAY,CAAC,EAAE,UAAU,OAAO,QAAQ,MAAM;AAC5C,oBAAI,CAAC,MAAM,OAAO,eAAe;AAAE;AAAA,gBAAO;AAC1C,sBAAM,iBAAiB;AAAA,kBACrB,QAAQ;AAAA,kBACR,QAAQ;AAAA,oBACN;AAAA,oBACA;AAAA,oBACA;AAAA,oBACA,eAAe,MAAM,MAAM;AAAA,kBAC7B;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF,CAAC;AACD,mBAAO,OAAO,IAAI,OAAO,QAAQ,KAAK,EAAE,QAAQ,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW;AACzE,qBAAOD,cAAa,MAAM;AAAA,YAC5B,CAAC,EAAE,MAAM,CAAC,UAAU;AAClB,kBAAI,iBAAiB,OAAO;AAC1B,uBAAOA,cAAa;AAAA,kBAClB,SAAS;AAAA,kBACT,MAAM,MAAM;AAAA,kBACZ,SAAS,MAAM;AAAA,kBACf,OAAO,MAAM;AAAA,gBACf,CAAC;AAAA,cACH,OAAO;AACL,uBAAOA,cAAa;AAAA,kBAClB,SAAS;AAAA,kBACT,MAAM;AAAA,kBACN,SAAS;AAAA,kBACT;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF,CAAC;AAAA,UACH,CAAC;AAAA,QACH;AACA,cAAM,YAAY,IAAI,qBAAqB;AAC3C,cAAM,OAAO,QAAQ,SAAS;AAAA,MAChC;AAAA,MACA,MAAM,YAAY;AAChB,cAAM,QAAQ,MAAM;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AACF;","names":["randomUUID","toolResponse","createLogger","McpServer","capitalCase","pascalCase"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mcphero/mcp",
|
|
3
|
+
"version": "1.1.6",
|
|
4
|
+
"description": "MCP Hero MCP Package",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+ssh://git@github.com/atomicbi/mcphero.git",
|
|
8
|
+
"directory": "packages/mcp"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"main": "build/index.js",
|
|
12
|
+
"types": "build/index.d.ts",
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@clack/prompts": "^1.0.1",
|
|
15
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
16
|
+
"change-case": "^5.4.4",
|
|
17
|
+
"commander": "^13.1.0",
|
|
18
|
+
"cors": "^2.8.6",
|
|
19
|
+
"express": "^5.2.1",
|
|
20
|
+
"zod": "^4.3.6",
|
|
21
|
+
"@mcphero/core": "1.1.6",
|
|
22
|
+
"@mcphero/logger": "1.1.6"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@eslint/js": "^10.0.1",
|
|
26
|
+
"@modelcontextprotocol/inspector": "^0.21.1",
|
|
27
|
+
"@stylistic/eslint-plugin": "^5.10.0",
|
|
28
|
+
"@types/cors": "^2.8.19",
|
|
29
|
+
"@types/express": "^5.0.6",
|
|
30
|
+
"@types/node": "^22.0.0",
|
|
31
|
+
"rimraf": "^6.1.3",
|
|
32
|
+
"tsup": "^8.5.1",
|
|
33
|
+
"tsx": "^4.21.0",
|
|
34
|
+
"typescript": "^5.9.3",
|
|
35
|
+
"typescript-eslint": "^8.56.1"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"clean": "rimraf build",
|
|
39
|
+
"build": "tsup",
|
|
40
|
+
"watch": "tsup --watch",
|
|
41
|
+
"typecheck": "tsc --noEmit",
|
|
42
|
+
"lint": "eslint",
|
|
43
|
+
"check": "pnpm lint && pnpm typecheck"
|
|
44
|
+
}
|
|
45
|
+
}
|