@brightbeamai/chap-coordinator-mcp 0.3.4 → 0.3.5

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/dist/index.d.cts CHANGED
@@ -1,8 +1,9 @@
1
+ import { IncomingMessage, ServerResponse } from 'node:http';
1
2
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
3
  import { z } from 'zod';
3
- import { Coordinator, Envelope } from '@brightbeamai/chap-coordinator';
4
+ import { Envelope, Coordinator } from '@brightbeamai/chap-coordinator';
4
5
  export { JsonSchema, SCHEMAS, TOOL_NAMES, coerceToolArgs, methodForTool, schemaFor } from './schemas.cjs';
5
- export { TOOL_ANNOTATIONS, TOOL_DESCRIPTIONS, ToolAnnotations } from './tools.cjs';
6
+ export { AGENT_MCP_TOOLS, TOOL_ANNOTATIONS, TOOL_DESCRIPTIONS, ToolAnnotations } from './tools.cjs';
6
7
 
7
8
  /**
8
9
  * Per-request protocol envelope (MCP 2026-07-28).
@@ -101,10 +102,12 @@ declare function classifyEnvelope(params: unknown): ProtocolEra;
101
102
  * import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
102
103
  *
103
104
  * const coord = new Coordinator({ ... });
104
- * const server = makeChapMcpServer(coord, { name: "chap", version: "0.3.4" });
105
+ * const server = makeChapMcpServer(coord, { name: "chap", version: "0.3.5" });
105
106
  * await server.connect(new StdioServerTransport());
106
107
  *
107
- * Usage (Streamable HTTP): see reference/mcp-server-ts/server.ts.
108
+ * Usage (HTTP): chapMcpHttpHandler(coord, options) answers a Node `http`
109
+ * request on an MCP endpoint, in both protocol eras, and refuses a request
110
+ * under a foreign Host or from a foreign Origin.
108
111
  *
109
112
  * Architecture notes:
110
113
  *
@@ -117,6 +120,11 @@ declare function classifyEnvelope(params: unknown): ProtocolEra;
117
120
  * - Tool naming follows "chap.<method>" so the prefix avoids
118
121
  * collisions with other MCP servers a client might load.
119
122
  *
123
+ * - A server that is one participant's connection, such as an
124
+ * agent's, takes `participant`: every call is made as that member,
125
+ * and a call naming another `from` is refused. AGENT_MCP_TOOLS is
126
+ * the tool set such a connection offers an agent.
127
+ *
120
128
  * - Tool inputs are described by JSON Schemas (not Zod) and are
121
129
  * passed through to the Coordinator without re-validating at the
122
130
  * MCP layer. The Coordinator's own dispatch validates params and
@@ -144,21 +152,32 @@ declare const ServerDiscoverRequestSchema: z.ZodObject<{
144
152
  _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
145
153
  }, z.core.$loose>>;
146
154
  }, z.core.$strip>;
155
+ /**
156
+ * What the server dispatches each call through: a Coordinator, or anything
157
+ * with the same `dispatch`, such as a client that forwards the envelope to a
158
+ * running server. The answer may be returned or promised.
159
+ */
160
+ interface ChapDispatcher {
161
+ dispatch(envelope: Envelope): Envelope | Promise<Envelope>;
162
+ }
147
163
  interface ChapMcpOptions {
148
164
  /** Server name advertised to MCP clients. Default: "chap". */
149
165
  name?: string;
150
- /** Server version. Default: "0.3.4". */
166
+ /** Server version. Default: "0.3.5". */
151
167
  version?: string;
152
168
  /**
153
- * Restrict the CHAP methods this server offers. Default: all 39. A tool the
154
- * filter excludes is left out of the list and refused when called.
169
+ * Restrict the CHAP methods this server offers. Default: all of them. A
170
+ * tool the filter excludes is left out of the list and refused when called.
155
171
  */
156
172
  toolFilter?: (toolName: string) => boolean;
157
173
  /**
158
174
  * Make every call as this participant. `from` is filled in on each call,
159
175
  * and a call that names another `from` is refused. Use it where the server
160
176
  * is one participant's connection, such as an agent's, so the connection
161
- * cannot act in anyone else's name. Default: each call names its own `from`.
177
+ * cannot act in anyone else's name. The tools then list `from` as optional,
178
+ * with this URI in its description. A `human:` URI is refused: a person
179
+ * decides in a desk, never through a connection made for an agent.
180
+ * Default: each call names its own `from`.
162
181
  */
163
182
  participant?: string;
164
183
  /** Optional id generator for the envelopes emitted by tool calls. */
@@ -170,12 +189,67 @@ interface ChapMcpOptions {
170
189
  * CHAP method; pass it to a transport (stdio, Streamable HTTP) to
171
190
  * start serving.
172
191
  */
173
- declare function makeChapMcpServer(coord: Coordinator, options?: ChapMcpOptions): Server;
192
+ declare function makeChapMcpServer(coord: ChapDispatcher, options?: ChapMcpOptions): Server;
174
193
  /**
175
194
  * Lower-level helper: translate a tool call to a CHAP envelope and
176
195
  * back. Useful for tests and for embedding the adapter inside a
177
196
  * larger MCP server that registers its own additional tools.
178
197
  */
179
198
  declare function dispatchToolCall(coord: Coordinator, toolName: string, args: Record<string, unknown>, envelopeId?: string | number): Envelope;
199
+ interface ChapMcpHttpOptions extends ChapMcpOptions {
200
+ /**
201
+ * The largest request body read, when the caller has not read it. Default
202
+ * 1,114,112 bytes: the coordinator's default envelope limit of 1 MiB, and
203
+ * 64 KiB for the MCP request around it.
204
+ */
205
+ maxBodyBytes?: number;
206
+ /**
207
+ * Names the server also answers to, each as a Host header carries it:
208
+ * `mcp.internal:8792`, or a bare name behind a proxy on the default port.
209
+ * Its loopback names on the port it was reached on, 127.0.0.1, localhost
210
+ * and [::1], are always allowed. A request under any other name is refused
211
+ * with 421, so a page that rebinds its own name to the server's address
212
+ * gets nothing.
213
+ */
214
+ allowedHosts?: string[];
215
+ /**
216
+ * Origins a browser page may call from, each as an Origin header carries
217
+ * it, such as `http://localhost:6274`. A page served under one of the
218
+ * server's own names is always allowed, and a client that is not a
219
+ * browser sends no Origin. A request from any other origin is refused with
220
+ * 403. The handler sends no CORS headers: a page on another origin needs
221
+ * them from the server the handler is mounted in, as Express's cors
222
+ * middleware sends them.
223
+ */
224
+ allowedOrigins?: string[];
225
+ /**
226
+ * How long a request waits for the server's answer, in milliseconds. One
227
+ * with no answer by then is answered with an internal error, -32603: with
228
+ * HTTP 500, or on the event stream where a handshake-era answer has begun.
229
+ * Default 45,000.
230
+ */
231
+ timeoutMs?: number;
232
+ }
233
+ /** Answers one HTTP request on the MCP endpoint. Pass `parsedBody` when the server has read and parsed the body already. */
234
+ type ChapMcpHttpHandler = (req: IncomingMessage, res: ServerResponse, parsedBody?: unknown) => Promise<void>;
235
+ /**
236
+ * Serve MCP over HTTP: a handler for a Node `http` request and response,
237
+ * for an endpoint such as `/mcp`, with the version handling of the stdio
238
+ * server. A request with no MCP-Protocol-Version header, or a handshake-era
239
+ * one, is answered by the SDK's Streamable HTTP transport, statelessly; a
240
+ * 2026-07-28 request is answered as that revision's single exchange, one
241
+ * JSON-RPC request and one JSON answer. `options` are those of
242
+ * makeChapMcpServer, so `participant` and `toolFilter` hold over HTTP as on
243
+ * stdio.
244
+ *
245
+ * It answers only under the server's own names, refuses a browser request
246
+ * from another origin, and takes POST only; `allowedHosts` and
247
+ * `allowedOrigins` add names and origins. A request with no answer within
248
+ * `timeoutMs` is answered with an internal error.
249
+ *
250
+ * const mcp = chapMcpHttpHandler(coord, { participant: "agent:assistant", toolFilter: (n) => AGENT_MCP_TOOLS.has(n) });
251
+ * createServer((req, res) => (req.url === "/mcp" ? mcp(req, res) : notFound(res)));
252
+ */
253
+ declare function chapMcpHttpHandler(coord: ChapDispatcher, options?: ChapMcpHttpOptions): ChapMcpHttpHandler;
180
254
 
181
- export { type ChapMcpOptions, META_CLIENT_CAPABILITIES, META_CLIENT_INFO, META_PROTOCOL_VERSION, META_SERVER_INFO, MODERN_PROTOCOL_VERSIONS, type ProtocolEra, ProtocolError, SUPPORTED_PROTOCOL_VERSIONS, ServerDiscoverRequestSchema, UNSUPPORTED_PROTOCOL_VERSION, classifyEnvelope, dispatchToolCall, makeChapMcpServer };
255
+ export { type ChapDispatcher, type ChapMcpHttpHandler, type ChapMcpHttpOptions, type ChapMcpOptions, META_CLIENT_CAPABILITIES, META_CLIENT_INFO, META_PROTOCOL_VERSION, META_SERVER_INFO, MODERN_PROTOCOL_VERSIONS, type ProtocolEra, ProtocolError, SUPPORTED_PROTOCOL_VERSIONS, ServerDiscoverRequestSchema, UNSUPPORTED_PROTOCOL_VERSION, chapMcpHttpHandler, classifyEnvelope, dispatchToolCall, makeChapMcpServer };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
+ import { IncomingMessage, ServerResponse } from 'node:http';
1
2
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
3
  import { z } from 'zod';
3
- import { Coordinator, Envelope } from '@brightbeamai/chap-coordinator';
4
+ import { Envelope, Coordinator } from '@brightbeamai/chap-coordinator';
4
5
  export { JsonSchema, SCHEMAS, TOOL_NAMES, coerceToolArgs, methodForTool, schemaFor } from './schemas.js';
5
- export { TOOL_ANNOTATIONS, TOOL_DESCRIPTIONS, ToolAnnotations } from './tools.js';
6
+ export { AGENT_MCP_TOOLS, TOOL_ANNOTATIONS, TOOL_DESCRIPTIONS, ToolAnnotations } from './tools.js';
6
7
 
7
8
  /**
8
9
  * Per-request protocol envelope (MCP 2026-07-28).
@@ -101,10 +102,12 @@ declare function classifyEnvelope(params: unknown): ProtocolEra;
101
102
  * import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
102
103
  *
103
104
  * const coord = new Coordinator({ ... });
104
- * const server = makeChapMcpServer(coord, { name: "chap", version: "0.3.4" });
105
+ * const server = makeChapMcpServer(coord, { name: "chap", version: "0.3.5" });
105
106
  * await server.connect(new StdioServerTransport());
106
107
  *
107
- * Usage (Streamable HTTP): see reference/mcp-server-ts/server.ts.
108
+ * Usage (HTTP): chapMcpHttpHandler(coord, options) answers a Node `http`
109
+ * request on an MCP endpoint, in both protocol eras, and refuses a request
110
+ * under a foreign Host or from a foreign Origin.
108
111
  *
109
112
  * Architecture notes:
110
113
  *
@@ -117,6 +120,11 @@ declare function classifyEnvelope(params: unknown): ProtocolEra;
117
120
  * - Tool naming follows "chap.<method>" so the prefix avoids
118
121
  * collisions with other MCP servers a client might load.
119
122
  *
123
+ * - A server that is one participant's connection, such as an
124
+ * agent's, takes `participant`: every call is made as that member,
125
+ * and a call naming another `from` is refused. AGENT_MCP_TOOLS is
126
+ * the tool set such a connection offers an agent.
127
+ *
120
128
  * - Tool inputs are described by JSON Schemas (not Zod) and are
121
129
  * passed through to the Coordinator without re-validating at the
122
130
  * MCP layer. The Coordinator's own dispatch validates params and
@@ -144,21 +152,32 @@ declare const ServerDiscoverRequestSchema: z.ZodObject<{
144
152
  _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
145
153
  }, z.core.$loose>>;
146
154
  }, z.core.$strip>;
155
+ /**
156
+ * What the server dispatches each call through: a Coordinator, or anything
157
+ * with the same `dispatch`, such as a client that forwards the envelope to a
158
+ * running server. The answer may be returned or promised.
159
+ */
160
+ interface ChapDispatcher {
161
+ dispatch(envelope: Envelope): Envelope | Promise<Envelope>;
162
+ }
147
163
  interface ChapMcpOptions {
148
164
  /** Server name advertised to MCP clients. Default: "chap". */
149
165
  name?: string;
150
- /** Server version. Default: "0.3.4". */
166
+ /** Server version. Default: "0.3.5". */
151
167
  version?: string;
152
168
  /**
153
- * Restrict the CHAP methods this server offers. Default: all 39. A tool the
154
- * filter excludes is left out of the list and refused when called.
169
+ * Restrict the CHAP methods this server offers. Default: all of them. A
170
+ * tool the filter excludes is left out of the list and refused when called.
155
171
  */
156
172
  toolFilter?: (toolName: string) => boolean;
157
173
  /**
158
174
  * Make every call as this participant. `from` is filled in on each call,
159
175
  * and a call that names another `from` is refused. Use it where the server
160
176
  * is one participant's connection, such as an agent's, so the connection
161
- * cannot act in anyone else's name. Default: each call names its own `from`.
177
+ * cannot act in anyone else's name. The tools then list `from` as optional,
178
+ * with this URI in its description. A `human:` URI is refused: a person
179
+ * decides in a desk, never through a connection made for an agent.
180
+ * Default: each call names its own `from`.
162
181
  */
163
182
  participant?: string;
164
183
  /** Optional id generator for the envelopes emitted by tool calls. */
@@ -170,12 +189,67 @@ interface ChapMcpOptions {
170
189
  * CHAP method; pass it to a transport (stdio, Streamable HTTP) to
171
190
  * start serving.
172
191
  */
173
- declare function makeChapMcpServer(coord: Coordinator, options?: ChapMcpOptions): Server;
192
+ declare function makeChapMcpServer(coord: ChapDispatcher, options?: ChapMcpOptions): Server;
174
193
  /**
175
194
  * Lower-level helper: translate a tool call to a CHAP envelope and
176
195
  * back. Useful for tests and for embedding the adapter inside a
177
196
  * larger MCP server that registers its own additional tools.
178
197
  */
179
198
  declare function dispatchToolCall(coord: Coordinator, toolName: string, args: Record<string, unknown>, envelopeId?: string | number): Envelope;
199
+ interface ChapMcpHttpOptions extends ChapMcpOptions {
200
+ /**
201
+ * The largest request body read, when the caller has not read it. Default
202
+ * 1,114,112 bytes: the coordinator's default envelope limit of 1 MiB, and
203
+ * 64 KiB for the MCP request around it.
204
+ */
205
+ maxBodyBytes?: number;
206
+ /**
207
+ * Names the server also answers to, each as a Host header carries it:
208
+ * `mcp.internal:8792`, or a bare name behind a proxy on the default port.
209
+ * Its loopback names on the port it was reached on, 127.0.0.1, localhost
210
+ * and [::1], are always allowed. A request under any other name is refused
211
+ * with 421, so a page that rebinds its own name to the server's address
212
+ * gets nothing.
213
+ */
214
+ allowedHosts?: string[];
215
+ /**
216
+ * Origins a browser page may call from, each as an Origin header carries
217
+ * it, such as `http://localhost:6274`. A page served under one of the
218
+ * server's own names is always allowed, and a client that is not a
219
+ * browser sends no Origin. A request from any other origin is refused with
220
+ * 403. The handler sends no CORS headers: a page on another origin needs
221
+ * them from the server the handler is mounted in, as Express's cors
222
+ * middleware sends them.
223
+ */
224
+ allowedOrigins?: string[];
225
+ /**
226
+ * How long a request waits for the server's answer, in milliseconds. One
227
+ * with no answer by then is answered with an internal error, -32603: with
228
+ * HTTP 500, or on the event stream where a handshake-era answer has begun.
229
+ * Default 45,000.
230
+ */
231
+ timeoutMs?: number;
232
+ }
233
+ /** Answers one HTTP request on the MCP endpoint. Pass `parsedBody` when the server has read and parsed the body already. */
234
+ type ChapMcpHttpHandler = (req: IncomingMessage, res: ServerResponse, parsedBody?: unknown) => Promise<void>;
235
+ /**
236
+ * Serve MCP over HTTP: a handler for a Node `http` request and response,
237
+ * for an endpoint such as `/mcp`, with the version handling of the stdio
238
+ * server. A request with no MCP-Protocol-Version header, or a handshake-era
239
+ * one, is answered by the SDK's Streamable HTTP transport, statelessly; a
240
+ * 2026-07-28 request is answered as that revision's single exchange, one
241
+ * JSON-RPC request and one JSON answer. `options` are those of
242
+ * makeChapMcpServer, so `participant` and `toolFilter` hold over HTTP as on
243
+ * stdio.
244
+ *
245
+ * It answers only under the server's own names, refuses a browser request
246
+ * from another origin, and takes POST only; `allowedHosts` and
247
+ * `allowedOrigins` add names and origins. A request with no answer within
248
+ * `timeoutMs` is answered with an internal error.
249
+ *
250
+ * const mcp = chapMcpHttpHandler(coord, { participant: "agent:assistant", toolFilter: (n) => AGENT_MCP_TOOLS.has(n) });
251
+ * createServer((req, res) => (req.url === "/mcp" ? mcp(req, res) : notFound(res)));
252
+ */
253
+ declare function chapMcpHttpHandler(coord: ChapDispatcher, options?: ChapMcpHttpOptions): ChapMcpHttpHandler;
180
254
 
181
- export { type ChapMcpOptions, META_CLIENT_CAPABILITIES, META_CLIENT_INFO, META_PROTOCOL_VERSION, META_SERVER_INFO, MODERN_PROTOCOL_VERSIONS, type ProtocolEra, ProtocolError, SUPPORTED_PROTOCOL_VERSIONS, ServerDiscoverRequestSchema, UNSUPPORTED_PROTOCOL_VERSION, classifyEnvelope, dispatchToolCall, makeChapMcpServer };
255
+ export { type ChapDispatcher, type ChapMcpHttpHandler, type ChapMcpHttpOptions, type ChapMcpOptions, META_CLIENT_CAPABILITIES, META_CLIENT_INFO, META_PROTOCOL_VERSION, META_SERVER_INFO, MODERN_PROTOCOL_VERSIONS, type ProtocolEra, ProtocolError, SUPPORTED_PROTOCOL_VERSIONS, ServerDiscoverRequestSchema, UNSUPPORTED_PROTOCOL_VERSION, chapMcpHttpHandler, classifyEnvelope, dispatchToolCall, makeChapMcpServer };