@hazeljs/mcp 0.7.8 → 0.8.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/README.md +48 -34
- package/dist/client/mcp-client.d.ts +75 -0
- package/dist/client/mcp-client.d.ts.map +1 -0
- package/dist/client/mcp-client.js +275 -0
- package/dist/client/mcp-client.js.map +1 -0
- package/dist/client/types.d.ts +70 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +9 -0
- package/dist/client/types.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/server/createMcpServer.d.ts +26 -0
- package/dist/server/createMcpServer.d.ts.map +1 -0
- package/dist/server/createMcpServer.js +120 -0
- package/dist/server/createMcpServer.js.map +1 -0
- package/dist/server/errors.d.ts +34 -0
- package/dist/server/errors.d.ts.map +1 -0
- package/dist/server/errors.js +76 -0
- package/dist/server/errors.js.map +1 -0
- package/dist/server/hazelToolAdapter.d.ts +59 -0
- package/dist/server/hazelToolAdapter.d.ts.map +1 -0
- package/dist/server/hazelToolAdapter.js +105 -0
- package/dist/server/hazelToolAdapter.js.map +1 -0
- package/dist/server/stdioTransport.d.ts +37 -0
- package/dist/server/stdioTransport.d.ts.map +1 -0
- package/dist/server/stdioTransport.js +115 -0
- package/dist/server/stdioTransport.js.map +1 -0
- package/dist/server/types.d.ts +131 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +14 -0
- package/dist/server/types.js.map +1 -0
- package/package.json +2 -2
package/dist/index.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @hazeljs/mcp — Public API
|
|
4
|
+
*
|
|
5
|
+
* MCP Server: Expose HazelJS tools as MCP tools over STDIO/HTTP.
|
|
6
|
+
* MCP Client: Connect to external MCP servers and consume their tools.
|
|
7
|
+
*
|
|
8
|
+
* Quickstart (Server):
|
|
9
|
+
* import { createMcpServer } from '@hazeljs/mcp';
|
|
10
|
+
* const server = createMcpServer({ name: 'my-server', version: '1.0.0', toolRegistry });
|
|
11
|
+
* server.listenStdio();
|
|
12
|
+
*
|
|
13
|
+
* Quickstart (Client):
|
|
14
|
+
* import { McpClient } from '@hazeljs/mcp';
|
|
15
|
+
* const client = new McpClient({ name: 'my-app', version: '1.0.0' });
|
|
16
|
+
* await client.connect({ id: 'github', name: 'GitHub', transport: { type: 'stdio', command: 'npx', args: ['-y', '@modelcontextprotocol/server-github'] } });
|
|
17
|
+
* const tools = client.listTools();
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.McpClient = exports.internalError = exports.toolNotFoundError = exports.invalidParamsError = exports.methodNotFoundError = exports.invalidRequestError = exports.parseError = exports.makeErrorResponse = exports.makeError = exports.ErrorCode = exports.HazelToolAdapter = exports.createMcpServer = void 0;
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Server
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Factory function
|
|
25
|
+
var createMcpServer_1 = require("./server/createMcpServer");
|
|
26
|
+
Object.defineProperty(exports, "createMcpServer", { enumerable: true, get: function () { return createMcpServer_1.createMcpServer; } });
|
|
27
|
+
// Adapter — useful for testing or custom transports
|
|
28
|
+
var hazelToolAdapter_1 = require("./server/hazelToolAdapter");
|
|
29
|
+
Object.defineProperty(exports, "HazelToolAdapter", { enumerable: true, get: function () { return hazelToolAdapter_1.HazelToolAdapter; } });
|
|
30
|
+
// Error utilities — useful when building custom transports or middleware
|
|
31
|
+
var errors_1 = require("./server/errors");
|
|
32
|
+
Object.defineProperty(exports, "ErrorCode", { enumerable: true, get: function () { return errors_1.ErrorCode; } });
|
|
33
|
+
Object.defineProperty(exports, "makeError", { enumerable: true, get: function () { return errors_1.makeError; } });
|
|
34
|
+
Object.defineProperty(exports, "makeErrorResponse", { enumerable: true, get: function () { return errors_1.makeErrorResponse; } });
|
|
35
|
+
Object.defineProperty(exports, "parseError", { enumerable: true, get: function () { return errors_1.parseError; } });
|
|
36
|
+
Object.defineProperty(exports, "invalidRequestError", { enumerable: true, get: function () { return errors_1.invalidRequestError; } });
|
|
37
|
+
Object.defineProperty(exports, "methodNotFoundError", { enumerable: true, get: function () { return errors_1.methodNotFoundError; } });
|
|
38
|
+
Object.defineProperty(exports, "invalidParamsError", { enumerable: true, get: function () { return errors_1.invalidParamsError; } });
|
|
39
|
+
Object.defineProperty(exports, "toolNotFoundError", { enumerable: true, get: function () { return errors_1.toolNotFoundError; } });
|
|
40
|
+
Object.defineProperty(exports, "internalError", { enumerable: true, get: function () { return errors_1.internalError; } });
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Client
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
var mcp_client_1 = require("./client/mcp-client");
|
|
45
|
+
Object.defineProperty(exports, "McpClient", { enumerable: true, get: function () { return mcp_client_1.McpClient; } });
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;;;AAEH,8EAA8E;AAC9E,SAAS;AACT,8EAA8E;AAE9E,mBAAmB;AACnB,4DAA2D;AAAlD,kHAAA,eAAe,OAAA;AAExB,oDAAoD;AACpD,8DAA6D;AAApD,oHAAA,gBAAgB,OAAA;AAEzB,yEAAyE;AACzE,0CAUyB;AATvB,mGAAA,SAAS,OAAA;AACT,mGAAA,SAAS,OAAA;AACT,2GAAA,iBAAiB,OAAA;AACjB,oGAAA,UAAU,OAAA;AACV,6GAAA,mBAAmB,OAAA;AACnB,6GAAA,mBAAmB,OAAA;AACnB,4GAAA,kBAAkB,OAAA;AAClB,2GAAA,iBAAiB,OAAA;AACjB,uGAAA,aAAa,OAAA;AAGf,8EAA8E;AAC9E,SAAS;AACT,8EAA8E;AAE9E,kDAAgD;AAAvC,uGAAA,SAAS,OAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createMcpServer
|
|
3
|
+
*
|
|
4
|
+
* The main entry point of @hazeljs/mcp. Wires together:
|
|
5
|
+
* 1. HazelToolAdapter — converts Hazel tools to MCP definitions
|
|
6
|
+
* 2. Request router — dispatches JSON-RPC methods to handlers
|
|
7
|
+
* 3. STDIO transport — reads/writes newline-delimited JSON
|
|
8
|
+
*
|
|
9
|
+
* Supported JSON-RPC methods:
|
|
10
|
+
* initialize — MCP handshake; returns server name, version, capabilities
|
|
11
|
+
* ping — liveness probe; returns empty result
|
|
12
|
+
* tools/list — returns all registered MCP tool definitions
|
|
13
|
+
* tools/call — invokes a named tool with provided arguments
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* const server = createMcpServer({ name, version, toolRegistry });
|
|
17
|
+
* server.listenStdio();
|
|
18
|
+
*
|
|
19
|
+
* Extension note:
|
|
20
|
+
* To expose the same tools over HTTP/SSE, call handleRequest() from an
|
|
21
|
+
* HTTP handler instead of wiring it to createStdioTransport(). The router
|
|
22
|
+
* logic and adapter are reusable across transports.
|
|
23
|
+
*/
|
|
24
|
+
import type { McpServerOptions, McpServer } from './types';
|
|
25
|
+
export declare function createMcpServer(options: McpServerOptions): McpServer;
|
|
26
|
+
//# sourceMappingURL=createMcpServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createMcpServer.d.ts","sourceRoot":"","sources":["../../src/server/createMcpServer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,SAAS,EAMV,MAAM,SAAS,CAAC;AAUjB,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CA+GpE"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* createMcpServer
|
|
4
|
+
*
|
|
5
|
+
* The main entry point of @hazeljs/mcp. Wires together:
|
|
6
|
+
* 1. HazelToolAdapter — converts Hazel tools to MCP definitions
|
|
7
|
+
* 2. Request router — dispatches JSON-RPC methods to handlers
|
|
8
|
+
* 3. STDIO transport — reads/writes newline-delimited JSON
|
|
9
|
+
*
|
|
10
|
+
* Supported JSON-RPC methods:
|
|
11
|
+
* initialize — MCP handshake; returns server name, version, capabilities
|
|
12
|
+
* ping — liveness probe; returns empty result
|
|
13
|
+
* tools/list — returns all registered MCP tool definitions
|
|
14
|
+
* tools/call — invokes a named tool with provided arguments
|
|
15
|
+
*
|
|
16
|
+
* Usage:
|
|
17
|
+
* const server = createMcpServer({ name, version, toolRegistry });
|
|
18
|
+
* server.listenStdio();
|
|
19
|
+
*
|
|
20
|
+
* Extension note:
|
|
21
|
+
* To expose the same tools over HTTP/SSE, call handleRequest() from an
|
|
22
|
+
* HTTP handler instead of wiring it to createStdioTransport(). The router
|
|
23
|
+
* logic and adapter are reusable across transports.
|
|
24
|
+
*/
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.createMcpServer = createMcpServer;
|
|
27
|
+
const hazelToolAdapter_1 = require("./hazelToolAdapter");
|
|
28
|
+
const stdioTransport_1 = require("./stdioTransport");
|
|
29
|
+
const errors_1 = require("./errors");
|
|
30
|
+
function createMcpServer(options) {
|
|
31
|
+
const { name, version, toolRegistry } = options;
|
|
32
|
+
// Snapshot the registry once at startup. Tools registered after this point
|
|
33
|
+
// won't be visible until the server is restarted or the adapter is rebuilt.
|
|
34
|
+
const adapter = hazelToolAdapter_1.HazelToolAdapter.fromRegistry(toolRegistry);
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Request router
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
async function handleRequest(req) {
|
|
39
|
+
const id = req.id ?? null;
|
|
40
|
+
switch (req.method) {
|
|
41
|
+
case 'initialize':
|
|
42
|
+
return handleInitialize(id);
|
|
43
|
+
case 'initialized':
|
|
44
|
+
// Notification — no response required by spec, but we send an ack
|
|
45
|
+
// to avoid clients hanging on a missing reply
|
|
46
|
+
return { jsonrpc: '2.0', id, result: {} };
|
|
47
|
+
case 'ping':
|
|
48
|
+
return { jsonrpc: '2.0', id, result: {} };
|
|
49
|
+
case 'tools/list':
|
|
50
|
+
return handleListTools(id);
|
|
51
|
+
case 'tools/call':
|
|
52
|
+
return handleCallTool(id, req);
|
|
53
|
+
default:
|
|
54
|
+
return (0, errors_1.methodNotFoundError)(id, req.method);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
// Method handlers
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
function handleInitialize(id) {
|
|
61
|
+
return {
|
|
62
|
+
jsonrpc: '2.0',
|
|
63
|
+
id,
|
|
64
|
+
result: {
|
|
65
|
+
protocolVersion: '2024-11-05',
|
|
66
|
+
serverInfo: { name, version },
|
|
67
|
+
capabilities: {
|
|
68
|
+
// Advertise tool support; set listChanged: true if dynamic
|
|
69
|
+
// registration is added in a future version
|
|
70
|
+
tools: {},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function handleListTools(id) {
|
|
76
|
+
return {
|
|
77
|
+
jsonrpc: '2.0',
|
|
78
|
+
id,
|
|
79
|
+
result: {
|
|
80
|
+
tools: adapter.listTools(),
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
async function handleCallTool(id, req) {
|
|
85
|
+
const params = req.params;
|
|
86
|
+
if (!params?.name) {
|
|
87
|
+
return (0, errors_1.invalidParamsError)(id, 'Missing required field: name');
|
|
88
|
+
}
|
|
89
|
+
if (!adapter.hasTool(params.name)) {
|
|
90
|
+
return (0, errors_1.toolNotFoundError)(id, params.name);
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
const result = await adapter.invoke(params.name, params.arguments ?? {});
|
|
94
|
+
return {
|
|
95
|
+
jsonrpc: '2.0',
|
|
96
|
+
id,
|
|
97
|
+
result: {
|
|
98
|
+
// MCP content block format — clients render type: 'text' as plain text
|
|
99
|
+
content: [{ type: 'text', text: JSON.stringify(result) }],
|
|
100
|
+
isError: false,
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
return (0, errors_1.internalError)(id, err);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
// Public API
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
return {
|
|
112
|
+
listenStdio() {
|
|
113
|
+
(0, stdioTransport_1.createStdioTransport)(handleRequest);
|
|
114
|
+
},
|
|
115
|
+
listTools() {
|
|
116
|
+
return adapter.listTools();
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=createMcpServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createMcpServer.js","sourceRoot":"","sources":["../../src/server/createMcpServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON-RPC 2.0 Error Helpers
|
|
3
|
+
*
|
|
4
|
+
* Standard error codes: https://www.jsonrpc.org/specification#error_object
|
|
5
|
+
*
|
|
6
|
+
* MCP application-level codes occupy the -32000 to -32099 server-error range.
|
|
7
|
+
* The server never throws — every error path returns a typed response object
|
|
8
|
+
* so that the transport layer can safely serialize and send it.
|
|
9
|
+
*/
|
|
10
|
+
import type { McpError, McpErrorResponse } from './types';
|
|
11
|
+
export declare const ErrorCode: {
|
|
12
|
+
readonly PARSE_ERROR: -32700;
|
|
13
|
+
readonly INVALID_REQUEST: -32600;
|
|
14
|
+
readonly METHOD_NOT_FOUND: -32601;
|
|
15
|
+
readonly INVALID_PARAMS: -32602;
|
|
16
|
+
readonly INTERNAL_ERROR: -32603;
|
|
17
|
+
readonly TOOL_NOT_FOUND: -32001;
|
|
18
|
+
readonly TOOL_EXECUTION_FAILED: -32002;
|
|
19
|
+
};
|
|
20
|
+
export declare function makeError(code: number, message: string, data?: unknown): McpError;
|
|
21
|
+
export declare function makeErrorResponse(id: string | number | null, code: number, message: string, data?: unknown): McpErrorResponse;
|
|
22
|
+
/** -32700 — Line received from stdin could not be parsed as JSON */
|
|
23
|
+
export declare function parseError(id?: string | number | null): McpErrorResponse;
|
|
24
|
+
/** -32600 — Message is not a valid JSON-RPC 2.0 request */
|
|
25
|
+
export declare function invalidRequestError(id?: string | number | null): McpErrorResponse;
|
|
26
|
+
/** -32601 — No handler registered for the given method */
|
|
27
|
+
export declare function methodNotFoundError(id: string | number | null, method: string): McpErrorResponse;
|
|
28
|
+
/** -32602 — Required parameter missing or malformed */
|
|
29
|
+
export declare function invalidParamsError(id: string | number | null, detail?: string): McpErrorResponse;
|
|
30
|
+
/** -32001 — Requested tool name is not registered in the adapter */
|
|
31
|
+
export declare function toolNotFoundError(id: string | number | null, toolName: string): McpErrorResponse;
|
|
32
|
+
/** -32603 — Unexpected exception inside a handler or tool execution */
|
|
33
|
+
export declare function internalError(id: string | number | null, detail?: unknown): McpErrorResponse;
|
|
34
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/server/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAM1D,eAAO,MAAM,SAAS;;;;;;;;CAWZ,CAAC;AAMX,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAEjF;AAED,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,OAAO,GACb,gBAAgB,CAMlB;AAMD,oEAAoE;AACpE,wBAAgB,UAAU,CAAC,EAAE,GAAE,MAAM,GAAG,MAAM,GAAG,IAAW,GAAG,gBAAgB,CAE9E;AAED,2DAA2D;AAC3D,wBAAgB,mBAAmB,CAAC,EAAE,GAAE,MAAM,GAAG,MAAM,GAAG,IAAW,GAAG,gBAAgB,CAEvF;AAED,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAEhG;AAED,uDAAuD;AACvD,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAMhG;AAED,oEAAoE;AACpE,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAEhG;AAED,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAG5F"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* JSON-RPC 2.0 Error Helpers
|
|
4
|
+
*
|
|
5
|
+
* Standard error codes: https://www.jsonrpc.org/specification#error_object
|
|
6
|
+
*
|
|
7
|
+
* MCP application-level codes occupy the -32000 to -32099 server-error range.
|
|
8
|
+
* The server never throws — every error path returns a typed response object
|
|
9
|
+
* so that the transport layer can safely serialize and send it.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ErrorCode = void 0;
|
|
13
|
+
exports.makeError = makeError;
|
|
14
|
+
exports.makeErrorResponse = makeErrorResponse;
|
|
15
|
+
exports.parseError = parseError;
|
|
16
|
+
exports.invalidRequestError = invalidRequestError;
|
|
17
|
+
exports.methodNotFoundError = methodNotFoundError;
|
|
18
|
+
exports.invalidParamsError = invalidParamsError;
|
|
19
|
+
exports.toolNotFoundError = toolNotFoundError;
|
|
20
|
+
exports.internalError = internalError;
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Error code constants
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
exports.ErrorCode = {
|
|
25
|
+
// Standard JSON-RPC 2.0 codes
|
|
26
|
+
PARSE_ERROR: -32700,
|
|
27
|
+
INVALID_REQUEST: -32600,
|
|
28
|
+
METHOD_NOT_FOUND: -32601,
|
|
29
|
+
INVALID_PARAMS: -32602,
|
|
30
|
+
INTERNAL_ERROR: -32603,
|
|
31
|
+
// MCP / application-level codes
|
|
32
|
+
TOOL_NOT_FOUND: -32001,
|
|
33
|
+
TOOL_EXECUTION_FAILED: -32002,
|
|
34
|
+
};
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Primitive builders
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
function makeError(code, message, data) {
|
|
39
|
+
return { code, message, ...(data !== undefined ? { data } : {}) };
|
|
40
|
+
}
|
|
41
|
+
function makeErrorResponse(id, code, message, data) {
|
|
42
|
+
return {
|
|
43
|
+
jsonrpc: '2.0',
|
|
44
|
+
id,
|
|
45
|
+
error: makeError(code, message, data),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// Named error constructors
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
/** -32700 — Line received from stdin could not be parsed as JSON */
|
|
52
|
+
function parseError(id = null) {
|
|
53
|
+
return makeErrorResponse(id, exports.ErrorCode.PARSE_ERROR, 'Parse error');
|
|
54
|
+
}
|
|
55
|
+
/** -32600 — Message is not a valid JSON-RPC 2.0 request */
|
|
56
|
+
function invalidRequestError(id = null) {
|
|
57
|
+
return makeErrorResponse(id, exports.ErrorCode.INVALID_REQUEST, 'Invalid Request');
|
|
58
|
+
}
|
|
59
|
+
/** -32601 — No handler registered for the given method */
|
|
60
|
+
function methodNotFoundError(id, method) {
|
|
61
|
+
return makeErrorResponse(id, exports.ErrorCode.METHOD_NOT_FOUND, `Method not found: ${method}`);
|
|
62
|
+
}
|
|
63
|
+
/** -32602 — Required parameter missing or malformed */
|
|
64
|
+
function invalidParamsError(id, detail) {
|
|
65
|
+
return makeErrorResponse(id, exports.ErrorCode.INVALID_PARAMS, detail ? `Invalid params: ${detail}` : 'Invalid params');
|
|
66
|
+
}
|
|
67
|
+
/** -32001 — Requested tool name is not registered in the adapter */
|
|
68
|
+
function toolNotFoundError(id, toolName) {
|
|
69
|
+
return makeErrorResponse(id, exports.ErrorCode.TOOL_NOT_FOUND, `Tool not found: ${toolName}`);
|
|
70
|
+
}
|
|
71
|
+
/** -32603 — Unexpected exception inside a handler or tool execution */
|
|
72
|
+
function internalError(id, detail) {
|
|
73
|
+
const data = detail instanceof Error ? { message: detail.message } : detail;
|
|
74
|
+
return makeErrorResponse(id, exports.ErrorCode.INTERNAL_ERROR, 'Internal error', data);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/server/errors.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAyBH,8BAEC;AAED,8CAWC;AAOD,gCAEC;AAGD,kDAEC;AAGD,kDAEC;AAGD,gDAMC;AAGD,8CAEC;AAGD,sCAGC;AA3ED,8EAA8E;AAC9E,uBAAuB;AACvB,8EAA8E;AAEjE,QAAA,SAAS,GAAG;IACvB,8BAA8B;IAC9B,WAAW,EAAE,CAAC,KAAK;IACnB,eAAe,EAAE,CAAC,KAAK;IACvB,gBAAgB,EAAE,CAAC,KAAK;IACxB,cAAc,EAAE,CAAC,KAAK;IACtB,cAAc,EAAE,CAAC,KAAK;IAEtB,gCAAgC;IAChC,cAAc,EAAE,CAAC,KAAK;IACtB,qBAAqB,EAAE,CAAC,KAAK;CACrB,CAAC;AAEX,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E,SAAgB,SAAS,CAAC,IAAY,EAAE,OAAe,EAAE,IAAc;IACrE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACpE,CAAC;AAED,SAAgB,iBAAiB,CAC/B,EAA0B,EAC1B,IAAY,EACZ,OAAe,EACf,IAAc;IAEd,OAAO;QACL,OAAO,EAAE,KAAK;QACd,EAAE;QACF,KAAK,EAAE,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC;KACtC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,2BAA2B;AAC3B,8EAA8E;AAE9E,oEAAoE;AACpE,SAAgB,UAAU,CAAC,KAA6B,IAAI;IAC1D,OAAO,iBAAiB,CAAC,EAAE,EAAE,iBAAS,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;AACrE,CAAC;AAED,2DAA2D;AAC3D,SAAgB,mBAAmB,CAAC,KAA6B,IAAI;IACnE,OAAO,iBAAiB,CAAC,EAAE,EAAE,iBAAS,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;AAC7E,CAAC;AAED,0DAA0D;AAC1D,SAAgB,mBAAmB,CAAC,EAA0B,EAAE,MAAc;IAC5E,OAAO,iBAAiB,CAAC,EAAE,EAAE,iBAAS,CAAC,gBAAgB,EAAE,qBAAqB,MAAM,EAAE,CAAC,CAAC;AAC1F,CAAC;AAED,uDAAuD;AACvD,SAAgB,kBAAkB,CAAC,EAA0B,EAAE,MAAe;IAC5E,OAAO,iBAAiB,CACtB,EAAE,EACF,iBAAS,CAAC,cAAc,EACxB,MAAM,CAAC,CAAC,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC,CAAC,gBAAgB,CACxD,CAAC;AACJ,CAAC;AAED,oEAAoE;AACpE,SAAgB,iBAAiB,CAAC,EAA0B,EAAE,QAAgB;IAC5E,OAAO,iBAAiB,CAAC,EAAE,EAAE,iBAAS,CAAC,cAAc,EAAE,mBAAmB,QAAQ,EAAE,CAAC,CAAC;AACxF,CAAC;AAED,uEAAuE;AACvE,SAAgB,aAAa,CAAC,EAA0B,EAAE,MAAgB;IACxE,MAAM,IAAI,GAAG,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAC5E,OAAO,iBAAiB,CAAC,EAAE,EAAE,iBAAS,CAAC,cAAc,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC;AACjF,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HazelToolAdapter
|
|
3
|
+
*
|
|
4
|
+
* Converts a Hazel tool registry into MCP tool definitions and handles
|
|
5
|
+
* tool invocation on behalf of the MCP server.
|
|
6
|
+
*
|
|
7
|
+
* Hazel → MCP field mapping:
|
|
8
|
+
* ToolMetadata.name → McpToolDefinition.name
|
|
9
|
+
* ToolMetadata.description → McpToolDefinition.description
|
|
10
|
+
* ToolMetadata.parameters → McpToolDefinition.inputSchema (JSON Schema object)
|
|
11
|
+
*
|
|
12
|
+
* Invocation:
|
|
13
|
+
* The adapter calls method.call(target, input) to preserve the `this`
|
|
14
|
+
* context of the original decorated class instance. This means tools
|
|
15
|
+
* registered via @Tool() on an agent class work out of the box.
|
|
16
|
+
*
|
|
17
|
+
* Schema handling:
|
|
18
|
+
* - parameters[] present → converted to JSON Schema (type/description/enum)
|
|
19
|
+
* - parameters absent → empty schema, accepts any JSON object
|
|
20
|
+
*
|
|
21
|
+
* Extension note:
|
|
22
|
+
* To support input validation via Zod, replace the direct method.call with
|
|
23
|
+
* a validation step: parse input with the Zod schema, then call the method.
|
|
24
|
+
* The validation hook below is a placeholder for that upgrade path.
|
|
25
|
+
*
|
|
26
|
+
* The adapter is designed to be transport-agnostic. The same instance can be
|
|
27
|
+
* used by STDIO, HTTP, or SSE transports — only the transport glue changes.
|
|
28
|
+
*/
|
|
29
|
+
import type { IToolRegistry, McpToolDefinition } from './types';
|
|
30
|
+
export declare class HazelToolAdapter {
|
|
31
|
+
private readonly tools;
|
|
32
|
+
private constructor();
|
|
33
|
+
/**
|
|
34
|
+
* Build an adapter from a Hazel tool registry.
|
|
35
|
+
*
|
|
36
|
+
* The registry is snapshotted at construction time. If tools are registered
|
|
37
|
+
* dynamically after server start, call fromRegistry() again and replace the
|
|
38
|
+
* server's adapter (or extend this class to hold a live registry reference).
|
|
39
|
+
*/
|
|
40
|
+
static fromRegistry(registry: IToolRegistry): HazelToolAdapter;
|
|
41
|
+
/** Return all tools as MCP definitions for a tools/list response */
|
|
42
|
+
listTools(): McpToolDefinition[];
|
|
43
|
+
/**
|
|
44
|
+
* Invoke a named tool with the given input object.
|
|
45
|
+
*
|
|
46
|
+
* Throws if the tool is not found — callers should check hasTool() first
|
|
47
|
+
* or catch the error and convert it to a JSON-RPC error response.
|
|
48
|
+
*/
|
|
49
|
+
invoke(toolName: string, input: Record<string, unknown>): Promise<unknown>;
|
|
50
|
+
hasTool(toolName: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Convert a Hazel tool's parameter list into an MCP JSON Schema inputSchema.
|
|
53
|
+
*
|
|
54
|
+
* If parameters is empty or undefined, an open schema is emitted
|
|
55
|
+
* ({ type: 'object', properties: {}, required: [] }) which accepts any input.
|
|
56
|
+
*/
|
|
57
|
+
private toMcpDefinition;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=hazelToolAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hazelToolAdapter.d.ts","sourceRoot":"","sources":["../../src/server/hazelToolAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAa,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE3E,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;IAE3D,OAAO;IAEP;;;;;;OAMG;IACH,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,aAAa,GAAG,gBAAgB;IAU9D,oEAAoE;IACpE,SAAS,IAAI,iBAAiB,EAAE;IAIhC;;;;;OAKG;IACG,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAWhF,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAQlC;;;;;OAKG;IACH,OAAO,CAAC,eAAe;CA0BxB"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* HazelToolAdapter
|
|
4
|
+
*
|
|
5
|
+
* Converts a Hazel tool registry into MCP tool definitions and handles
|
|
6
|
+
* tool invocation on behalf of the MCP server.
|
|
7
|
+
*
|
|
8
|
+
* Hazel → MCP field mapping:
|
|
9
|
+
* ToolMetadata.name → McpToolDefinition.name
|
|
10
|
+
* ToolMetadata.description → McpToolDefinition.description
|
|
11
|
+
* ToolMetadata.parameters → McpToolDefinition.inputSchema (JSON Schema object)
|
|
12
|
+
*
|
|
13
|
+
* Invocation:
|
|
14
|
+
* The adapter calls method.call(target, input) to preserve the `this`
|
|
15
|
+
* context of the original decorated class instance. This means tools
|
|
16
|
+
* registered via @Tool() on an agent class work out of the box.
|
|
17
|
+
*
|
|
18
|
+
* Schema handling:
|
|
19
|
+
* - parameters[] present → converted to JSON Schema (type/description/enum)
|
|
20
|
+
* - parameters absent → empty schema, accepts any JSON object
|
|
21
|
+
*
|
|
22
|
+
* Extension note:
|
|
23
|
+
* To support input validation via Zod, replace the direct method.call with
|
|
24
|
+
* a validation step: parse input with the Zod schema, then call the method.
|
|
25
|
+
* The validation hook below is a placeholder for that upgrade path.
|
|
26
|
+
*
|
|
27
|
+
* The adapter is designed to be transport-agnostic. The same instance can be
|
|
28
|
+
* used by STDIO, HTTP, or SSE transports — only the transport glue changes.
|
|
29
|
+
*/
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.HazelToolAdapter = void 0;
|
|
32
|
+
class HazelToolAdapter {
|
|
33
|
+
constructor() {
|
|
34
|
+
this.tools = new Map();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build an adapter from a Hazel tool registry.
|
|
38
|
+
*
|
|
39
|
+
* The registry is snapshotted at construction time. If tools are registered
|
|
40
|
+
* dynamically after server start, call fromRegistry() again and replace the
|
|
41
|
+
* server's adapter (or extend this class to hold a live registry reference).
|
|
42
|
+
*/
|
|
43
|
+
static fromRegistry(registry) {
|
|
44
|
+
const adapter = new HazelToolAdapter();
|
|
45
|
+
for (const tool of registry.getAllTools()) {
|
|
46
|
+
adapter.tools.set(tool.name, tool);
|
|
47
|
+
}
|
|
48
|
+
return adapter;
|
|
49
|
+
}
|
|
50
|
+
/** Return all tools as MCP definitions for a tools/list response */
|
|
51
|
+
listTools() {
|
|
52
|
+
return Array.from(this.tools.values()).map((tool) => this.toMcpDefinition(tool));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Invoke a named tool with the given input object.
|
|
56
|
+
*
|
|
57
|
+
* Throws if the tool is not found — callers should check hasTool() first
|
|
58
|
+
* or catch the error and convert it to a JSON-RPC error response.
|
|
59
|
+
*/
|
|
60
|
+
async invoke(toolName, input) {
|
|
61
|
+
const tool = this.tools.get(toolName);
|
|
62
|
+
if (!tool) {
|
|
63
|
+
throw new Error(`Tool not found: ${toolName}`);
|
|
64
|
+
}
|
|
65
|
+
// Preserve the original `this` context from the registered class instance
|
|
66
|
+
return tool.method.call(tool.target, input);
|
|
67
|
+
}
|
|
68
|
+
hasTool(toolName) {
|
|
69
|
+
return this.tools.has(toolName);
|
|
70
|
+
}
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// Private helpers
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
/**
|
|
75
|
+
* Convert a Hazel tool's parameter list into an MCP JSON Schema inputSchema.
|
|
76
|
+
*
|
|
77
|
+
* If parameters is empty or undefined, an open schema is emitted
|
|
78
|
+
* ({ type: 'object', properties: {}, required: [] }) which accepts any input.
|
|
79
|
+
*/
|
|
80
|
+
toMcpDefinition(tool) {
|
|
81
|
+
const properties = {};
|
|
82
|
+
const required = [];
|
|
83
|
+
for (const param of tool.parameters ?? []) {
|
|
84
|
+
properties[param.name] = {
|
|
85
|
+
type: param.type,
|
|
86
|
+
description: param.description,
|
|
87
|
+
...(param.enum !== undefined ? { enum: param.enum } : {}),
|
|
88
|
+
};
|
|
89
|
+
if (param.required) {
|
|
90
|
+
required.push(param.name);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
name: tool.name,
|
|
95
|
+
description: tool.description,
|
|
96
|
+
inputSchema: {
|
|
97
|
+
type: 'object',
|
|
98
|
+
properties,
|
|
99
|
+
required,
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
exports.HazelToolAdapter = HazelToolAdapter;
|
|
105
|
+
//# sourceMappingURL=hazelToolAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hazelToolAdapter.js","sourceRoot":"","sources":["../../src/server/hazelToolAdapter.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;;;AAIH,MAAa,gBAAgB;IAG3B;QAFiB,UAAK,GAA2B,IAAI,GAAG,EAAE,CAAC;IAEpC,CAAC;IAExB;;;;;;OAMG;IACH,MAAM,CAAC,YAAY,CAAC,QAAuB;QACzC,MAAM,OAAO,GAAG,IAAI,gBAAgB,EAAE,CAAC;QAEvC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;YAC1C,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACrC,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,oEAAoE;IACpE,SAAS;QACP,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;IACnF,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,KAA8B;QAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAEtC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;QACjD,CAAC;QAED,0EAA0E;QAC1E,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAqB,CAAC;IAClE,CAAC;IAED,OAAO,CAAC,QAAgB;QACtB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IAED,8EAA8E;IAC9E,kBAAkB;IAClB,8EAA8E;IAE9E;;;;;OAKG;IACK,eAAe,CAAC,IAAe;QACrC,MAAM,UAAU,GAAmD,EAAE,CAAC;QACtE,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;YAC1C,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG;gBACvB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC1D,CAAC;YAEF,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACnB,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,UAAU;gBACV,QAAQ;aACT;SACF,CAAC;IACJ,CAAC;CACF;AApFD,4CAoFC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* STDIO Transport
|
|
3
|
+
*
|
|
4
|
+
* Reads newline-delimited JSON from process.stdin, passes each message to the
|
|
5
|
+
* supplied RequestHandler, and writes the JSON-RPC response back to
|
|
6
|
+
* process.stdout followed by a newline.
|
|
7
|
+
*
|
|
8
|
+
* Design decisions:
|
|
9
|
+
* - Each incoming line is handled in its own promise chain (no await in the
|
|
10
|
+
* readline handler) so slow tool calls don't block subsequent requests.
|
|
11
|
+
* - JSON parse errors are returned as -32700 responses instead of crashing.
|
|
12
|
+
* - Unexpected handler exceptions are caught and returned as -32603 so the
|
|
13
|
+
* server never exits due to user input.
|
|
14
|
+
* - process.stdin 'close' triggers a clean process.exit(0) — MCP clients
|
|
15
|
+
* that close stdin expect the server to terminate.
|
|
16
|
+
*
|
|
17
|
+
* Extension note:
|
|
18
|
+
* To add HTTP/SSE transport, implement the same RequestHandler signature
|
|
19
|
+
* and wire it to incoming HTTP requests (e.g. via Express or Fastify).
|
|
20
|
+
* The handler itself, the adapter, and all protocol types stay unchanged.
|
|
21
|
+
*
|
|
22
|
+
* Example HTTP skeleton:
|
|
23
|
+
* app.post('/rpc', async (req, res) => {
|
|
24
|
+
* const response = await handler(req.body as McpRequest);
|
|
25
|
+
* res.json(response);
|
|
26
|
+
* });
|
|
27
|
+
*/
|
|
28
|
+
import type { McpRequest, McpResponse, McpErrorResponse } from './types';
|
|
29
|
+
export type RequestHandler = (req: McpRequest) => Promise<McpResponse | McpErrorResponse>;
|
|
30
|
+
/**
|
|
31
|
+
* Attach the STDIO transport to the current process.
|
|
32
|
+
*
|
|
33
|
+
* After this call, the process reads from stdin and writes to stdout until
|
|
34
|
+
* stdin is closed. Call this once at server startup.
|
|
35
|
+
*/
|
|
36
|
+
export declare function createStdioTransport(handler: RequestHandler): void;
|
|
37
|
+
//# sourceMappingURL=stdioTransport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdioTransport.d.ts","sourceRoot":"","sources":["../../src/server/stdioTransport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAGzE,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,WAAW,GAAG,gBAAgB,CAAC,CAAC;AAE1F;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAmBlE"}
|