@ttoss/http-server-mcp 0.16.5 → 0.17.1
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 +7 -4
- package/dist/index.cjs +10 -2
- package/dist/index.d.cts +8 -2
- package/dist/index.d.mts +8 -2
- package/dist/index.mjs +10 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -641,21 +641,23 @@ This package implements the [Model Context Protocol](https://spec.modelcontextpr
|
|
|
641
641
|
|
|
642
642
|
## AWS Lambda Deployment
|
|
643
643
|
|
|
644
|
-
The default **stateless** mode (see [Stateless vs stateful mode](#stateless-vs-stateful-mode)) is built for serverless: a fresh transport is created per request, nothing is kept in memory between invocations, and responses are plain JSON (no SSE) — exactly the request/response shape API Gateway and Lambda Function URLs expect.
|
|
644
|
+
The default **stateless** mode (see [Stateless vs stateful mode](#stateless-vs-stateful-mode)) is built for serverless: a fresh transport is created per request, nothing is kept in memory between invocations, and responses are plain JSON (no SSE) — exactly the request/response shape API Gateway and Lambda Function URLs expect.
|
|
645
|
+
|
|
646
|
+
Use [`@ttoss/http-server-serverless`](https://github.com/ttoss/ttoss/tree/main/packages/http-server-serverless) as the Lambda adapter. It wraps `serverless-http` and additionally populates `req.rawHeaders` from the API Gateway event before the request reaches Koa. Without this step, `@hono/node-server` — used internally by the MCP transport — drops all headers (including `Accept`) and every `initialize` request returns HTTP 406.
|
|
645
647
|
|
|
646
648
|
```mermaid
|
|
647
649
|
flowchart LR
|
|
648
650
|
Client[MCP Client] -->|POST /mcp| GW[API Gateway / Function URL]
|
|
649
651
|
GW --> L[Lambda]
|
|
650
652
|
subgraph L[Lambda]
|
|
651
|
-
H[
|
|
653
|
+
H[toLambdaHandler] -->|rawHeaders populated| App[Koa App + createMcpRouter]
|
|
652
654
|
end
|
|
653
655
|
```
|
|
654
656
|
|
|
655
657
|
```typescript
|
|
656
|
-
import serverless from 'serverless-http';
|
|
657
658
|
import { App, bodyParser } from '@ttoss/http-server';
|
|
658
659
|
import { createMcpRouter, McpServer, z } from '@ttoss/http-server-mcp';
|
|
660
|
+
import { toLambdaHandler } from '@ttoss/http-server-serverless';
|
|
659
661
|
|
|
660
662
|
const mcpServer = new McpServer({ name: 'my-mcp-server', version: '1.0.0' });
|
|
661
663
|
|
|
@@ -675,7 +677,7 @@ app.use(bodyParser());
|
|
|
675
677
|
// Stateless by default — no sessionIdGenerator
|
|
676
678
|
app.use(createMcpRouter(mcpServer).routes());
|
|
677
679
|
|
|
678
|
-
export const handler =
|
|
680
|
+
export const handler = toLambdaHandler(app);
|
|
679
681
|
```
|
|
680
682
|
|
|
681
683
|
Keep the following in mind:
|
|
@@ -689,6 +691,7 @@ Keep the following in mind:
|
|
|
689
691
|
## Related Packages
|
|
690
692
|
|
|
691
693
|
- [@ttoss/http-server](https://ttoss.dev/docs/modules/packages/http-server) - HTTP server foundation
|
|
694
|
+
- [@ttoss/http-server-serverless](https://github.com/ttoss/ttoss/tree/main/packages/http-server-serverless) - AWS Lambda adapter (required for MCP on Lambda)
|
|
692
695
|
- [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/sdk) - MCP SDK
|
|
693
696
|
|
|
694
697
|
## Resources
|
package/dist/index.cjs
CHANGED
|
@@ -126,7 +126,9 @@ var getIdentity = () => {
|
|
|
126
126
|
* Throws if any scope is missing — the MCP SDK catches this and returns a
|
|
127
127
|
* tool error to the client. Use inside tool handlers for per-tool authorization.
|
|
128
128
|
*
|
|
129
|
-
*
|
|
129
|
+
* Accepts either `scope: string` (space-separated, standard JWT claim) or
|
|
130
|
+
* `scopes: string[]` from `verifyToken`. If neither is present and `required`
|
|
131
|
+
* is non-empty, throws with a descriptive message instead of a silent 403.
|
|
130
132
|
*
|
|
131
133
|
* @example
|
|
132
134
|
* ```typescript
|
|
@@ -137,7 +139,13 @@ var getIdentity = () => {
|
|
|
137
139
|
* ```
|
|
138
140
|
*/
|
|
139
141
|
var checkScopes = required => {
|
|
140
|
-
const
|
|
142
|
+
const identity = getIdentity();
|
|
143
|
+
let scopeString = null;
|
|
144
|
+
if (typeof identity?.scope === "string") scopeString = identity.scope;else if (Array.isArray(identity?.scopes) && identity.scopes.every(s => {
|
|
145
|
+
return typeof s === "string";
|
|
146
|
+
})) scopeString = identity.scopes.join(" ");
|
|
147
|
+
if (scopeString === null && required.length > 0) throw new Error(`verifyToken returned no scope/scopes but requiredScopes is set (${required.join(", ")}). Return either scope: string or scopes: string[] from verifyToken.`);
|
|
148
|
+
const tokenScopes = scopeString ? scopeString.split(" ") : [];
|
|
141
149
|
if (required.filter(s => {
|
|
142
150
|
return !tokenScopes.includes(s);
|
|
143
151
|
}).length > 0) throw new Error(`Insufficient scopes. Required: ${required.join(", ")}`);
|
package/dist/index.d.cts
CHANGED
|
@@ -692,7 +692,11 @@ interface McpAuthOptions {
|
|
|
692
692
|
* JWTs, opaque tokens). Resolve with the verified payload, or throw to reject.
|
|
693
693
|
*/
|
|
694
694
|
verifyToken?: (token: string) => Promise<unknown>;
|
|
695
|
-
/**
|
|
695
|
+
/**
|
|
696
|
+
* Scopes that must all be present on the token, else `403`.
|
|
697
|
+
* `verifyToken` may return either `scope: string` (space-separated) or
|
|
698
|
+
* `scopes: string[]`; both are normalised internally.
|
|
699
|
+
*/
|
|
696
700
|
requiredScopes?: string[];
|
|
697
701
|
/**
|
|
698
702
|
* JSON-RPC methods (read from `body.method`) that bypass verification.
|
|
@@ -793,7 +797,9 @@ declare const getIdentity: () => unknown;
|
|
|
793
797
|
* Throws if any scope is missing — the MCP SDK catches this and returns a
|
|
794
798
|
* tool error to the client. Use inside tool handlers for per-tool authorization.
|
|
795
799
|
*
|
|
796
|
-
*
|
|
800
|
+
* Accepts either `scope: string` (space-separated, standard JWT claim) or
|
|
801
|
+
* `scopes: string[]` from `verifyToken`. If neither is present and `required`
|
|
802
|
+
* is non-empty, throws with a descriptive message instead of a silent 403.
|
|
797
803
|
*
|
|
798
804
|
* @example
|
|
799
805
|
* ```typescript
|
package/dist/index.d.mts
CHANGED
|
@@ -692,7 +692,11 @@ interface McpAuthOptions {
|
|
|
692
692
|
* JWTs, opaque tokens). Resolve with the verified payload, or throw to reject.
|
|
693
693
|
*/
|
|
694
694
|
verifyToken?: (token: string) => Promise<unknown>;
|
|
695
|
-
/**
|
|
695
|
+
/**
|
|
696
|
+
* Scopes that must all be present on the token, else `403`.
|
|
697
|
+
* `verifyToken` may return either `scope: string` (space-separated) or
|
|
698
|
+
* `scopes: string[]`; both are normalised internally.
|
|
699
|
+
*/
|
|
696
700
|
requiredScopes?: string[];
|
|
697
701
|
/**
|
|
698
702
|
* JSON-RPC methods (read from `body.method`) that bypass verification.
|
|
@@ -793,7 +797,9 @@ declare const getIdentity: () => unknown;
|
|
|
793
797
|
* Throws if any scope is missing — the MCP SDK catches this and returns a
|
|
794
798
|
* tool error to the client. Use inside tool handlers for per-tool authorization.
|
|
795
799
|
*
|
|
796
|
-
*
|
|
800
|
+
* Accepts either `scope: string` (space-separated, standard JWT claim) or
|
|
801
|
+
* `scopes: string[]` from `verifyToken`. If neither is present and `required`
|
|
802
|
+
* is non-empty, throws with a descriptive message instead of a silent 403.
|
|
797
803
|
*
|
|
798
804
|
* @example
|
|
799
805
|
* ```typescript
|
package/dist/index.mjs
CHANGED
|
@@ -123,7 +123,9 @@ var getIdentity = () => {
|
|
|
123
123
|
* Throws if any scope is missing — the MCP SDK catches this and returns a
|
|
124
124
|
* tool error to the client. Use inside tool handlers for per-tool authorization.
|
|
125
125
|
*
|
|
126
|
-
*
|
|
126
|
+
* Accepts either `scope: string` (space-separated, standard JWT claim) or
|
|
127
|
+
* `scopes: string[]` from `verifyToken`. If neither is present and `required`
|
|
128
|
+
* is non-empty, throws with a descriptive message instead of a silent 403.
|
|
127
129
|
*
|
|
128
130
|
* @example
|
|
129
131
|
* ```typescript
|
|
@@ -134,7 +136,13 @@ var getIdentity = () => {
|
|
|
134
136
|
* ```
|
|
135
137
|
*/
|
|
136
138
|
var checkScopes = required => {
|
|
137
|
-
const
|
|
139
|
+
const identity = getIdentity();
|
|
140
|
+
let scopeString = null;
|
|
141
|
+
if (typeof identity?.scope === "string") scopeString = identity.scope;else if (Array.isArray(identity?.scopes) && identity.scopes.every(s => {
|
|
142
|
+
return typeof s === "string";
|
|
143
|
+
})) scopeString = identity.scopes.join(" ");
|
|
144
|
+
if (scopeString === null && required.length > 0) throw new Error(`verifyToken returned no scope/scopes but requiredScopes is set (${required.join(", ")}). Return either scope: string or scopes: string[] from verifyToken.`);
|
|
145
|
+
const tokenScopes = scopeString ? scopeString.split(" ") : [];
|
|
138
146
|
if (required.filter(s => {
|
|
139
147
|
return !tokenScopes.includes(s);
|
|
140
148
|
}).length > 0) throw new Error(`Insufficient scopes. Required: ${required.join(", ")}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttoss/http-server-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"description": "Model Context Protocol (MCP) server integration for @ttoss/http-server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
37
37
|
"zod": "^4.4.3",
|
|
38
38
|
"@ttoss/auth-core": "^0.7.0",
|
|
39
|
-
"@ttoss/http-server-auth": "^0.3.
|
|
39
|
+
"@ttoss/http-server-auth": "^0.3.4",
|
|
40
40
|
"@ttoss/http-server": "^0.7.1"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|