@ttoss/http-server-mcp 0.12.4 → 0.12.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,26 +1,687 @@
1
- import * as koa from 'koa';
2
- import { Context } from 'koa';
3
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
- export { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
- import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
6
- import { Router } from '@ttoss/http-server';
7
- export { z } from 'zod';
8
1
 
9
- /**
10
- * Options for a single `apiCall` request.
11
- */
12
- interface ApiCallOptions {
2
+ /// <reference types="node" />
3
+ import { McpServer, McpServer as McpServer$1 } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
5
+ import { Router } from "@ttoss/http-server";
6
+ import accepts from "accepts";
7
+ import { AsyncLocalStorage } from "async_hooks";
8
+ import Cookies from "cookies";
9
+ import { EventEmitter } from "events";
10
+ import { IncomingHttpHeaders, IncomingMessage, OutgoingHttpHeaders, Server, ServerResponse } from "http";
11
+ import { Http2ServerRequest, Http2ServerResponse } from "http2";
12
+ import httpAssert from "http-assert";
13
+ import contentDisposition from "content-disposition";
14
+ import HttpErrors from "http-errors";
15
+ import Keygrip from "keygrip";
16
+ import compose from "koa-compose";
17
+ import { ListenOptions, Socket } from "net";
18
+ import { ParsedUrlQuery } from "querystring";
19
+ import * as url from "url";
20
+ import { z } from "zod";
21
+
22
+ //#region ../../node_modules/.pnpm/@types+koa@3.0.3/node_modules/@types/koa/index.d.ts
23
+ declare interface ContextDelegatedRequest {
24
+ /**
25
+ * Return request header.
26
+ */
27
+ header: IncomingHttpHeaders;
28
+ /**
29
+ * Return request header, alias as request.header
30
+ */
31
+ headers: IncomingHttpHeaders;
32
+ /**
33
+ * Get/Set request URL.
34
+ */
35
+ url: string;
36
+ /**
37
+ * Get origin of URL.
38
+ */
39
+ origin: string;
40
+ /**
41
+ * Get full request URL.
42
+ */
43
+ href: string;
44
+ /**
45
+ * Get/Set request method.
46
+ */
47
+ method: string;
48
+ /**
49
+ * Get request pathname.
50
+ * Set pathname, retaining the query-string when present.
51
+ */
52
+ path: string;
53
+ /**
54
+ * Get parsed query-string.
55
+ * Set query-string as an object.
56
+ */
57
+ query: ParsedUrlQuery;
58
+ /**
59
+ * Get/Set query string.
60
+ */
61
+ querystring: string;
62
+ /**
63
+ * Get the search string. Same as the querystring
64
+ * except it includes the leading ?.
65
+ *
66
+ * Set the search string. Same as
67
+ * response.querystring= but included for ubiquity.
68
+ */
69
+ search: string;
70
+ /**
71
+ * Parse the "Host" header field host
72
+ * and support X-Forwarded-Host when a
73
+ * proxy is enabled.
74
+ */
75
+ host: string;
76
+ /**
77
+ * Parse the "Host" header field hostname
78
+ * and support X-Forwarded-Host when a
79
+ * proxy is enabled.
80
+ */
81
+ hostname: string;
82
+ /**
83
+ * Get WHATWG parsed URL object.
84
+ */
85
+ URL: url.URL;
86
+ /**
87
+ * Check if the request is fresh, aka
88
+ * Last-Modified and/or the ETag
89
+ * still match.
90
+ */
91
+ fresh: boolean;
92
+ /**
93
+ * Check if the request is stale, aka
94
+ * "Last-Modified" and / or the "ETag" for the
95
+ * resource has changed.
96
+ */
97
+ stale: boolean;
98
+ /**
99
+ * Check if the request is idempotent.
100
+ */
101
+ idempotent: boolean;
102
+ /**
103
+ * Return the request socket.
104
+ */
105
+ socket: Socket;
106
+ /**
107
+ * Return the protocol string "http" or "https"
108
+ * when requested with TLS. When the proxy setting
109
+ * is enabled the "X-Forwarded-Proto" header
110
+ * field will be trusted. If you're running behind
111
+ * a reverse proxy that supplies https for you this
112
+ * may be enabled.
113
+ */
114
+ protocol: string;
115
+ /**
116
+ * Short-hand for:
117
+ *
118
+ * this.protocol == 'https'
119
+ */
120
+ secure: boolean;
121
+ /**
122
+ * Request remote address. Supports X-Forwarded-For when app.proxy is true.
123
+ */
124
+ ip: string;
125
+ /**
126
+ * When `app.proxy` is `true`, parse
127
+ * the "X-Forwarded-For" ip address list.
128
+ *
129
+ * For example if the value were "client, proxy1, proxy2"
130
+ * you would receive the array `["client", "proxy1", "proxy2"]`
131
+ * where "proxy2" is the furthest down-stream.
132
+ */
133
+ ips: string[];
134
+ /**
135
+ * Return subdomains as an array.
136
+ *
137
+ * Subdomains are the dot-separated parts of the host before the main domain
138
+ * of the app. By default, the domain of the app is assumed to be the last two
139
+ * parts of the host. This can be changed by setting `app.subdomainOffset`.
140
+ *
141
+ * For example, if the domain is "tobi.ferrets.example.com":
142
+ * If `app.subdomainOffset` is not set, this.subdomains is
143
+ * `["ferrets", "tobi"]`.
144
+ * If `app.subdomainOffset` is 3, this.subdomains is `["tobi"]`.
145
+ */
146
+ subdomains: string[];
147
+ /**
148
+ * Check if the given `type(s)` is acceptable, returning
149
+ * the best match when true, otherwise `false`, in which
150
+ * case you should respond with 406 "Not Acceptable".
151
+ *
152
+ * The `type` value may be a single mime type string
153
+ * such as "application/json", the extension name
154
+ * such as "json" or an array `["json", "html", "text/plain"]`. When a list
155
+ * or array is given the _best_ match, if any is returned.
156
+ *
157
+ * Examples:
158
+ *
159
+ * // Accept: text/html
160
+ * this.accepts('html');
161
+ * // => "html"
162
+ *
163
+ * // Accept: text/*, application/json
164
+ * this.accepts('html');
165
+ * // => "html"
166
+ * this.accepts('text/html');
167
+ * // => "text/html"
168
+ * this.accepts('json', 'text');
169
+ * // => "json"
170
+ * this.accepts('application/json');
171
+ * // => "application/json"
172
+ *
173
+ * // Accept: text/*, application/json
174
+ * this.accepts('image/png');
175
+ * this.accepts('png');
176
+ * // => undefined
177
+ *
178
+ * // Accept: text/*;q=.5, application/json
179
+ * this.accepts(['html', 'json']);
180
+ * this.accepts('html', 'json');
181
+ * // => "json"
182
+ */
183
+ accepts(): string[];
184
+ accepts(...types: string[]): string | false;
185
+ accepts(types: string[]): string | false;
186
+ /**
187
+ * Return accepted encodings or best fit based on `encodings`.
188
+ *
189
+ * Given `Accept-Encoding: gzip, deflate`
190
+ * an array sorted by quality is returned:
191
+ *
192
+ * ['gzip', 'deflate']
193
+ */
194
+ acceptsEncodings(): string[];
195
+ acceptsEncodings(...encodings: string[]): string | false;
196
+ acceptsEncodings(encodings: string[]): string | false;
197
+ /**
198
+ * Return accepted charsets or best fit based on `charsets`.
199
+ *
200
+ * Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
201
+ * an array sorted by quality is returned:
202
+ *
203
+ * ['utf-8', 'utf-7', 'iso-8859-1']
204
+ */
205
+ acceptsCharsets(): string[];
206
+ acceptsCharsets(...charsets: string[]): string | false;
207
+ acceptsCharsets(charsets: string[]): string | false;
208
+ /**
209
+ * Return accepted languages or best fit based on `langs`.
210
+ *
211
+ * Given `Accept-Language: en;q=0.8, es, pt`
212
+ * an array sorted by quality is returned:
213
+ *
214
+ * ['es', 'pt', 'en']
215
+ */
216
+ acceptsLanguages(): string[];
217
+ acceptsLanguages(...langs: string[]): string | false;
218
+ acceptsLanguages(langs: string[]): string | false;
219
+ /**
220
+ * Check if the incoming request contains the "Content-Type"
221
+ * header field, and it contains any of the give mime `type`s.
222
+ * If there is no request body, `null` is returned.
223
+ * If there is no content type, `false` is returned.
224
+ * Otherwise, it returns the first `type` that matches.
225
+ *
226
+ * Examples:
227
+ *
228
+ * // With Content-Type: text/html; charset=utf-8
229
+ * this.is('html'); // => 'html'
230
+ * this.is('text/html'); // => 'text/html'
231
+ * this.is('text/*', 'application/json'); // => 'text/html'
232
+ *
233
+ * // When Content-Type is application/json
234
+ * this.is('json', 'urlencoded'); // => 'json'
235
+ * this.is('application/json'); // => 'application/json'
236
+ * this.is('html', 'application/*'); // => 'application/json'
237
+ *
238
+ * this.is('html'); // => false
239
+ */
240
+ // is(): string | boolean;
241
+ is(...types: string[]): string | false | null;
242
+ is(types: string[]): string | false | null;
243
+ /**
244
+ * Return request header. If the header is not set, will return an empty
245
+ * string.
246
+ *
247
+ * The `Referrer` header field is special-cased, both `Referrer` and
248
+ * `Referer` are interchangeable.
249
+ *
250
+ * Examples:
251
+ *
252
+ * this.get('Content-Type');
253
+ * // => "text/plain"
254
+ *
255
+ * this.get('content-type');
256
+ * // => "text/plain"
257
+ *
258
+ * this.get('Something');
259
+ * // => ''
260
+ */
261
+ get(field: string): string;
262
+ }
263
+ declare interface ContextDelegatedResponse {
264
+ /**
265
+ * Get/Set response status code.
266
+ */
267
+ status: number;
268
+ /**
269
+ * Get response status message
270
+ */
271
+ message: string;
272
+ /**
273
+ * Get/Set response body.
274
+ */
275
+ body: unknown;
276
+ /**
277
+ * Return parsed response Content-Length when present.
278
+ * Set Content-Length field to `n`.
279
+ */
280
+ length: number;
281
+ /**
282
+ * Check if a header has been written to the socket.
283
+ */
284
+ headerSent: boolean;
285
+ /**
286
+ * Vary on `field`.
287
+ */
288
+ vary(field: string | string[]): void;
289
+ /**
290
+ * Perform a special-cased "back" to provide Referrer support.
291
+ * When Referrer is not present, `alt` or "/" is used.
292
+ *
293
+ * Examples:
294
+ *
295
+ * ctx.back()
296
+ * ctx.back('/index.html')
297
+ */
298
+ back(alt?: string): void;
299
+ /**
300
+ * Perform a 302 redirect to `url`.
301
+ *
302
+ * The string "back" is special-cased
303
+ * to provide Referrer support, when Referrer
304
+ * is not present `alt` or "/" is used.
305
+ *
306
+ * Examples:
307
+ *
308
+ * this.redirect('/login');
309
+ * this.redirect('http://google.com');
310
+ */
311
+ redirect(url: string): void;
312
+ /**
313
+ * Set Content-Disposition to "attachment" to signal the client to prompt for download.
314
+ * Optionally specify the filename of the download and some options.
315
+ */
316
+ attachment(filename?: string, options?: contentDisposition.Options): void;
317
+ /**
318
+ * Return the response mime type void of
319
+ * parameters such as "charset".
320
+ *
321
+ * Set Content-Type response header with `type` through `mime.lookup()`
322
+ * when it does not contain a charset.
323
+ *
324
+ * Examples:
325
+ *
326
+ * this.type = '.html';
327
+ * this.type = 'html';
328
+ * this.type = 'json';
329
+ * this.type = 'application/json';
330
+ * this.type = 'png';
331
+ */
332
+ type: string;
333
+ /**
334
+ * Get the Last-Modified date in Date form, if it exists.
335
+ * Set the Last-Modified date using a string or a Date.
336
+ *
337
+ * this.response.lastModified = new Date();
338
+ * this.response.lastModified = '2013-09-13';
339
+ */
340
+ lastModified: Date;
341
+ /**
342
+ * Get/Set the ETag of a response.
343
+ * This will normalize the quotes if necessary.
344
+ *
345
+ * this.response.etag = 'md5hashsum';
346
+ * this.response.etag = '"md5hashsum"';
347
+ * this.response.etag = 'W/"123456789"';
348
+ *
349
+ * @param {String} etag
350
+ * @api public
351
+ */
352
+ etag: string;
353
+ /**
354
+ * Set header `field` to `val`, or pass
355
+ * an object of header fields.
356
+ *
357
+ * Examples:
358
+ *
359
+ * this.set('Foo', ['bar', 'baz']);
360
+ * this.set('Accept', 'application/json');
361
+ * this.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
362
+ */
363
+ set(field: {
364
+ [key: string]: string | string[];
365
+ }): void;
366
+ set(field: string, val: string | string[]): void;
367
+ /**
368
+ * Append additional header `field` with value `val`.
369
+ *
370
+ * Examples:
371
+ *
372
+ * ```
373
+ * this.append('Link', ['<http://localhost/>', '<http://localhost:3000/>']);
374
+ * this.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly');
375
+ * this.append('Warning', '199 Miscellaneous warning');
376
+ * ```
377
+ */
378
+ append(field: string, val: string | string[]): void;
379
+ /**
380
+ * Remove header `field`.
381
+ */
382
+ remove(field: string): void;
383
+ /**
384
+ * Checks if the request is writable.
385
+ * Tests for the existence of the socket
386
+ * as node sometimes does not set it.
387
+ */
388
+ writable: boolean;
389
+ /**
390
+ * Flush any set headers, and begin the body
391
+ */
392
+ flushHeaders(): void;
393
+ }
394
+ declare class Application<StateT = Application.DefaultState, ContextT = Application.DefaultContext> extends EventEmitter {
395
+ proxy: boolean;
396
+ proxyIpHeader: string;
397
+ maxIpsCount: number;
398
+ middleware: Array<Application.Middleware<StateT, ContextT>>;
399
+ subdomainOffset: number;
400
+ env: string;
401
+ context: Application.BaseContext & ContextT;
402
+ request: Application.BaseRequest;
403
+ response: Application.BaseResponse;
404
+ silent: boolean;
405
+ keys: Keygrip | string[];
406
+ ctxStorage: AsyncLocalStorage<ContextT> | undefined;
407
+ /**
408
+ * @param {object} [options] Application options
409
+ * @param {string} [options.env='development'] Environment
410
+ * @param {string[]} [options.keys] Signed cookie keys
411
+ * @param {boolean} [options.proxy] Trust proxy headers
412
+ * @param {number} [options.subdomainOffset] Subdomain offset
413
+ * @param {string} [options.proxyIpHeader] Proxy IP header, defaults to X-Forwarded-For
414
+ * @param {number} [options.maxIpsCount] Max IPs read from proxy IP header, default to 0 (means infinity)
415
+ * @param {boolean|AsyncLocalStorage} [options.asyncLocalStorage] Pass `true` or an instance of `AsyncLocalStorage` to enable async local storage
416
+ */
417
+ constructor(options?: {
418
+ env?: string | undefined;
419
+ keys?: string[] | undefined;
420
+ proxy?: boolean | undefined;
421
+ subdomainOffset?: number | undefined;
422
+ proxyIpHeader?: string | undefined;
423
+ maxIpsCount?: number | undefined;
424
+ asyncLocalStorage?: boolean | AsyncLocalStorage<ContextT> | undefined;
425
+ });
426
+ /**
427
+ * Shorthand for:
428
+ *
429
+ * http.createServer(app.callback()).listen(...)
430
+ */
431
+ listen(port?: number, hostname?: string, backlog?: number, listeningListener?: () => void): Server;
432
+ listen(port: number, hostname?: string, listeningListener?: () => void): Server;
433
+ listen(port: number, backlog?: number, listeningListener?: () => void): Server;
434
+ listen(port: number, listeningListener?: () => void): Server;
435
+ listen(path: string, backlog?: number, listeningListener?: () => void): Server;
436
+ listen(path: string, listeningListener?: () => void): Server;
437
+ listen(options: ListenOptions, listeningListener?: () => void): Server;
438
+ listen(handle: any, backlog?: number, listeningListener?: () => void): Server;
439
+ listen(handle: any, listeningListener?: () => void): Server;
440
+ /**
441
+ * Return JSON representation.
442
+ * We only bother showing settings.
443
+ */
444
+ inspect(): any;
445
+ /**
446
+ * Return JSON representation.
447
+ * We only bother showing settings.
448
+ */
449
+ toJSON(): any;
450
+ /**
451
+ * Use the given middleware `fn`.
452
+ *
453
+ * Old-style middleware will be converted.
454
+ */
455
+ use<NewStateT = {}, NewContextT = {}>(middleware: Application.Middleware<StateT & NewStateT, ContextT & NewContextT>): Application<StateT & NewStateT, ContextT & NewContextT>;
456
+ /**
457
+ * Return a request handler callback
458
+ * for node's native http/http2 server.
459
+ */
460
+ callback(): (req: IncomingMessage | Http2ServerRequest, res: ServerResponse | Http2ServerResponse) => Promise<void>;
461
+ /**
462
+ * Initialize a new context.
463
+ *
464
+ * @api private
465
+ */
466
+ createContext<StateT = Application.DefaultState>(req: IncomingMessage, res: ServerResponse): Application.ParameterizedContext<StateT>;
467
+ /**
468
+ * Default error handler.
469
+ *
470
+ * @api private
471
+ */
472
+ onerror(err: Error): void;
473
+ /**
474
+ * return current context from async local storage
475
+ */
476
+ readonly currentContext: ContextT | undefined;
477
+ }
478
+ declare namespace Application {
479
+ interface DefaultContextDelegatedRequest extends ContextDelegatedRequest {}
480
+ interface DefaultContextDelegatedResponse extends ContextDelegatedResponse {}
481
+ type DefaultStateExtends = any;
482
+ /**
483
+ * This interface can be augmented by users to add types to Koa's default state
484
+ */
485
+ interface DefaultState extends DefaultStateExtends {}
486
+ type DefaultContextExtends = {};
487
+ /**
488
+ * This interface can be augmented by users to add types to Koa's default context
489
+ */
490
+ interface DefaultContext extends DefaultContextExtends {
491
+ /**
492
+ * Custom properties.
493
+ */
494
+ [key: PropertyKey]: any;
495
+ }
496
+ type Middleware<StateT = DefaultState, ContextT = DefaultContext, ResponseBodyT = any> = compose.Middleware<ParameterizedContext<StateT, ContextT, ResponseBodyT>>;
497
+ interface BaseRequest extends DefaultContextDelegatedRequest {
498
+ /**
499
+ * Get the charset when present or undefined.
500
+ */
501
+ charset: string;
502
+ /**
503
+ * Return parsed Content-Length when present.
504
+ */
505
+ length: number;
506
+ /**
507
+ * Return the request mime type void of
508
+ * parameters such as "charset".
509
+ */
510
+ type: string;
511
+ /**
512
+ * Inspect implementation.
513
+ */
514
+ inspect(): any;
515
+ /**
516
+ * Return JSON representation.
517
+ */
518
+ toJSON(): any;
519
+ }
520
+ interface BaseResponse extends DefaultContextDelegatedResponse {
521
+ /**
522
+ * Return the request socket.
523
+ *
524
+ * @return {Connection}
525
+ * @api public
526
+ */
527
+ socket: Socket;
528
+ /**
529
+ * Return response header.
530
+ */
531
+ header: OutgoingHttpHeaders;
532
+ /**
533
+ * Return response header, alias as response.header
534
+ */
535
+ headers: OutgoingHttpHeaders;
536
+ /**
537
+ * Check whether the response is one of the listed types.
538
+ * Pretty much the same as `this.request.is()`.
539
+ *
540
+ * @param {String|Array} types...
541
+ * @return {String|false}
542
+ * @api public
543
+ */
544
+ // is(): string;
545
+ is(...types: string[]): string | false | null;
546
+ is(types: string[]): string | false | null;
547
+ /**
548
+ * Return response header. If the header is not set, will return an empty
549
+ * string.
550
+ *
551
+ * The `Referrer` header field is special-cased, both `Referrer` and
552
+ * `Referer` are interchangeable.
553
+ *
554
+ * Examples:
555
+ *
556
+ * this.get('Content-Type');
557
+ * // => "text/plain"
558
+ *
559
+ * this.get('content-type');
560
+ * // => "text/plain"
561
+ *
562
+ * this.get('Something');
563
+ * // => ''
564
+ */
565
+ get(field: string): string;
566
+ /**
567
+ * Inspect implementation.
568
+ */
569
+ inspect(): any;
13
570
  /**
14
- * JSON-serialisable request body. Automatically serialised and sent with
15
- * `Content-Type: application/json`.
571
+ * Return JSON representation.
16
572
  */
17
- body?: unknown;
573
+ toJSON(): any;
574
+ }
575
+ interface BaseContext extends DefaultContextDelegatedRequest, DefaultContextDelegatedResponse {
18
576
  /**
19
- * Additional or override headers for this specific request.
20
- * These are merged on top of any headers injected from the MCP request
21
- * context via `getApiHeaders`, allowing per-call overrides.
577
+ * util.inspect() implementation, which
578
+ * just returns the JSON output.
22
579
  */
23
- headers?: Record<string, string>;
580
+ inspect(): any;
581
+ /**
582
+ * Return JSON representation.
583
+ *
584
+ * Here we explicitly invoke .toJSON() on each
585
+ * object, as iteration will otherwise fail due
586
+ * to the getters and cause utilities such as
587
+ * clone() to fail.
588
+ */
589
+ toJSON(): any;
590
+ /**
591
+ * Similar to .throw(), adds assertion.
592
+ *
593
+ * this.assert(this.user, 401, 'Please login!');
594
+ *
595
+ * See: https://github.com/jshttp/http-assert
596
+ */
597
+ assert: typeof httpAssert;
598
+ /**
599
+ * Throw an error with `msg` and optional `status`
600
+ * defaulting to 500. Note that these are user-level
601
+ * errors, and the message may be exposed to the client.
602
+ *
603
+ * this.throw(403)
604
+ * this.throw('name required', 400)
605
+ * this.throw(400, 'name required')
606
+ * this.throw('something exploded')
607
+ * this.throw(new Error('invalid'), 400);
608
+ * this.throw(400, new Error('invalid'));
609
+ *
610
+ * See: https://github.com/jshttp/http-errors
611
+ */
612
+ throw(status: number, ...args: HttpErrors.UnknownError[]): never;
613
+ throw(...args: HttpErrors.UnknownError[]): never;
614
+ /**
615
+ * Default error handling.
616
+ */
617
+ onerror(err: Error): void;
618
+ }
619
+ interface Request extends BaseRequest {
620
+ app: Application;
621
+ req: IncomingMessage;
622
+ res: ServerResponse;
623
+ ctx: Context;
624
+ response: Response;
625
+ originalUrl: string;
626
+ ip: string;
627
+ accept: accepts.Accepts;
628
+ }
629
+ interface Response extends BaseResponse {
630
+ app: Application;
631
+ req: IncomingMessage;
632
+ res: ServerResponse;
633
+ ctx: Context;
634
+ request: Request;
635
+ }
636
+ interface ExtendableContext extends BaseContext {
637
+ app: Application;
638
+ request: Request;
639
+ response: Response;
640
+ req: IncomingMessage;
641
+ res: ServerResponse;
642
+ originalUrl: string;
643
+ cookies: Cookies;
644
+ accept: accepts.Accepts;
645
+ /**
646
+ * To bypass Koa's built-in response handling, you may explicitly set `ctx.respond = false;`
647
+ */
648
+ respond?: boolean | undefined;
649
+ }
650
+ type ParameterizedContext<StateT = DefaultState, ContextT = DefaultContext, ResponseBodyT = unknown> = ExtendableContext & {
651
+ state: StateT;
652
+ } & ContextT & {
653
+ body: ResponseBodyT;
654
+ response: {
655
+ body: ResponseBodyT;
656
+ };
657
+ };
658
+ interface Context extends ParameterizedContext {}
659
+ type Next = () => Promise<any>;
660
+ /**
661
+ * A re-export of `HttpError` from the `http-error` package.
662
+ *
663
+ * This is the error type that is thrown by `ctx.assert()` and `ctx.throw()`.
664
+ */
665
+ const HttpError: typeof HttpErrors.HttpError;
666
+ }
667
+ //#endregion
668
+ //#region src/index.d.ts
669
+ type Context$1 = Application.Context;
670
+ /**
671
+ * Options for a single `apiCall` request.
672
+ */
673
+ interface ApiCallOptions {
674
+ /**
675
+ * JSON-serialisable request body. Automatically serialised and sent with
676
+ * `Content-Type: application/json`.
677
+ */
678
+ body?: unknown;
679
+ /**
680
+ * Additional or override headers for this specific request.
681
+ * These are merged on top of any headers injected from the MCP request
682
+ * context via `getApiHeaders`, allowing per-call overrides.
683
+ */
684
+ headers?: Record<string, string>;
24
685
  }
25
686
  /**
26
687
  * Generic HTTP helper for use inside MCP tool handlers.
@@ -80,51 +741,51 @@ declare const apiCall: (method: string, url: string, options?: ApiCallOptions) =
80
741
  * Options for configuring the MCP router
81
742
  */
82
743
  interface McpRouterOptions {
83
- /**
84
- * The HTTP path where the MCP server will be mounted
85
- * @default '/mcp'
86
- */
87
- path?: string;
88
- /**
89
- * Optional session ID generator for stateful MCP servers.
90
- * When provided, a single shared transport is created and sessions are tracked.
91
- * When undefined (default), the server operates in stateless mode where each
92
- * HTTP request uses its own transport instance.
93
- */
94
- sessionIdGenerator?: () => string;
95
- /**
96
- * Base URL prepended to relative paths passed to `apiCall` (paths starting
97
- * with `/`). Tool handlers can then call `apiCall('GET', '/resource')` without
98
- * specifying a host.
99
- *
100
- * @example 'http://localhost:3000/api/v1'
101
- */
102
- apiBaseUrl?: string;
103
- /**
104
- * Called once per incoming MCP HTTP request. Return a plain object whose
105
- * key-value pairs will be merged into the headers of every `apiCall` made
106
- * within that request's tool handlers.
107
- *
108
- * Use this to forward any header from the MCP request — Bearer tokens, API
109
- * keys, tenant IDs, trace headers, etc. — without coupling tool handlers to
110
- * a specific authentication scheme.
111
- *
112
- * @example Forward a Bearer token
113
- * ```typescript
114
- * getApiHeaders: (ctx) => ({ Authorization: ctx.headers.authorization ?? '' })
115
- * ```
116
- *
117
- * @example Forward an x-api-key header
118
- * ```typescript
119
- * getApiHeaders: (ctx) => ({ 'x-api-key': ctx.headers['x-api-key'] as string })
120
- * ```
121
- *
122
- * @example Inject a static service-to-service key
123
- * ```typescript
124
- * getApiHeaders: () => ({ 'x-internal-key': process.env.INTERNAL_API_KEY! })
125
- * ```
126
- */
127
- getApiHeaders?: (ctx: Context) => Record<string, string>;
744
+ /**
745
+ * The HTTP path where the MCP server will be mounted
746
+ * @default '/mcp'
747
+ */
748
+ path?: string;
749
+ /**
750
+ * Optional session ID generator for stateful MCP servers.
751
+ * When provided, a single shared transport is created and sessions are tracked.
752
+ * When undefined (default), the server operates in stateless mode where each
753
+ * HTTP request uses its own transport instance.
754
+ */
755
+ sessionIdGenerator?: () => string;
756
+ /**
757
+ * Base URL prepended to relative paths passed to `apiCall` (paths starting
758
+ * with `/`). Tool handlers can then call `apiCall('GET', '/resource')` without
759
+ * specifying a host.
760
+ *
761
+ * @example 'http://localhost:3000/api/v1'
762
+ */
763
+ apiBaseUrl?: string;
764
+ /**
765
+ * Called once per incoming MCP HTTP request. Return a plain object whose
766
+ * key-value pairs will be merged into the headers of every `apiCall` made
767
+ * within that request's tool handlers.
768
+ *
769
+ * Use this to forward any header from the MCP request — Bearer tokens, API
770
+ * keys, tenant IDs, trace headers, etc. — without coupling tool handlers to
771
+ * a specific authentication scheme.
772
+ *
773
+ * @example Forward a Bearer token
774
+ * ```typescript
775
+ * getApiHeaders: (ctx) => ({ Authorization: ctx.headers.authorization ?? '' })
776
+ * ```
777
+ *
778
+ * @example Forward an x-api-key header
779
+ * ```typescript
780
+ * getApiHeaders: (ctx) => ({ 'x-api-key': ctx.headers['x-api-key'] as string })
781
+ * ```
782
+ *
783
+ * @example Inject a static service-to-service key
784
+ * ```typescript
785
+ * getApiHeaders: () => ({ 'x-internal-key': process.env.INTERNAL_API_KEY! })
786
+ * ```
787
+ */
788
+ getApiHeaders?: (ctx: Context$1) => Record<string, string>;
128
789
  }
129
790
  /**
130
791
  * Creates a Koa router configured to handle MCP protocol requests
@@ -163,7 +824,7 @@ interface McpRouterOptions {
163
824
  * app.listen(3000);
164
825
  * ```
165
826
  */
166
- declare const createMcpRouter: (server: McpServer, options?: McpRouterOptions) => Router<koa.DefaultState, koa.DefaultContext>;
827
+ declare const createMcpRouter: (server: McpServer$1, options?: McpRouterOptions) => Router<Application.DefaultState, Application.DefaultContext>;
167
828
  /**
168
829
  * A plain JSON Schema object (draft-07 compatible) describing the shape of a
169
830
  * tool's input. Used with {@link registerToolFromSchema} as an alternative to
@@ -171,32 +832,32 @@ declare const createMcpRouter: (server: McpServer, options?: McpRouterOptions) =
171
832
  * features not expressible in Zod v3 (`anyOf`, `$ref`, `pattern`, `allOf`, …).
172
833
  */
173
834
  interface JsonObjectSchema {
174
- type: 'object';
175
- properties?: Record<string, unknown>;
176
- required?: string[];
177
- [key: string]: unknown;
835
+ type: 'object';
836
+ properties?: Record<string, unknown>;
837
+ required?: string[];
838
+ [key: string]: unknown;
178
839
  }
179
840
  /**
180
841
  * Parameters accepted by {@link registerToolFromSchema}.
181
842
  */
182
843
  interface RegisterToolFromSchemaParams {
183
- /** Unique tool name. */
184
- name: string;
185
- /** Human-readable description shown to the AI client. */
186
- description?: string;
187
- /**
188
- * Plain JSON Schema that describes the tool's input object.
189
- * This schema is forwarded verbatim over the MCP wire protocol, so any
190
- * JSON Schema feature (`anyOf`, `$ref`, `pattern`, …) is preserved without
191
- * loss. Defaults to `{ type: 'object', properties: {} }` when omitted.
192
- */
193
- inputSchema?: JsonObjectSchema;
194
- /**
195
- * Tool handler invoked when the AI client calls the tool.
196
- * Receives the raw request arguments as a plain object (no Zod validation is
197
- * applied, so the shape matches whatever the client sends).
198
- */
199
- handler: (args: Record<string, unknown>) => CallToolResult | Promise<CallToolResult>;
844
+ /** Unique tool name. */
845
+ name: string;
846
+ /** Human-readable description shown to the AI client. */
847
+ description?: string;
848
+ /**
849
+ * Plain JSON Schema that describes the tool's input object.
850
+ * This schema is forwarded verbatim over the MCP wire protocol, so any
851
+ * JSON Schema feature (`anyOf`, `$ref`, `pattern`, …) is preserved without
852
+ * loss. Defaults to `{ type: 'object', properties: {} }` when omitted.
853
+ */
854
+ inputSchema?: JsonObjectSchema;
855
+ /**
856
+ * Tool handler invoked when the AI client calls the tool.
857
+ * Receives the raw request arguments as a plain object (no Zod validation is
858
+ * applied, so the shape matches whatever the client sends).
859
+ */
860
+ handler: (args: Record<string, unknown>) => CallToolResult | Promise<CallToolResult>;
200
861
  }
201
862
  /**
202
863
  * Registers a tool on an MCP server using a **plain JSON Schema** object for
@@ -239,6 +900,6 @@ interface RegisterToolFromSchemaParams {
239
900
  * });
240
901
  * ```
241
902
  */
242
- declare const registerToolFromSchema: (server: McpServer, params: RegisterToolFromSchemaParams) => void;
243
-
244
- export { type ApiCallOptions, type JsonObjectSchema, type McpRouterOptions, type RegisterToolFromSchemaParams, apiCall, createMcpRouter, registerToolFromSchema };
903
+ declare const registerToolFromSchema: (server: McpServer$1, params: RegisterToolFromSchemaParams) => void;
904
+ //#endregion
905
+ export { ApiCallOptions, JsonObjectSchema, McpRouterOptions, type McpServer, RegisterToolFromSchemaParams, apiCall, createMcpRouter, registerToolFromSchema, z };