@ttoss/http-server-mcp 0.37.1 → 0.39.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 +22 -0
- package/dist/index.cjs +11 -10
- package/dist/index.d.cts +36 -73
- package/dist/index.d.mts +36 -73
- package/dist/index.mjs +8 -7
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -1114,6 +1114,28 @@ const call = await request(app.callback())
|
|
|
1114
1114
|
expect(call.status).toBe(200);
|
|
1115
1115
|
```
|
|
1116
1116
|
|
|
1117
|
+
A `2026-07-28` request carries the per-request envelope in `params._meta` and must also send the `Mcp-Method` and `MCP-Protocol-Version` headers; the SDK answers `-32020` (headers and body disagree) at HTTP 400 when the version header is missing:
|
|
1118
|
+
|
|
1119
|
+
```typescript
|
|
1120
|
+
const discover = await request(app.callback())
|
|
1121
|
+
.post('/mcp')
|
|
1122
|
+
.set('Content-Type', 'application/json')
|
|
1123
|
+
.set('Accept', 'application/json, text/event-stream')
|
|
1124
|
+
.set('Mcp-Method', 'server/discover')
|
|
1125
|
+
.set('MCP-Protocol-Version', '2026-07-28')
|
|
1126
|
+
.send({
|
|
1127
|
+
jsonrpc: '2.0',
|
|
1128
|
+
id: 3,
|
|
1129
|
+
method: 'server/discover',
|
|
1130
|
+
params: {
|
|
1131
|
+
_meta: {
|
|
1132
|
+
'io.modelcontextprotocol/protocolVersion': '2026-07-28',
|
|
1133
|
+
'io.modelcontextprotocol/clientCapabilities': {},
|
|
1134
|
+
},
|
|
1135
|
+
},
|
|
1136
|
+
});
|
|
1137
|
+
```
|
|
1138
|
+
|
|
1117
1139
|
### `publicMethods` and OAuth clients
|
|
1118
1140
|
|
|
1119
1141
|
`auth.publicMethods` defaults to `['initialize', 'server/discover']`: the lifecycle handshake is reachable without a token, nothing else is. There are two entries because the exemption is about _the handshake_, not the method name — `initialize` is the 2025-era handshake and `server/discover` its `2026-07-28` replacement, since that revision removed `initialize` outright. Naming only one leaves the other era unable to negotiate at all.
|
package/dist/index.cjs
CHANGED
|
@@ -782,7 +782,7 @@ var rankTools = ({
|
|
|
782
782
|
};
|
|
783
783
|
var summaryOf = tool => {
|
|
784
784
|
const [line] = (tool.summary ?? tool.description).trim().split("\n", 1);
|
|
785
|
-
return line.length > SUMMARY_MAX_LENGTH ? `${line.slice(0,
|
|
785
|
+
return line.length > SUMMARY_MAX_LENGTH ? `${line.slice(0, 159).trimEnd()}…` : line;
|
|
786
786
|
};
|
|
787
787
|
var editDistance = (a, b) => {
|
|
788
788
|
const row = Array.from({
|
|
@@ -956,14 +956,15 @@ var searchToolOf = ({
|
|
|
956
956
|
},
|
|
957
957
|
handler: async args => {
|
|
958
958
|
const limit = args.limit ?? searchLimit;
|
|
959
|
+
const matches = await searchTools({
|
|
960
|
+
query: args.query,
|
|
961
|
+
tag: args.tag,
|
|
962
|
+
limit,
|
|
963
|
+
tools: visibleTools()
|
|
964
|
+
});
|
|
959
965
|
return jsonResult({
|
|
960
966
|
data: {
|
|
961
|
-
tools: (
|
|
962
|
-
query: args.query,
|
|
963
|
-
tag: args.tag,
|
|
964
|
-
limit,
|
|
965
|
-
tools: visibleTools()
|
|
966
|
-
})).slice(0, limit).map(tool => {
|
|
967
|
+
tools: matches.slice(0, limit).map(tool => {
|
|
967
968
|
return {
|
|
968
969
|
name: tool.name,
|
|
969
970
|
summary: summaryOf(tool),
|
|
@@ -1716,13 +1717,13 @@ var createMcpRouter = (server, options = {}) => {
|
|
|
1716
1717
|
//#endregion
|
|
1717
1718
|
exports.DEFAULT_DESCRIPTION_LIMIT = DEFAULT_DESCRIPTION_LIMIT;
|
|
1718
1719
|
exports.DEFAULT_INSTRUCTIONS_LIMIT = DEFAULT_INSTRUCTIONS_LIMIT;
|
|
1719
|
-
Object.defineProperty(exports,
|
|
1720
|
+
Object.defineProperty(exports, "InMemoryServerEventBus", {
|
|
1720
1721
|
enumerable: true,
|
|
1721
1722
|
get: function () {
|
|
1722
1723
|
return _modelcontextprotocol_server.InMemoryServerEventBus;
|
|
1723
1724
|
}
|
|
1724
1725
|
});
|
|
1725
|
-
Object.defineProperty(exports,
|
|
1726
|
+
Object.defineProperty(exports, "McpServer", {
|
|
1726
1727
|
enumerable: true,
|
|
1727
1728
|
get: function () {
|
|
1728
1729
|
return _modelcontextprotocol_server.McpServer;
|
|
@@ -1745,7 +1746,7 @@ exports.measureMcpSurface = measureMcpSurface;
|
|
|
1745
1746
|
exports.rankTools = rankTools;
|
|
1746
1747
|
exports.registerAppResource = registerAppResource;
|
|
1747
1748
|
exports.registerTools = registerTools;
|
|
1748
|
-
Object.defineProperty(exports,
|
|
1749
|
+
Object.defineProperty(exports, "z", {
|
|
1749
1750
|
enumerable: true,
|
|
1750
1751
|
get: function () {
|
|
1751
1752
|
return zod.z;
|
package/dist/index.d.cts
CHANGED
|
@@ -2,23 +2,22 @@
|
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
import { CallToolResult, InMemoryServerEventBus, McpServer, McpServer as McpServer$1, McpServerFactory, RegisteredResource, ServerEvent, ServerEventBus, ServerEventBus as ServerEventBus$1, ServerNotifier, ServerNotifier as ServerNotifier$1, StandardSchemaWithJSON, ToolAnnotations } from "@modelcontextprotocol/server";
|
|
4
4
|
import { Router } from "@ttoss/http-server";
|
|
5
|
-
import accepts from "accepts";
|
|
5
|
+
import * as accepts from "accepts";
|
|
6
6
|
import { AsyncLocalStorage } from "async_hooks";
|
|
7
|
-
import Cookies from "cookies";
|
|
7
|
+
import * as Cookies from "cookies";
|
|
8
8
|
import { EventEmitter } from "events";
|
|
9
9
|
import { IncomingHttpHeaders, IncomingMessage, OutgoingHttpHeaders, Server, ServerResponse } from "http";
|
|
10
10
|
import { Http2ServerRequest, Http2ServerResponse } from "http2";
|
|
11
|
-
import httpAssert from "http-assert";
|
|
12
|
-
import contentDisposition from "content-disposition";
|
|
13
|
-
import HttpErrors from "http-errors";
|
|
14
|
-
import Keygrip from "keygrip";
|
|
15
|
-
import compose from "koa-compose";
|
|
11
|
+
import * as httpAssert from "http-assert";
|
|
12
|
+
import * as contentDisposition from "content-disposition";
|
|
13
|
+
import * as HttpErrors from "http-errors";
|
|
14
|
+
import * as Keygrip from "keygrip";
|
|
15
|
+
import * as compose from "koa-compose";
|
|
16
16
|
import { ListenOptions, Socket } from "net";
|
|
17
17
|
import { ParsedUrlQuery } from "querystring";
|
|
18
18
|
import * as url from "url";
|
|
19
19
|
import { Catalog } from "@ttoss/i18n-core";
|
|
20
20
|
import { z } from "zod";
|
|
21
|
-
|
|
22
21
|
//#region ../../node_modules/.pnpm/@types+koa@3.0.3/node_modules/@types/koa/index.d.ts
|
|
23
22
|
declare interface ContextDelegatedRequest {
|
|
24
23
|
/**
|
|
@@ -674,7 +673,7 @@ declare namespace Application {
|
|
|
674
673
|
* `getIdentity<{ sub: string; email: string }>()` returns `T | undefined`.
|
|
675
674
|
* Omitting the type parameter keeps the return type as `unknown | undefined`.
|
|
676
675
|
*/
|
|
677
|
-
declare const getIdentity: <T = unknown>() => T | undefined;
|
|
676
|
+
export declare const getIdentity: <T = unknown>() => T | undefined;
|
|
678
677
|
/**
|
|
679
678
|
* Returns the headers `getApiHeaders` produced for the current MCP request —
|
|
680
679
|
* the same headers `apiCall` injects. Use it inside a tool handler that runs
|
|
@@ -683,13 +682,13 @@ declare const getIdentity: <T = unknown>() => T | undefined;
|
|
|
683
682
|
*
|
|
684
683
|
* Returns `{}` outside a request, or when `getApiHeaders` is not configured.
|
|
685
684
|
*/
|
|
686
|
-
declare const getApiHeaders: () => Record<string, string>;
|
|
685
|
+
export declare const getApiHeaders: () => Record<string, string>;
|
|
687
686
|
/**
|
|
688
687
|
* The `Accept-Language` header of the current MCP request, or `undefined`
|
|
689
688
|
* outside a request or when the client sent none. The default locale source
|
|
690
689
|
* for `createToolGate`'s `i18n` option.
|
|
691
690
|
*/
|
|
692
|
-
declare const getRequestLocale: () => string | undefined;
|
|
691
|
+
export declare const getRequestLocale: () => string | undefined;
|
|
693
692
|
//#endregion
|
|
694
693
|
//#region src/tool.d.ts
|
|
695
694
|
/**
|
|
@@ -800,11 +799,7 @@ interface DefineToolParams extends Omit<Tool, 'handler'> {
|
|
|
800
799
|
* });
|
|
801
800
|
* ```
|
|
802
801
|
*/
|
|
803
|
-
declare const defineTool: ({
|
|
804
|
-
method,
|
|
805
|
-
notFoundMessage,
|
|
806
|
-
...tool
|
|
807
|
-
}: DefineToolParams) => Tool;
|
|
802
|
+
export declare const defineTool: ({ method, notFoundMessage, ...tool }: DefineToolParams) => Tool;
|
|
808
803
|
//#endregion
|
|
809
804
|
//#region src/toolSearch.d.ts
|
|
810
805
|
/** What the deferred `search` ranks: one call, already narrowed to the visible tools. */
|
|
@@ -823,12 +818,7 @@ interface ToolSearchArgs {
|
|
|
823
818
|
* weighted name > summary > tags > description, and breaks ties by the
|
|
824
819
|
* tools' order. No index — a few hundred tools need none.
|
|
825
820
|
*/
|
|
826
|
-
declare const rankTools: ({
|
|
827
|
-
query,
|
|
828
|
-
tag,
|
|
829
|
-
limit,
|
|
830
|
-
tools
|
|
831
|
-
}: ToolSearchArgs) => Tool[];
|
|
821
|
+
export declare const rankTools: ({ query, tag, limit, tools }: ToolSearchArgs) => Tool[];
|
|
832
822
|
//#endregion
|
|
833
823
|
//#region src/deferTools.d.ts
|
|
834
824
|
/** How {@link registerTools} defers tools behind `search` / `describe` / `call`. */
|
|
@@ -957,12 +947,12 @@ type McpSurfaceViolation = {
|
|
|
957
947
|
* (https://code.claude.com/docs/en/mcp; a user can change it with
|
|
958
948
|
* `CLAUDE_CODE_MAX_MCP_DESCRIPTION_LENGTH`).
|
|
959
949
|
*/
|
|
960
|
-
declare const DEFAULT_INSTRUCTIONS_LIMIT = 2048;
|
|
950
|
+
export declare const DEFAULT_INSTRUCTIONS_LIMIT = 2048;
|
|
961
951
|
/**
|
|
962
952
|
* Claude Code truncates each tool description at the same length as the
|
|
963
953
|
* instructions, from the same documentation, and just as silently.
|
|
964
954
|
*/
|
|
965
|
-
declare const DEFAULT_DESCRIPTION_LIMIT = 2048;
|
|
955
|
+
export declare const DEFAULT_DESCRIPTION_LIMIT = 2048;
|
|
966
956
|
/**
|
|
967
957
|
* Measures what an MCP server costs every session that connects to it: each
|
|
968
958
|
* tool's name, description and input schema, and the instructions.
|
|
@@ -970,10 +960,7 @@ declare const DEFAULT_DESCRIPTION_LIMIT = 2048;
|
|
|
970
960
|
* It does not judge; {@link checkMcpSurface} compares the same numbers with a
|
|
971
961
|
* budget.
|
|
972
962
|
*/
|
|
973
|
-
declare const measureMcpSurface: ({
|
|
974
|
-
tools,
|
|
975
|
-
instructions
|
|
976
|
-
}: {
|
|
963
|
+
export declare const measureMcpSurface: ({ tools, instructions }: {
|
|
977
964
|
tools: McpSurfaceTool[];
|
|
978
965
|
instructions?: string;
|
|
979
966
|
}) => McpSurfaceReport;
|
|
@@ -995,11 +982,7 @@ declare const measureMcpSurface: ({
|
|
|
995
982
|
* ).toEqual([]);
|
|
996
983
|
* ```
|
|
997
984
|
*/
|
|
998
|
-
declare const checkMcpSurface: ({
|
|
999
|
-
tools,
|
|
1000
|
-
instructions,
|
|
1001
|
-
budget
|
|
1002
|
-
}: {
|
|
985
|
+
export declare const checkMcpSurface: ({ tools, instructions, budget }: {
|
|
1003
986
|
tools: McpSurfaceTool[];
|
|
1004
987
|
instructions?: string;
|
|
1005
988
|
budget?: McpSurfaceBudget;
|
|
@@ -1012,11 +995,7 @@ declare const checkMcpSurface: ({
|
|
|
1012
995
|
* Pass `pattern` (a global RegExp whose first group is the name) when the
|
|
1013
996
|
* instructions name tools some other way.
|
|
1014
997
|
*/
|
|
1015
|
-
declare const findUnknownToolMentions: ({
|
|
1016
|
-
instructions,
|
|
1017
|
-
tools,
|
|
1018
|
-
pattern
|
|
1019
|
-
}: {
|
|
998
|
+
export declare const findUnknownToolMentions: ({ instructions, tools, pattern }: {
|
|
1020
999
|
instructions: string;
|
|
1021
1000
|
tools: Array<Pick<McpSurfaceTool, "name">>;
|
|
1022
1001
|
pattern?: RegExp;
|
|
@@ -1043,9 +1022,9 @@ declare const findUnknownToolMentions: ({
|
|
|
1043
1022
|
* );
|
|
1044
1023
|
* ```
|
|
1045
1024
|
*/
|
|
1046
|
-
declare const UI_EXTENSION_ID = "io.modelcontextprotocol/ui";
|
|
1025
|
+
export declare const UI_EXTENSION_ID = "io.modelcontextprotocol/ui";
|
|
1047
1026
|
/** MIME type every MCP Apps HTML resource is served as. */
|
|
1048
|
-
declare const UI_RESOURCE_MIME_TYPE = "text/html;profile=mcp-app";
|
|
1027
|
+
export declare const UI_RESOURCE_MIME_TYPE = "text/html;profile=mcp-app";
|
|
1049
1028
|
/**
|
|
1050
1029
|
* Origins an app's view is allowed to reach, mapped by the host onto the
|
|
1051
1030
|
* iframe's Content Security Policy. Anything not declared is blocked: an
|
|
@@ -1203,14 +1182,7 @@ interface RegisteredAppResource {
|
|
|
1203
1182
|
* );
|
|
1204
1183
|
* ```
|
|
1205
1184
|
*/
|
|
1206
|
-
declare const registerAppResource: ({
|
|
1207
|
-
server,
|
|
1208
|
-
name,
|
|
1209
|
-
uri,
|
|
1210
|
-
description,
|
|
1211
|
-
html,
|
|
1212
|
-
ui
|
|
1213
|
-
}: RegisterAppResourceParams) => RegisteredAppResource;
|
|
1185
|
+
export declare const registerAppResource: ({ server, name, uri, description, html, ui }: RegisterAppResourceParams) => RegisteredAppResource;
|
|
1214
1186
|
//#endregion
|
|
1215
1187
|
//#region src/registerTools.d.ts
|
|
1216
1188
|
/** Parameters for {@link registerTools}. */
|
|
@@ -1258,11 +1230,7 @@ interface RegisterToolsParams {
|
|
|
1258
1230
|
* registerTools({ server: deferredServer, tools, defer: true });
|
|
1259
1231
|
* ```
|
|
1260
1232
|
*/
|
|
1261
|
-
declare const registerTools: ({
|
|
1262
|
-
server,
|
|
1263
|
-
tools,
|
|
1264
|
-
defer
|
|
1265
|
-
}: RegisterToolsParams) => void;
|
|
1233
|
+
export declare const registerTools: ({ server, tools, defer }: RegisterToolsParams) => void;
|
|
1266
1234
|
//#endregion
|
|
1267
1235
|
//#region src/toolGate.d.ts
|
|
1268
1236
|
/** Resolved identity for a gated tool call. */
|
|
@@ -1276,12 +1244,14 @@ type ToolIdentity = {
|
|
|
1276
1244
|
* be both identity-aware and args-aware without multiple parameters.
|
|
1277
1245
|
*/
|
|
1278
1246
|
type ToolCallContext = {
|
|
1279
|
-
/** The resolved caller identity. */
|
|
1247
|
+
/** The resolved caller identity. */
|
|
1248
|
+
identity: ToolIdentity;
|
|
1280
1249
|
/**
|
|
1281
1250
|
* The validated tool input. Arg-conditional gates read this to vary their
|
|
1282
1251
|
* predicate per call.
|
|
1283
1252
|
*/
|
|
1284
|
-
args: Record<string, unknown>;
|
|
1253
|
+
args: Record<string, unknown>;
|
|
1254
|
+
/** Tool name, for error attribution and gate labelling. */
|
|
1285
1255
|
handler: string;
|
|
1286
1256
|
};
|
|
1287
1257
|
/** An authorization check. Throw to reject the call; return to continue. */
|
|
@@ -1401,19 +1371,12 @@ type ToolGate = (params: GateToolParams) => Tool;
|
|
|
1401
1371
|
* });
|
|
1402
1372
|
* ```
|
|
1403
1373
|
*/
|
|
1404
|
-
declare const createToolGate: ({
|
|
1405
|
-
resolveIdentity,
|
|
1406
|
-
gates,
|
|
1407
|
-
enforceScope,
|
|
1408
|
-
onError,
|
|
1409
|
-
buildContext,
|
|
1410
|
-
i18n
|
|
1411
|
-
}?: CreateToolGateOptions) => ToolGate;
|
|
1374
|
+
export declare const createToolGate: ({ resolveIdentity, gates, enforceScope, onError, buildContext, i18n }?: CreateToolGateOptions) => ToolGate;
|
|
1412
1375
|
//#endregion
|
|
1413
1376
|
//#region src/index.d.ts
|
|
1414
1377
|
type Context$1 = Application.Context;
|
|
1415
1378
|
/** Amazon Cognito user pool configuration for JWT verification. */
|
|
1416
|
-
interface CognitoUserPoolConfig {
|
|
1379
|
+
export interface CognitoUserPoolConfig {
|
|
1417
1380
|
/** The Cognito User Pool ID (e.g. `us-east-1_abc123`). */
|
|
1418
1381
|
userPoolId: string;
|
|
1419
1382
|
/**
|
|
@@ -1429,7 +1392,7 @@ interface CognitoUserPoolConfig {
|
|
|
1429
1392
|
* `@ttoss/http-server-auth`'s `oauth` strategy; supply either a Cognito user
|
|
1430
1393
|
* pool or a custom `verifyToken`.
|
|
1431
1394
|
*/
|
|
1432
|
-
interface McpAuthOptions {
|
|
1395
|
+
export interface McpAuthOptions {
|
|
1433
1396
|
/** Amazon Cognito user pool config; a `CognitoJwtVerifier` is built from it. */
|
|
1434
1397
|
cognitoUserPool?: CognitoUserPoolConfig;
|
|
1435
1398
|
/**
|
|
@@ -1561,11 +1524,11 @@ interface McpAuthOptions {
|
|
|
1561
1524
|
* }
|
|
1562
1525
|
* ```
|
|
1563
1526
|
*/
|
|
1564
|
-
declare const errorBodyMessage: (body: unknown) => string | undefined;
|
|
1527
|
+
export declare const errorBodyMessage: (body: unknown) => string | undefined;
|
|
1565
1528
|
/**
|
|
1566
1529
|
* Options for a single `apiCall` request.
|
|
1567
1530
|
*/
|
|
1568
|
-
interface ApiCallOptions {
|
|
1531
|
+
export interface ApiCallOptions {
|
|
1569
1532
|
/**
|
|
1570
1533
|
* JSON-serialisable request body. Automatically serialised and sent with
|
|
1571
1534
|
* `Content-Type: application/json`.
|
|
@@ -1631,7 +1594,7 @@ interface ApiCallOptions {
|
|
|
1631
1594
|
* });
|
|
1632
1595
|
* ```
|
|
1633
1596
|
*/
|
|
1634
|
-
declare const apiCall: (method: string, url: string, options?: ApiCallOptions) => Promise<unknown>;
|
|
1597
|
+
export declare const apiCall: (method: string, url: string, options?: ApiCallOptions) => Promise<unknown>;
|
|
1635
1598
|
/**
|
|
1636
1599
|
* Asserts that the current request's token contains all required scopes.
|
|
1637
1600
|
* Throws if any scope is missing — the MCP SDK catches this and returns a
|
|
@@ -1649,12 +1612,12 @@ declare const apiCall: (method: string, url: string, options?: ApiCallOptions) =
|
|
|
1649
1612
|
* });
|
|
1650
1613
|
* ```
|
|
1651
1614
|
*/
|
|
1652
|
-
declare const checkScopes: (required: string[]) => void;
|
|
1615
|
+
export declare const checkScopes: (required: string[]) => void;
|
|
1653
1616
|
/**
|
|
1654
1617
|
* The router {@link createMcpRouter} returns: a Koa router, plus the two
|
|
1655
1618
|
* operations on the `2026-07-28` streams it serves.
|
|
1656
1619
|
*/
|
|
1657
|
-
type McpRouter = Router & {
|
|
1620
|
+
export type McpRouter = Router & {
|
|
1658
1621
|
/**
|
|
1659
1622
|
* Publishes the `list_changed` notifications (and `resources/updated`) to
|
|
1660
1623
|
* every open `subscriptions/listen` stream that opted in. Call
|
|
@@ -1676,7 +1639,7 @@ type McpRouter = Router & {
|
|
|
1676
1639
|
/**
|
|
1677
1640
|
* Options for configuring the MCP router
|
|
1678
1641
|
*/
|
|
1679
|
-
interface McpRouterOptions {
|
|
1642
|
+
export interface McpRouterOptions {
|
|
1680
1643
|
/**
|
|
1681
1644
|
* The HTTP path where the MCP server will be mounted
|
|
1682
1645
|
* @default '/mcp'
|
|
@@ -1851,6 +1814,6 @@ interface McpRouterOptions {
|
|
|
1851
1814
|
* app.listen(3000);
|
|
1852
1815
|
* ```
|
|
1853
1816
|
*/
|
|
1854
|
-
declare const createMcpRouter: (server: McpServer$1, options?: McpRouterOptions) => McpRouter;
|
|
1817
|
+
export declare const createMcpRouter: (server: McpServer$1, options?: McpRouterOptions) => McpRouter;
|
|
1855
1818
|
//#endregion
|
|
1856
|
-
export {
|
|
1819
|
+
export { type CreateToolGateOptions, type DeferToolsOptions, type DefineToolParams, type GateToolParams, InMemoryServerEventBus, type JsonObjectSchema, McpServer, type McpSurfaceBudget, type McpSurfaceReport, type McpSurfaceTool, type McpSurfaceViolation, type RegisterAppResourceParams, type RegisterToolsParams, type RegisteredAppResource, type ServerEvent, type ServerEventBus, type ServerNotifier, type Tool, type ToolCallContext, type ToolCallGate, type ToolGate, type ToolIdentity, type ToolMetaParams, type ToolSchema, type ToolSearchArgs, type UiResourceCsp, type UiResourceMeta, type UiResourcePermissions, type UiToolVisibility, z };
|
package/dist/index.d.mts
CHANGED
|
@@ -4,22 +4,21 @@ import { Router } from "@ttoss/http-server";
|
|
|
4
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
5
|
import { CallToolResult, InMemoryServerEventBus, McpServer, McpServer as McpServer$1, McpServerFactory, RegisteredResource, ServerEvent, ServerEventBus, ServerEventBus as ServerEventBus$1, ServerNotifier, ServerNotifier as ServerNotifier$1, StandardSchemaWithJSON, ToolAnnotations } from "@modelcontextprotocol/server";
|
|
6
6
|
import { z } from "zod";
|
|
7
|
-
import accepts from "accepts";
|
|
7
|
+
import * as accepts from "accepts";
|
|
8
8
|
import { AsyncLocalStorage as AsyncLocalStorage$1 } from "async_hooks";
|
|
9
|
-
import Cookies from "cookies";
|
|
9
|
+
import * as Cookies from "cookies";
|
|
10
10
|
import { EventEmitter } from "events";
|
|
11
11
|
import { IncomingHttpHeaders, IncomingMessage, OutgoingHttpHeaders, Server, ServerResponse } from "http";
|
|
12
12
|
import { Http2ServerRequest, Http2ServerResponse } from "http2";
|
|
13
|
-
import httpAssert from "http-assert";
|
|
14
|
-
import contentDisposition from "content-disposition";
|
|
15
|
-
import HttpErrors from "http-errors";
|
|
16
|
-
import Keygrip from "keygrip";
|
|
17
|
-
import compose from "koa-compose";
|
|
13
|
+
import * as httpAssert from "http-assert";
|
|
14
|
+
import * as contentDisposition from "content-disposition";
|
|
15
|
+
import * as HttpErrors from "http-errors";
|
|
16
|
+
import * as Keygrip from "keygrip";
|
|
17
|
+
import * as compose from "koa-compose";
|
|
18
18
|
import { ListenOptions, Socket } from "net";
|
|
19
19
|
import { ParsedUrlQuery } from "querystring";
|
|
20
20
|
import * as url from "url";
|
|
21
21
|
import { Catalog } from "@ttoss/i18n-core";
|
|
22
|
-
|
|
23
22
|
//#region ../../node_modules/.pnpm/@types+koa@3.0.3/node_modules/@types/koa/index.d.ts
|
|
24
23
|
declare interface ContextDelegatedRequest {
|
|
25
24
|
/**
|
|
@@ -675,7 +674,7 @@ declare namespace Application {
|
|
|
675
674
|
* `getIdentity<{ sub: string; email: string }>()` returns `T | undefined`.
|
|
676
675
|
* Omitting the type parameter keeps the return type as `unknown | undefined`.
|
|
677
676
|
*/
|
|
678
|
-
declare const getIdentity: <T = unknown>() => T | undefined;
|
|
677
|
+
export declare const getIdentity: <T = unknown>() => T | undefined;
|
|
679
678
|
/**
|
|
680
679
|
* Returns the headers `getApiHeaders` produced for the current MCP request —
|
|
681
680
|
* the same headers `apiCall` injects. Use it inside a tool handler that runs
|
|
@@ -684,13 +683,13 @@ declare const getIdentity: <T = unknown>() => T | undefined;
|
|
|
684
683
|
*
|
|
685
684
|
* Returns `{}` outside a request, or when `getApiHeaders` is not configured.
|
|
686
685
|
*/
|
|
687
|
-
declare const getApiHeaders: () => Record<string, string>;
|
|
686
|
+
export declare const getApiHeaders: () => Record<string, string>;
|
|
688
687
|
/**
|
|
689
688
|
* The `Accept-Language` header of the current MCP request, or `undefined`
|
|
690
689
|
* outside a request or when the client sent none. The default locale source
|
|
691
690
|
* for `createToolGate`'s `i18n` option.
|
|
692
691
|
*/
|
|
693
|
-
declare const getRequestLocale: () => string | undefined;
|
|
692
|
+
export declare const getRequestLocale: () => string | undefined;
|
|
694
693
|
//#endregion
|
|
695
694
|
//#region src/tool.d.ts
|
|
696
695
|
/**
|
|
@@ -801,11 +800,7 @@ interface DefineToolParams extends Omit<Tool, 'handler'> {
|
|
|
801
800
|
* });
|
|
802
801
|
* ```
|
|
803
802
|
*/
|
|
804
|
-
declare const defineTool: ({
|
|
805
|
-
method,
|
|
806
|
-
notFoundMessage,
|
|
807
|
-
...tool
|
|
808
|
-
}: DefineToolParams) => Tool;
|
|
803
|
+
export declare const defineTool: ({ method, notFoundMessage, ...tool }: DefineToolParams) => Tool;
|
|
809
804
|
//#endregion
|
|
810
805
|
//#region src/toolSearch.d.ts
|
|
811
806
|
/** What the deferred `search` ranks: one call, already narrowed to the visible tools. */
|
|
@@ -824,12 +819,7 @@ interface ToolSearchArgs {
|
|
|
824
819
|
* weighted name > summary > tags > description, and breaks ties by the
|
|
825
820
|
* tools' order. No index — a few hundred tools need none.
|
|
826
821
|
*/
|
|
827
|
-
declare const rankTools: ({
|
|
828
|
-
query,
|
|
829
|
-
tag,
|
|
830
|
-
limit,
|
|
831
|
-
tools
|
|
832
|
-
}: ToolSearchArgs) => Tool[];
|
|
822
|
+
export declare const rankTools: ({ query, tag, limit, tools }: ToolSearchArgs) => Tool[];
|
|
833
823
|
//#endregion
|
|
834
824
|
//#region src/deferTools.d.ts
|
|
835
825
|
/** How {@link registerTools} defers tools behind `search` / `describe` / `call`. */
|
|
@@ -958,12 +948,12 @@ type McpSurfaceViolation = {
|
|
|
958
948
|
* (https://code.claude.com/docs/en/mcp; a user can change it with
|
|
959
949
|
* `CLAUDE_CODE_MAX_MCP_DESCRIPTION_LENGTH`).
|
|
960
950
|
*/
|
|
961
|
-
declare const DEFAULT_INSTRUCTIONS_LIMIT = 2048;
|
|
951
|
+
export declare const DEFAULT_INSTRUCTIONS_LIMIT = 2048;
|
|
962
952
|
/**
|
|
963
953
|
* Claude Code truncates each tool description at the same length as the
|
|
964
954
|
* instructions, from the same documentation, and just as silently.
|
|
965
955
|
*/
|
|
966
|
-
declare const DEFAULT_DESCRIPTION_LIMIT = 2048;
|
|
956
|
+
export declare const DEFAULT_DESCRIPTION_LIMIT = 2048;
|
|
967
957
|
/**
|
|
968
958
|
* Measures what an MCP server costs every session that connects to it: each
|
|
969
959
|
* tool's name, description and input schema, and the instructions.
|
|
@@ -971,10 +961,7 @@ declare const DEFAULT_DESCRIPTION_LIMIT = 2048;
|
|
|
971
961
|
* It does not judge; {@link checkMcpSurface} compares the same numbers with a
|
|
972
962
|
* budget.
|
|
973
963
|
*/
|
|
974
|
-
declare const measureMcpSurface: ({
|
|
975
|
-
tools,
|
|
976
|
-
instructions
|
|
977
|
-
}: {
|
|
964
|
+
export declare const measureMcpSurface: ({ tools, instructions }: {
|
|
978
965
|
tools: McpSurfaceTool[];
|
|
979
966
|
instructions?: string;
|
|
980
967
|
}) => McpSurfaceReport;
|
|
@@ -996,11 +983,7 @@ declare const measureMcpSurface: ({
|
|
|
996
983
|
* ).toEqual([]);
|
|
997
984
|
* ```
|
|
998
985
|
*/
|
|
999
|
-
declare const checkMcpSurface: ({
|
|
1000
|
-
tools,
|
|
1001
|
-
instructions,
|
|
1002
|
-
budget
|
|
1003
|
-
}: {
|
|
986
|
+
export declare const checkMcpSurface: ({ tools, instructions, budget }: {
|
|
1004
987
|
tools: McpSurfaceTool[];
|
|
1005
988
|
instructions?: string;
|
|
1006
989
|
budget?: McpSurfaceBudget;
|
|
@@ -1013,11 +996,7 @@ declare const checkMcpSurface: ({
|
|
|
1013
996
|
* Pass `pattern` (a global RegExp whose first group is the name) when the
|
|
1014
997
|
* instructions name tools some other way.
|
|
1015
998
|
*/
|
|
1016
|
-
declare const findUnknownToolMentions: ({
|
|
1017
|
-
instructions,
|
|
1018
|
-
tools,
|
|
1019
|
-
pattern
|
|
1020
|
-
}: {
|
|
999
|
+
export declare const findUnknownToolMentions: ({ instructions, tools, pattern }: {
|
|
1021
1000
|
instructions: string;
|
|
1022
1001
|
tools: Array<Pick<McpSurfaceTool, "name">>;
|
|
1023
1002
|
pattern?: RegExp;
|
|
@@ -1044,9 +1023,9 @@ declare const findUnknownToolMentions: ({
|
|
|
1044
1023
|
* );
|
|
1045
1024
|
* ```
|
|
1046
1025
|
*/
|
|
1047
|
-
declare const UI_EXTENSION_ID = "io.modelcontextprotocol/ui";
|
|
1026
|
+
export declare const UI_EXTENSION_ID = "io.modelcontextprotocol/ui";
|
|
1048
1027
|
/** MIME type every MCP Apps HTML resource is served as. */
|
|
1049
|
-
declare const UI_RESOURCE_MIME_TYPE = "text/html;profile=mcp-app";
|
|
1028
|
+
export declare const UI_RESOURCE_MIME_TYPE = "text/html;profile=mcp-app";
|
|
1050
1029
|
/**
|
|
1051
1030
|
* Origins an app's view is allowed to reach, mapped by the host onto the
|
|
1052
1031
|
* iframe's Content Security Policy. Anything not declared is blocked: an
|
|
@@ -1204,14 +1183,7 @@ interface RegisteredAppResource {
|
|
|
1204
1183
|
* );
|
|
1205
1184
|
* ```
|
|
1206
1185
|
*/
|
|
1207
|
-
declare const registerAppResource: ({
|
|
1208
|
-
server,
|
|
1209
|
-
name,
|
|
1210
|
-
uri,
|
|
1211
|
-
description,
|
|
1212
|
-
html,
|
|
1213
|
-
ui
|
|
1214
|
-
}: RegisterAppResourceParams) => RegisteredAppResource;
|
|
1186
|
+
export declare const registerAppResource: ({ server, name, uri, description, html, ui }: RegisterAppResourceParams) => RegisteredAppResource;
|
|
1215
1187
|
//#endregion
|
|
1216
1188
|
//#region src/registerTools.d.ts
|
|
1217
1189
|
/** Parameters for {@link registerTools}. */
|
|
@@ -1259,11 +1231,7 @@ interface RegisterToolsParams {
|
|
|
1259
1231
|
* registerTools({ server: deferredServer, tools, defer: true });
|
|
1260
1232
|
* ```
|
|
1261
1233
|
*/
|
|
1262
|
-
declare const registerTools: ({
|
|
1263
|
-
server,
|
|
1264
|
-
tools,
|
|
1265
|
-
defer
|
|
1266
|
-
}: RegisterToolsParams) => void;
|
|
1234
|
+
export declare const registerTools: ({ server, tools, defer }: RegisterToolsParams) => void;
|
|
1267
1235
|
//#endregion
|
|
1268
1236
|
//#region src/toolGate.d.ts
|
|
1269
1237
|
/** Resolved identity for a gated tool call. */
|
|
@@ -1277,12 +1245,14 @@ type ToolIdentity = {
|
|
|
1277
1245
|
* be both identity-aware and args-aware without multiple parameters.
|
|
1278
1246
|
*/
|
|
1279
1247
|
type ToolCallContext = {
|
|
1280
|
-
/** The resolved caller identity. */
|
|
1248
|
+
/** The resolved caller identity. */
|
|
1249
|
+
identity: ToolIdentity;
|
|
1281
1250
|
/**
|
|
1282
1251
|
* The validated tool input. Arg-conditional gates read this to vary their
|
|
1283
1252
|
* predicate per call.
|
|
1284
1253
|
*/
|
|
1285
|
-
args: Record<string, unknown>;
|
|
1254
|
+
args: Record<string, unknown>;
|
|
1255
|
+
/** Tool name, for error attribution and gate labelling. */
|
|
1286
1256
|
handler: string;
|
|
1287
1257
|
};
|
|
1288
1258
|
/** An authorization check. Throw to reject the call; return to continue. */
|
|
@@ -1402,19 +1372,12 @@ type ToolGate = (params: GateToolParams) => Tool;
|
|
|
1402
1372
|
* });
|
|
1403
1373
|
* ```
|
|
1404
1374
|
*/
|
|
1405
|
-
declare const createToolGate: ({
|
|
1406
|
-
resolveIdentity,
|
|
1407
|
-
gates,
|
|
1408
|
-
enforceScope,
|
|
1409
|
-
onError,
|
|
1410
|
-
buildContext,
|
|
1411
|
-
i18n
|
|
1412
|
-
}?: CreateToolGateOptions) => ToolGate;
|
|
1375
|
+
export declare const createToolGate: ({ resolveIdentity, gates, enforceScope, onError, buildContext, i18n }?: CreateToolGateOptions) => ToolGate;
|
|
1413
1376
|
//#endregion
|
|
1414
1377
|
//#region src/index.d.ts
|
|
1415
1378
|
type Context$1 = Application.Context;
|
|
1416
1379
|
/** Amazon Cognito user pool configuration for JWT verification. */
|
|
1417
|
-
interface CognitoUserPoolConfig {
|
|
1380
|
+
export interface CognitoUserPoolConfig {
|
|
1418
1381
|
/** The Cognito User Pool ID (e.g. `us-east-1_abc123`). */
|
|
1419
1382
|
userPoolId: string;
|
|
1420
1383
|
/**
|
|
@@ -1430,7 +1393,7 @@ interface CognitoUserPoolConfig {
|
|
|
1430
1393
|
* `@ttoss/http-server-auth`'s `oauth` strategy; supply either a Cognito user
|
|
1431
1394
|
* pool or a custom `verifyToken`.
|
|
1432
1395
|
*/
|
|
1433
|
-
interface McpAuthOptions {
|
|
1396
|
+
export interface McpAuthOptions {
|
|
1434
1397
|
/** Amazon Cognito user pool config; a `CognitoJwtVerifier` is built from it. */
|
|
1435
1398
|
cognitoUserPool?: CognitoUserPoolConfig;
|
|
1436
1399
|
/**
|
|
@@ -1562,11 +1525,11 @@ interface McpAuthOptions {
|
|
|
1562
1525
|
* }
|
|
1563
1526
|
* ```
|
|
1564
1527
|
*/
|
|
1565
|
-
declare const errorBodyMessage: (body: unknown) => string | undefined;
|
|
1528
|
+
export declare const errorBodyMessage: (body: unknown) => string | undefined;
|
|
1566
1529
|
/**
|
|
1567
1530
|
* Options for a single `apiCall` request.
|
|
1568
1531
|
*/
|
|
1569
|
-
interface ApiCallOptions {
|
|
1532
|
+
export interface ApiCallOptions {
|
|
1570
1533
|
/**
|
|
1571
1534
|
* JSON-serialisable request body. Automatically serialised and sent with
|
|
1572
1535
|
* `Content-Type: application/json`.
|
|
@@ -1632,7 +1595,7 @@ interface ApiCallOptions {
|
|
|
1632
1595
|
* });
|
|
1633
1596
|
* ```
|
|
1634
1597
|
*/
|
|
1635
|
-
declare const apiCall: (method: string, url: string, options?: ApiCallOptions) => Promise<unknown>;
|
|
1598
|
+
export declare const apiCall: (method: string, url: string, options?: ApiCallOptions) => Promise<unknown>;
|
|
1636
1599
|
/**
|
|
1637
1600
|
* Asserts that the current request's token contains all required scopes.
|
|
1638
1601
|
* Throws if any scope is missing — the MCP SDK catches this and returns a
|
|
@@ -1650,12 +1613,12 @@ declare const apiCall: (method: string, url: string, options?: ApiCallOptions) =
|
|
|
1650
1613
|
* });
|
|
1651
1614
|
* ```
|
|
1652
1615
|
*/
|
|
1653
|
-
declare const checkScopes: (required: string[]) => void;
|
|
1616
|
+
export declare const checkScopes: (required: string[]) => void;
|
|
1654
1617
|
/**
|
|
1655
1618
|
* The router {@link createMcpRouter} returns: a Koa router, plus the two
|
|
1656
1619
|
* operations on the `2026-07-28` streams it serves.
|
|
1657
1620
|
*/
|
|
1658
|
-
type McpRouter = Router & {
|
|
1621
|
+
export type McpRouter = Router & {
|
|
1659
1622
|
/**
|
|
1660
1623
|
* Publishes the `list_changed` notifications (and `resources/updated`) to
|
|
1661
1624
|
* every open `subscriptions/listen` stream that opted in. Call
|
|
@@ -1677,7 +1640,7 @@ type McpRouter = Router & {
|
|
|
1677
1640
|
/**
|
|
1678
1641
|
* Options for configuring the MCP router
|
|
1679
1642
|
*/
|
|
1680
|
-
interface McpRouterOptions {
|
|
1643
|
+
export interface McpRouterOptions {
|
|
1681
1644
|
/**
|
|
1682
1645
|
* The HTTP path where the MCP server will be mounted
|
|
1683
1646
|
* @default '/mcp'
|
|
@@ -1852,6 +1815,6 @@ interface McpRouterOptions {
|
|
|
1852
1815
|
* app.listen(3000);
|
|
1853
1816
|
* ```
|
|
1854
1817
|
*/
|
|
1855
|
-
declare const createMcpRouter: (server: McpServer$1, options?: McpRouterOptions) => McpRouter;
|
|
1818
|
+
export declare const createMcpRouter: (server: McpServer$1, options?: McpRouterOptions) => McpRouter;
|
|
1856
1819
|
//#endregion
|
|
1857
|
-
export {
|
|
1820
|
+
export { type CreateToolGateOptions, type DeferToolsOptions, type DefineToolParams, type GateToolParams, InMemoryServerEventBus, type JsonObjectSchema, McpServer, type McpSurfaceBudget, type McpSurfaceReport, type McpSurfaceTool, type McpSurfaceViolation, type RegisterAppResourceParams, type RegisterToolsParams, type RegisteredAppResource, type ServerEvent, type ServerEventBus, type ServerNotifier, type Tool, type ToolCallContext, type ToolCallGate, type ToolGate, type ToolIdentity, type ToolMetaParams, type ToolSchema, type ToolSearchArgs, type UiResourceCsp, type UiResourceMeta, type UiResourcePermissions, type UiToolVisibility, z };
|
package/dist/index.mjs
CHANGED
|
@@ -779,7 +779,7 @@ var rankTools = ({
|
|
|
779
779
|
};
|
|
780
780
|
var summaryOf = tool => {
|
|
781
781
|
const [line] = (tool.summary ?? tool.description).trim().split("\n", 1);
|
|
782
|
-
return line.length > SUMMARY_MAX_LENGTH ? `${line.slice(0,
|
|
782
|
+
return line.length > SUMMARY_MAX_LENGTH ? `${line.slice(0, 159).trimEnd()}…` : line;
|
|
783
783
|
};
|
|
784
784
|
var editDistance = (a, b) => {
|
|
785
785
|
const row = Array.from({
|
|
@@ -953,14 +953,15 @@ var searchToolOf = ({
|
|
|
953
953
|
},
|
|
954
954
|
handler: async args => {
|
|
955
955
|
const limit = args.limit ?? searchLimit;
|
|
956
|
+
const matches = await searchTools({
|
|
957
|
+
query: args.query,
|
|
958
|
+
tag: args.tag,
|
|
959
|
+
limit,
|
|
960
|
+
tools: visibleTools()
|
|
961
|
+
});
|
|
956
962
|
return jsonResult({
|
|
957
963
|
data: {
|
|
958
|
-
tools: (
|
|
959
|
-
query: args.query,
|
|
960
|
-
tag: args.tag,
|
|
961
|
-
limit,
|
|
962
|
-
tools: visibleTools()
|
|
963
|
-
})).slice(0, limit).map(tool => {
|
|
964
|
+
tools: matches.slice(0, limit).map(tool => {
|
|
964
965
|
return {
|
|
965
966
|
name: tool.name,
|
|
966
967
|
summary: summaryOf(tool),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttoss/http-server-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.39.0",
|
|
4
4
|
"description": "Model Context Protocol (MCP) server integration for @ttoss/http-server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -35,20 +35,20 @@
|
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@modelcontextprotocol/node": "^2.1.1",
|
|
38
|
-
"@modelcontextprotocol/server": "^2.
|
|
39
|
-
"zod": "^4.
|
|
40
|
-
"@ttoss/
|
|
41
|
-
"@ttoss/
|
|
42
|
-
"@ttoss/
|
|
43
|
-
"@ttoss/
|
|
38
|
+
"@modelcontextprotocol/server": "^2.3.1",
|
|
39
|
+
"zod": "^4.6.7",
|
|
40
|
+
"@ttoss/http-server": "^0.14.1",
|
|
41
|
+
"@ttoss/i18n-core": "^0.9.1",
|
|
42
|
+
"@ttoss/http-server-auth": "^0.10.1",
|
|
43
|
+
"@ttoss/auth-core": "^0.20.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@modelcontextprotocol/client": "^2.3.1",
|
|
47
47
|
"@types/koa": "^3.0.3",
|
|
48
|
-
"jest": "^30.
|
|
49
|
-
"supertest": "^7.
|
|
50
|
-
"tsdown": "^0.
|
|
51
|
-
"@ttoss/config": "^
|
|
48
|
+
"jest": "^30.5.2",
|
|
49
|
+
"supertest": "^7.3.1",
|
|
50
|
+
"tsdown": "^0.23.1",
|
|
51
|
+
"@ttoss/config": "^3.0.0"
|
|
52
52
|
},
|
|
53
53
|
"publishConfig": {
|
|
54
54
|
"access": "public",
|