@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.
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ /**
3
+ * STDIO Transport
4
+ *
5
+ * Reads newline-delimited JSON from process.stdin, passes each message to the
6
+ * supplied RequestHandler, and writes the JSON-RPC response back to
7
+ * process.stdout followed by a newline.
8
+ *
9
+ * Design decisions:
10
+ * - Each incoming line is handled in its own promise chain (no await in the
11
+ * readline handler) so slow tool calls don't block subsequent requests.
12
+ * - JSON parse errors are returned as -32700 responses instead of crashing.
13
+ * - Unexpected handler exceptions are caught and returned as -32603 so the
14
+ * server never exits due to user input.
15
+ * - process.stdin 'close' triggers a clean process.exit(0) — MCP clients
16
+ * that close stdin expect the server to terminate.
17
+ *
18
+ * Extension note:
19
+ * To add HTTP/SSE transport, implement the same RequestHandler signature
20
+ * and wire it to incoming HTTP requests (e.g. via Express or Fastify).
21
+ * The handler itself, the adapter, and all protocol types stay unchanged.
22
+ *
23
+ * Example HTTP skeleton:
24
+ * app.post('/rpc', async (req, res) => {
25
+ * const response = await handler(req.body as McpRequest);
26
+ * res.json(response);
27
+ * });
28
+ */
29
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
30
+ if (k2 === undefined) k2 = k;
31
+ var desc = Object.getOwnPropertyDescriptor(m, k);
32
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
33
+ desc = { enumerable: true, get: function() { return m[k]; } };
34
+ }
35
+ Object.defineProperty(o, k2, desc);
36
+ }) : (function(o, m, k, k2) {
37
+ if (k2 === undefined) k2 = k;
38
+ o[k2] = m[k];
39
+ }));
40
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
41
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
42
+ }) : function(o, v) {
43
+ o["default"] = v;
44
+ });
45
+ var __importStar = (this && this.__importStar) || (function () {
46
+ var ownKeys = function(o) {
47
+ ownKeys = Object.getOwnPropertyNames || function (o) {
48
+ var ar = [];
49
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
50
+ return ar;
51
+ };
52
+ return ownKeys(o);
53
+ };
54
+ return function (mod) {
55
+ if (mod && mod.__esModule) return mod;
56
+ var result = {};
57
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
58
+ __setModuleDefault(result, mod);
59
+ return result;
60
+ };
61
+ })();
62
+ Object.defineProperty(exports, "__esModule", { value: true });
63
+ exports.createStdioTransport = createStdioTransport;
64
+ const readline = __importStar(require("readline"));
65
+ const errors_1 = require("./errors");
66
+ /**
67
+ * Attach the STDIO transport to the current process.
68
+ *
69
+ * After this call, the process reads from stdin and writes to stdout until
70
+ * stdin is closed. Call this once at server startup.
71
+ */
72
+ function createStdioTransport(handler) {
73
+ const rl = readline.createInterface({
74
+ input: process.stdin,
75
+ // terminal: false disables readline's default SIGINT / line-echoing
76
+ terminal: false,
77
+ });
78
+ rl.on('line', (line) => {
79
+ const trimmed = line.trim();
80
+ if (!trimmed)
81
+ return;
82
+ // Fire-and-forget: concurrent tool calls are handled independently
83
+ void handleLine(trimmed, handler);
84
+ });
85
+ rl.on('close', () => {
86
+ // Client closed stdin — exit cleanly rather than hanging
87
+ process.exit(0);
88
+ });
89
+ }
90
+ // ---------------------------------------------------------------------------
91
+ // Internal helpers
92
+ // ---------------------------------------------------------------------------
93
+ async function handleLine(line, handler) {
94
+ let request;
95
+ try {
96
+ request = JSON.parse(line);
97
+ }
98
+ catch {
99
+ writeResponse((0, errors_1.parseError)(null));
100
+ return;
101
+ }
102
+ const id = request.id ?? null;
103
+ try {
104
+ const response = await handler(request);
105
+ writeResponse(response);
106
+ }
107
+ catch (err) {
108
+ // The handler should never throw, but guard here as a last resort
109
+ writeResponse((0, errors_1.internalError)(id, err));
110
+ }
111
+ }
112
+ function writeResponse(response) {
113
+ process.stdout.write(JSON.stringify(response) + '\n');
114
+ }
115
+ //# sourceMappingURL=stdioTransport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdioTransport.js","sourceRoot":"","sources":["../../src/server/stdioTransport.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcH,oDAmBC;AA/BD,mDAAqC;AAErC,qCAAqD;AAIrD;;;;;GAKG;AACH,SAAgB,oBAAoB,CAAC,OAAuB;IAC1D,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,oEAAoE;QACpE,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,mEAAmE;QACnE,KAAK,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QAClB,yDAAyD;QACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,KAAK,UAAU,UAAU,CAAC,IAAY,EAAE,OAAuB;IAC7D,IAAI,OAAmB,CAAC;IAExB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAe,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,aAAa,CAAC,IAAA,mBAAU,EAAC,IAAI,CAAC,CAAC,CAAC;QAChC,OAAO;IACT,CAAC;IAED,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,IAAI,IAAI,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QACxC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,kEAAkE;QAClE,aAAa,CAAC,IAAA,sBAAa,EAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,QAAwC;IAC7D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * MCP Protocol Types — JSON-RPC 2.0
3
+ *
4
+ * This module defines the minimal set of types needed for the Model Context
5
+ * Protocol over STDIO. The full spec lives at:
6
+ * https://spec.modelcontextprotocol.io/
7
+ *
8
+ * Extension note: When adding HTTP/SSE transport in the future, only the
9
+ * transport layer changes. These types remain unchanged because they describe
10
+ * the protocol messages, not the transport mechanism.
11
+ */
12
+ /** A single JSON Schema property descriptor used in inputSchema */
13
+ export interface JsonSchemaProperty {
14
+ type: string;
15
+ description: string;
16
+ enum?: unknown[];
17
+ }
18
+ /**
19
+ * MCP tool definition — what is advertised to clients on tools/list.
20
+ *
21
+ * Mapping from Hazel:
22
+ * ToolMetadata.name → name
23
+ * ToolMetadata.description → description
24
+ * ToolMetadata.parameters → inputSchema.properties / required
25
+ */
26
+ export interface McpToolDefinition {
27
+ name: string;
28
+ description: string;
29
+ inputSchema: {
30
+ type: 'object';
31
+ properties: Record<string, JsonSchemaProperty>;
32
+ required: string[];
33
+ };
34
+ }
35
+ /** JSON-RPC 2.0 inbound request */
36
+ export interface McpRequest {
37
+ jsonrpc: '2.0';
38
+ id: string | number | null;
39
+ method: string;
40
+ params?: unknown;
41
+ }
42
+ /** JSON-RPC 2.0 successful response */
43
+ export interface McpResponse {
44
+ jsonrpc: '2.0';
45
+ id: string | number | null;
46
+ result: unknown;
47
+ }
48
+ /** JSON-RPC 2.0 error object */
49
+ export interface McpError {
50
+ code: number;
51
+ message: string;
52
+ data?: unknown;
53
+ }
54
+ /** JSON-RPC 2.0 error response */
55
+ export interface McpErrorResponse {
56
+ jsonrpc: '2.0';
57
+ id: string | number | null;
58
+ error: McpError;
59
+ }
60
+ /** Params received with the initialize request */
61
+ export interface InitializeParams {
62
+ protocolVersion: string;
63
+ capabilities?: Record<string, unknown>;
64
+ clientInfo?: {
65
+ name: string;
66
+ version: string;
67
+ };
68
+ }
69
+ /** Params received with tools/call */
70
+ export interface CallToolParams {
71
+ name: string;
72
+ arguments?: Record<string, unknown>;
73
+ }
74
+ /** Server capabilities advertised during the initialize handshake */
75
+ export interface ServerCapabilities {
76
+ tools?: {
77
+ listChanged?: boolean;
78
+ };
79
+ }
80
+ /**
81
+ * Minimal representation of a Hazel tool as seen by the MCP adapter.
82
+ *
83
+ * @hazeljs/agent's ToolMetadata is a structural superset of this interface,
84
+ * so a ToolRegistry instance can be passed as IToolRegistry without any cast.
85
+ *
86
+ * If you use a custom registry (no decorators), implement this interface
87
+ * directly — see examples/stdio-server for a reference implementation.
88
+ */
89
+ export interface HazelTool {
90
+ name: string;
91
+ description: string;
92
+ parameters?: Array<{
93
+ name: string;
94
+ type: string;
95
+ description: string;
96
+ required?: boolean;
97
+ enum?: unknown[];
98
+ }>;
99
+ /** The object whose context the method should be called with */
100
+ target: object;
101
+ /** The callable function — invoked as method.call(target, input) */
102
+ method: Function;
103
+ }
104
+ /**
105
+ * The interface a tool registry must satisfy to work with @hazeljs/mcp.
106
+ *
107
+ * @hazeljs/agent's ToolRegistry satisfies this interface out of the box.
108
+ * You can also roll your own for standalone MCP servers — see the example.
109
+ */
110
+ export interface IToolRegistry {
111
+ getAllTools(): HazelTool[];
112
+ getTool(toolName: string): HazelTool | undefined;
113
+ hasTool(toolName: string): boolean;
114
+ }
115
+ /** Options passed to createMcpServer() */
116
+ export interface McpServerOptions {
117
+ /** Server name advertised to MCP clients during initialize */
118
+ name: string;
119
+ /** Server version advertised to MCP clients during initialize */
120
+ version: string;
121
+ /** Hazel tool registry — @hazeljs/agent ToolRegistry or a custom one */
122
+ toolRegistry: IToolRegistry;
123
+ }
124
+ /** The object returned by createMcpServer() */
125
+ export interface McpServer {
126
+ /** Attach to process.stdin / process.stdout and start serving */
127
+ listenStdio(): void;
128
+ /** Return the current list of MCP tool definitions */
129
+ listTools(): McpToolDefinition[];
130
+ }
131
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ /**
3
+ * MCP Protocol Types — JSON-RPC 2.0
4
+ *
5
+ * This module defines the minimal set of types needed for the Model Context
6
+ * Protocol over STDIO. The full spec lives at:
7
+ * https://spec.modelcontextprotocol.io/
8
+ *
9
+ * Extension note: When adding HTTP/SSE transport in the future, only the
10
+ * transport layer changes. These types remain unchanged because they describe
11
+ * the protocol messages, not the transport mechanism.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hazeljs/mcp",
3
- "version": "0.7.8",
3
+ "version": "0.8.0",
4
4
  "description": "Expose HazelJS tools as MCP (Model Context Protocol) tools over STDIO",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -54,5 +54,5 @@
54
54
  "description": "Required when using @hazeljs/agent ToolRegistry. Not needed for custom IToolRegistry implementations."
55
55
  }
56
56
  },
57
- "gitHead": "906cacdc08d52c4616831b888748f1d1887edb80"
57
+ "gitHead": "e0ed98ca074dd4f7472816d3c32ef576900dcca6"
58
58
  }