@ttoss/http-server-mcp 0.16.1 → 0.16.2
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 +1 -1
- package/dist/index.cjs +40 -14
- package/dist/index.d.cts +36 -6
- package/dist/index.d.mts +36 -6
- package/dist/index.mjs +40 -14
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -342,7 +342,7 @@ Both fields are optional. Omitting `resourceMetadataUrl` keeps the bare `Bearer`
|
|
|
342
342
|
|
|
343
343
|
## Issuing tokens for MCP clients
|
|
344
344
|
|
|
345
|
-
The `auth` option above covers the **resource-server** half of MCP authorization — it verifies tokens issued by an external authorization server (Cognito, Auth0, …). To make your own first-party server _issue_ the tokens an MCP client runs the full OAuth flow against, add the [`@ttoss/http-server-
|
|
345
|
+
The `auth` option above covers the **resource-server** half of MCP authorization — it verifies tokens issued by an external authorization server (Cognito, Auth0, …). To make your own first-party server _issue_ the tokens an MCP client runs the full OAuth flow against, add the [`@ttoss/http-server-auth`](https://ttoss.dev/docs/modules/packages/http-server-auth) plugin's `oauthServer()` and pair it with `createMcpRouter({ auth: { verifyToken } })` so one deployment both issues and verifies tokens. See the [OAuth Authorization Server](https://ttoss.dev/docs/engineering/guidelines/oauth-authorization-server) guideline.
|
|
346
346
|
|
|
347
347
|
## API Reference
|
|
348
348
|
|
package/dist/index.cjs
CHANGED
|
@@ -4,14 +4,29 @@ Object.defineProperty(exports, Symbol.toStringTag, {
|
|
|
4
4
|
});
|
|
5
5
|
let node_async_hooks = require("node:async_hooks");
|
|
6
6
|
let _modelcontextprotocol_sdk_server_streamableHttp_js = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
7
|
+
let _ttoss_auth_core_amazon_cognito = require("@ttoss/auth-core/amazon-cognito");
|
|
7
8
|
let _ttoss_http_server = require("@ttoss/http-server");
|
|
8
|
-
let
|
|
9
|
+
let _ttoss_http_server_auth = require("@ttoss/http-server-auth");
|
|
9
10
|
let zod = require("zod");
|
|
10
11
|
let _modelcontextprotocol_sdk_server_mcp_js = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
11
12
|
|
|
12
13
|
//#region src/index.ts
|
|
13
14
|
/** MCP lifecycle/discovery methods reachable before a client authenticates. */
|
|
14
15
|
var DEFAULT_PUBLIC_METHODS = ["initialize", "tools/list"];
|
|
16
|
+
/** Builds the token verifier from the MCP auth options. */
|
|
17
|
+
var buildVerifyToken = auth => {
|
|
18
|
+
if (auth.cognitoUserPool) {
|
|
19
|
+
const verifier = _ttoss_auth_core_amazon_cognito.CognitoJwtVerifier.create({
|
|
20
|
+
tokenUse: "access",
|
|
21
|
+
...auth.cognitoUserPool
|
|
22
|
+
});
|
|
23
|
+
return token => {
|
|
24
|
+
return verifier.verify(token);
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (auth.verifyToken) return auth.verifyToken;
|
|
28
|
+
throw new Error("McpAuthOptions requires either cognitoUserPool or verifyToken");
|
|
29
|
+
};
|
|
15
30
|
var requestContextStore = new node_async_hooks.AsyncLocalStorage();
|
|
16
31
|
/**
|
|
17
32
|
* Generic HTTP helper for use inside MCP tool handlers.
|
|
@@ -192,25 +207,36 @@ var createMcpRouter = (server, options = {}) => {
|
|
|
192
207
|
};
|
|
193
208
|
const router = new _ttoss_http_server.Router();
|
|
194
209
|
if (auth) {
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
210
|
+
const verifyToken = buildVerifyToken(auth);
|
|
211
|
+
const publicMethods = new Set(auth.publicMethods ?? DEFAULT_PUBLIC_METHODS);
|
|
212
|
+
const verify = (0, _ttoss_http_server_auth.authMiddleware)({
|
|
213
|
+
strategies: ["oauth"],
|
|
214
|
+
oauth: {
|
|
215
|
+
verify: token => {
|
|
216
|
+
return verifyToken(token);
|
|
217
|
+
},
|
|
218
|
+
requiredScopes: auth.requiredScopes
|
|
219
|
+
},
|
|
220
|
+
resourceMetadataUrl: auth.resourceMetadataUrl
|
|
221
|
+
});
|
|
222
|
+
router.use(path, async (ctx, next) => {
|
|
223
|
+
const method = ctx.request.body?.method;
|
|
224
|
+
if (publicMethods.has(method ?? "")) {
|
|
225
|
+
await next();
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
await verify(ctx, next);
|
|
229
|
+
});
|
|
230
|
+
if (auth.resourceServerUrl && auth.authorizationServerUrl) router.get("/.well-known/oauth-protected-resource", ctx => {
|
|
205
231
|
ctx.body = {
|
|
206
|
-
resource: resourceServerUrl,
|
|
207
|
-
authorization_servers: [authorizationServerUrl]
|
|
232
|
+
resource: auth.resourceServerUrl,
|
|
233
|
+
authorization_servers: [auth.authorizationServerUrl]
|
|
208
234
|
};
|
|
209
235
|
});
|
|
210
236
|
}
|
|
211
237
|
const handleWithContext = async (ctx, body) => {
|
|
212
238
|
const apiHeaders = getApiHeaders ? getApiHeaders(ctx) : {};
|
|
213
|
-
const identity = ctx.state.
|
|
239
|
+
const identity = ctx.state.user;
|
|
214
240
|
const runRequest = async transport => {
|
|
215
241
|
await transport.handleRequest(ctx.req, ctx.res, body);
|
|
216
242
|
ctx.respond = false;
|
package/dist/index.d.cts
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import { McpServer, McpServer as McpServer$1 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
4
|
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
5
5
|
import { Router } from "@ttoss/http-server";
|
|
6
|
-
import { OAuthVerifyOptions } from "@ttoss/http-server-oauth";
|
|
7
6
|
import accepts from "accepts";
|
|
8
7
|
import { AsyncLocalStorage } from "async_hooks";
|
|
9
8
|
import Cookies from "cookies";
|
|
@@ -668,12 +667,43 @@ declare namespace Application {
|
|
|
668
667
|
//#endregion
|
|
669
668
|
//#region src/index.d.ts
|
|
670
669
|
type Context$1 = Application.Context;
|
|
670
|
+
/** Amazon Cognito user pool configuration for JWT verification. */
|
|
671
|
+
interface CognitoUserPoolConfig {
|
|
672
|
+
/** The Cognito User Pool ID (e.g. `us-east-1_abc123`). */
|
|
673
|
+
userPoolId: string;
|
|
674
|
+
/**
|
|
675
|
+
* Which token type to verify.
|
|
676
|
+
* @default 'access'
|
|
677
|
+
*/
|
|
678
|
+
tokenUse?: 'access' | 'id';
|
|
679
|
+
/** The app client ID registered in the User Pool. */
|
|
680
|
+
clientId: string;
|
|
681
|
+
}
|
|
671
682
|
/**
|
|
672
|
-
* Authentication options for the MCP endpoint.
|
|
673
|
-
*
|
|
674
|
-
*
|
|
683
|
+
* Authentication options for the MCP endpoint. Verification runs through
|
|
684
|
+
* `@ttoss/http-server-auth`'s `oauth` strategy; supply either a Cognito user
|
|
685
|
+
* pool or a custom `verifyToken`.
|
|
675
686
|
*/
|
|
676
|
-
interface McpAuthOptions
|
|
687
|
+
interface McpAuthOptions {
|
|
688
|
+
/** Amazon Cognito user pool config; a `CognitoJwtVerifier` is built from it. */
|
|
689
|
+
cognitoUserPool?: CognitoUserPoolConfig;
|
|
690
|
+
/**
|
|
691
|
+
* Custom token verifier for non-Cognito providers (Auth0, Keycloak, your own
|
|
692
|
+
* JWTs, opaque tokens). Resolve with the verified payload, or throw to reject.
|
|
693
|
+
*/
|
|
694
|
+
verifyToken?: (token: string) => Promise<unknown>;
|
|
695
|
+
/** Scopes that must all be present on the token's `scope` claim, else `403`. */
|
|
696
|
+
requiredScopes?: string[];
|
|
697
|
+
/**
|
|
698
|
+
* JSON-RPC methods (read from `body.method`) that bypass verification.
|
|
699
|
+
* @default ['initialize', 'tools/list']
|
|
700
|
+
*/
|
|
701
|
+
publicMethods?: string[];
|
|
702
|
+
/**
|
|
703
|
+
* When set, a `401` carries `WWW-Authenticate: Bearer resource_metadata="…"`
|
|
704
|
+
* (RFC 9728) so MCP clients can discover the authorization server.
|
|
705
|
+
*/
|
|
706
|
+
resourceMetadataUrl?: string;
|
|
677
707
|
/**
|
|
678
708
|
* URL of this MCP server, surfaced in the OAuth Protected Resource Metadata
|
|
679
709
|
* response. Both this and `authorizationServerUrl` must be set to serve
|
|
@@ -974,4 +1004,4 @@ interface RegisterToolFromSchemaParams {
|
|
|
974
1004
|
*/
|
|
975
1005
|
declare const registerToolFromSchema: (server: McpServer$1, params: RegisterToolFromSchemaParams) => void;
|
|
976
1006
|
//#endregion
|
|
977
|
-
export { ApiCallOptions, JsonObjectSchema, McpAuthOptions, McpRouterOptions, McpServer, RegisterToolFromSchemaParams, apiCall, checkScopes, createMcpRouter, getIdentity, registerToolFromSchema, z };
|
|
1007
|
+
export { ApiCallOptions, CognitoUserPoolConfig, JsonObjectSchema, McpAuthOptions, McpRouterOptions, McpServer, RegisterToolFromSchemaParams, apiCall, checkScopes, createMcpRouter, getIdentity, registerToolFromSchema, z };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
import { Router } from "@ttoss/http-server";
|
|
4
|
-
import { OAuthVerifyOptions } from "@ttoss/http-server-oauth";
|
|
5
4
|
import { z } from "zod";
|
|
6
5
|
import { McpServer, McpServer as McpServer$1 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
6
|
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
@@ -668,12 +667,43 @@ declare namespace Application {
|
|
|
668
667
|
//#endregion
|
|
669
668
|
//#region src/index.d.ts
|
|
670
669
|
type Context$1 = Application.Context;
|
|
670
|
+
/** Amazon Cognito user pool configuration for JWT verification. */
|
|
671
|
+
interface CognitoUserPoolConfig {
|
|
672
|
+
/** The Cognito User Pool ID (e.g. `us-east-1_abc123`). */
|
|
673
|
+
userPoolId: string;
|
|
674
|
+
/**
|
|
675
|
+
* Which token type to verify.
|
|
676
|
+
* @default 'access'
|
|
677
|
+
*/
|
|
678
|
+
tokenUse?: 'access' | 'id';
|
|
679
|
+
/** The app client ID registered in the User Pool. */
|
|
680
|
+
clientId: string;
|
|
681
|
+
}
|
|
671
682
|
/**
|
|
672
|
-
* Authentication options for the MCP endpoint.
|
|
673
|
-
*
|
|
674
|
-
*
|
|
683
|
+
* Authentication options for the MCP endpoint. Verification runs through
|
|
684
|
+
* `@ttoss/http-server-auth`'s `oauth` strategy; supply either a Cognito user
|
|
685
|
+
* pool or a custom `verifyToken`.
|
|
675
686
|
*/
|
|
676
|
-
interface McpAuthOptions
|
|
687
|
+
interface McpAuthOptions {
|
|
688
|
+
/** Amazon Cognito user pool config; a `CognitoJwtVerifier` is built from it. */
|
|
689
|
+
cognitoUserPool?: CognitoUserPoolConfig;
|
|
690
|
+
/**
|
|
691
|
+
* Custom token verifier for non-Cognito providers (Auth0, Keycloak, your own
|
|
692
|
+
* JWTs, opaque tokens). Resolve with the verified payload, or throw to reject.
|
|
693
|
+
*/
|
|
694
|
+
verifyToken?: (token: string) => Promise<unknown>;
|
|
695
|
+
/** Scopes that must all be present on the token's `scope` claim, else `403`. */
|
|
696
|
+
requiredScopes?: string[];
|
|
697
|
+
/**
|
|
698
|
+
* JSON-RPC methods (read from `body.method`) that bypass verification.
|
|
699
|
+
* @default ['initialize', 'tools/list']
|
|
700
|
+
*/
|
|
701
|
+
publicMethods?: string[];
|
|
702
|
+
/**
|
|
703
|
+
* When set, a `401` carries `WWW-Authenticate: Bearer resource_metadata="…"`
|
|
704
|
+
* (RFC 9728) so MCP clients can discover the authorization server.
|
|
705
|
+
*/
|
|
706
|
+
resourceMetadataUrl?: string;
|
|
677
707
|
/**
|
|
678
708
|
* URL of this MCP server, surfaced in the OAuth Protected Resource Metadata
|
|
679
709
|
* response. Both this and `authorizationServerUrl` must be set to serve
|
|
@@ -974,4 +1004,4 @@ interface RegisterToolFromSchemaParams {
|
|
|
974
1004
|
*/
|
|
975
1005
|
declare const registerToolFromSchema: (server: McpServer$1, params: RegisterToolFromSchemaParams) => void;
|
|
976
1006
|
//#endregion
|
|
977
|
-
export { ApiCallOptions, JsonObjectSchema, McpAuthOptions, McpRouterOptions, McpServer, RegisterToolFromSchemaParams, apiCall, checkScopes, createMcpRouter, getIdentity, registerToolFromSchema, z };
|
|
1007
|
+
export { ApiCallOptions, CognitoUserPoolConfig, JsonObjectSchema, McpAuthOptions, McpRouterOptions, McpServer, RegisterToolFromSchemaParams, apiCall, checkScopes, createMcpRouter, getIdentity, registerToolFromSchema, z };
|
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,29 @@
|
|
|
1
1
|
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
2
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
3
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
4
|
+
import { CognitoJwtVerifier } from "@ttoss/auth-core/amazon-cognito";
|
|
4
5
|
import { Router } from "@ttoss/http-server";
|
|
5
|
-
import {
|
|
6
|
+
import { authMiddleware } from "@ttoss/http-server-auth";
|
|
6
7
|
import { z, z as z$1 } from "zod";
|
|
7
8
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
9
|
|
|
9
10
|
//#region src/index.ts
|
|
10
11
|
/** MCP lifecycle/discovery methods reachable before a client authenticates. */
|
|
11
12
|
var DEFAULT_PUBLIC_METHODS = ["initialize", "tools/list"];
|
|
13
|
+
/** Builds the token verifier from the MCP auth options. */
|
|
14
|
+
var buildVerifyToken = auth => {
|
|
15
|
+
if (auth.cognitoUserPool) {
|
|
16
|
+
const verifier = CognitoJwtVerifier.create({
|
|
17
|
+
tokenUse: "access",
|
|
18
|
+
...auth.cognitoUserPool
|
|
19
|
+
});
|
|
20
|
+
return token => {
|
|
21
|
+
return verifier.verify(token);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (auth.verifyToken) return auth.verifyToken;
|
|
25
|
+
throw new Error("McpAuthOptions requires either cognitoUserPool or verifyToken");
|
|
26
|
+
};
|
|
12
27
|
var requestContextStore = new AsyncLocalStorage();
|
|
13
28
|
/**
|
|
14
29
|
* Generic HTTP helper for use inside MCP tool handlers.
|
|
@@ -189,25 +204,36 @@ var createMcpRouter = (server, options = {}) => {
|
|
|
189
204
|
};
|
|
190
205
|
const router = new Router();
|
|
191
206
|
if (auth) {
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
207
|
+
const verifyToken = buildVerifyToken(auth);
|
|
208
|
+
const publicMethods = new Set(auth.publicMethods ?? DEFAULT_PUBLIC_METHODS);
|
|
209
|
+
const verify = authMiddleware({
|
|
210
|
+
strategies: ["oauth"],
|
|
211
|
+
oauth: {
|
|
212
|
+
verify: token => {
|
|
213
|
+
return verifyToken(token);
|
|
214
|
+
},
|
|
215
|
+
requiredScopes: auth.requiredScopes
|
|
216
|
+
},
|
|
217
|
+
resourceMetadataUrl: auth.resourceMetadataUrl
|
|
218
|
+
});
|
|
219
|
+
router.use(path, async (ctx, next) => {
|
|
220
|
+
const method = ctx.request.body?.method;
|
|
221
|
+
if (publicMethods.has(method ?? "")) {
|
|
222
|
+
await next();
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
await verify(ctx, next);
|
|
226
|
+
});
|
|
227
|
+
if (auth.resourceServerUrl && auth.authorizationServerUrl) router.get("/.well-known/oauth-protected-resource", ctx => {
|
|
202
228
|
ctx.body = {
|
|
203
|
-
resource: resourceServerUrl,
|
|
204
|
-
authorization_servers: [authorizationServerUrl]
|
|
229
|
+
resource: auth.resourceServerUrl,
|
|
230
|
+
authorization_servers: [auth.authorizationServerUrl]
|
|
205
231
|
};
|
|
206
232
|
});
|
|
207
233
|
}
|
|
208
234
|
const handleWithContext = async (ctx, body) => {
|
|
209
235
|
const apiHeaders = getApiHeaders ? getApiHeaders(ctx) : {};
|
|
210
|
-
const identity = ctx.state.
|
|
236
|
+
const identity = ctx.state.user;
|
|
211
237
|
const runRequest = async transport => {
|
|
212
238
|
await transport.handleRequest(ctx.req, ctx.res, body);
|
|
213
239
|
ctx.respond = false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttoss/http-server-mcp",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.2",
|
|
4
4
|
"description": "Model Context Protocol (MCP) server integration for @ttoss/http-server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -35,8 +35,9 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
37
37
|
"zod": "^4.4.3",
|
|
38
|
-
"@ttoss/
|
|
39
|
-
"@ttoss/http-server
|
|
38
|
+
"@ttoss/auth-core": "^0.6.2",
|
|
39
|
+
"@ttoss/http-server": "^0.7.1",
|
|
40
|
+
"@ttoss/http-server-auth": "^0.3.2"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"@types/koa": "^3.0.3",
|