@aws/run-mcp-servers-with-aws-lambda 0.2.1 → 0.2.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/dist/handlers/api_gateway_proxy_event_handler.d.ts +31 -0
- package/dist/handlers/api_gateway_proxy_event_handler.js +43 -0
- package/dist/handlers/api_gateway_proxy_event_v2_handler.d.ts +30 -0
- package/dist/handlers/api_gateway_proxy_event_v2_handler.js +42 -0
- package/dist/handlers/handlers.test.js +629 -0
- package/dist/handlers/index.d.ts +4 -0
- package/dist/handlers/index.js +3 -0
- package/dist/handlers/lambda_function_url_event_handler.d.ts +30 -0
- package/dist/handlers/lambda_function_url_event_handler.js +42 -0
- package/dist/handlers/request_handler.d.ts +43 -0
- package/dist/handlers/request_handler.js +1 -0
- package/dist/handlers/streamable_http_handler.d.ts +81 -0
- package/dist/handlers/streamable_http_handler.js +234 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/server-adapter/index.d.ts +2 -4
- package/dist/server-adapter/index.js +2 -110
- package/dist/server-adapter/stdio_server_adapter.d.ts +17 -0
- package/dist/server-adapter/stdio_server_adapter.js +118 -0
- package/dist/server-adapter/stdio_server_adapter.test.d.ts +1 -0
- package/dist/server-adapter/{index.test.js → stdio_server_adapter.test.js} +1 -1
- package/dist/server-adapter/stdio_server_adapter_request_handler.d.ts +26 -0
- package/dist/server-adapter/stdio_server_adapter_request_handler.js +66 -0
- package/dist/server-adapter/stdio_server_adapter_request_handler.test.d.ts +1 -0
- package/dist/server-adapter/stdio_server_adapter_request_handler.test.js +148 -0
- package/package.json +12 -12
- /package/dist/{server-adapter/index.test.d.ts → handlers/handlers.test.d.ts} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ErrorCode, } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
-
import { stdioServerAdapter } from './
|
|
2
|
+
import { stdioServerAdapter } from './stdio_server_adapter.js';
|
|
3
3
|
const serverParameters = {
|
|
4
4
|
command: 'npx',
|
|
5
5
|
args: ['tsx', 'test-stdio-server/echo_server.ts'],
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Context } from 'aws-lambda';
|
|
2
|
+
import { StdioServerParameters } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
3
|
+
import { JSONRPCRequest, JSONRPCResponse, JSONRPCError } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
import { RequestHandler } from '../handlers/request_handler.js';
|
|
5
|
+
/**
|
|
6
|
+
* Generic Request Handler for MCP Stdio Server Adapter
|
|
7
|
+
*
|
|
8
|
+
* This class provides a reusable implementation of the RequestHandler interface
|
|
9
|
+
* that delegates JSON-RPC requests to an MCP server via the stdio server adapter.
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const serverParams = {
|
|
14
|
+
* command: "node",
|
|
15
|
+
* args: ["path/to/mcp-server.js", "--option", "value"]
|
|
16
|
+
* };
|
|
17
|
+
*
|
|
18
|
+
* const handler = new StdioServerAdapterRequestHandler(serverParams);
|
|
19
|
+
* const streamableHandler = new StreamableHttpHandler(handler);
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare class StdioServerAdapterRequestHandler implements RequestHandler {
|
|
23
|
+
private serverParams;
|
|
24
|
+
constructor(serverParams: StdioServerParameters);
|
|
25
|
+
handleRequest(request: JSONRPCRequest, context: Context): Promise<JSONRPCResponse | JSONRPCError>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { isJSONRPCResponse, isJSONRPCError, ErrorCode, } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import { createLogger, format, transports } from 'winston';
|
|
3
|
+
import { stdioServerAdapter } from './stdio_server_adapter.js';
|
|
4
|
+
const logger = createLogger({
|
|
5
|
+
level: process.env.LOG_LEVEL?.toLowerCase() || 'info',
|
|
6
|
+
format: format.simple(),
|
|
7
|
+
transports: [new transports.Console()],
|
|
8
|
+
});
|
|
9
|
+
/**
|
|
10
|
+
* Generic Request Handler for MCP Stdio Server Adapter
|
|
11
|
+
*
|
|
12
|
+
* This class provides a reusable implementation of the RequestHandler interface
|
|
13
|
+
* that delegates JSON-RPC requests to an MCP server via the stdio server adapter.
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const serverParams = {
|
|
18
|
+
* command: "node",
|
|
19
|
+
* args: ["path/to/mcp-server.js", "--option", "value"]
|
|
20
|
+
* };
|
|
21
|
+
*
|
|
22
|
+
* const handler = new StdioServerAdapterRequestHandler(serverParams);
|
|
23
|
+
* const streamableHandler = new StreamableHttpHandler(handler);
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export class StdioServerAdapterRequestHandler {
|
|
27
|
+
serverParams;
|
|
28
|
+
constructor(serverParams) {
|
|
29
|
+
this.serverParams = serverParams;
|
|
30
|
+
}
|
|
31
|
+
async handleRequest(request, context) {
|
|
32
|
+
try {
|
|
33
|
+
// Call the MCP server adapter with the individual request
|
|
34
|
+
const mcpResponse = await stdioServerAdapter(this.serverParams, request, context);
|
|
35
|
+
// The stdioServerAdapter should return JSONRPCResponse or JSONRPCError for requests
|
|
36
|
+
if (isJSONRPCResponse(mcpResponse) || isJSONRPCError(mcpResponse)) {
|
|
37
|
+
return mcpResponse;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// Unexpected response format - return internal server error
|
|
41
|
+
logger.error('Unexpected response format from stdioServerAdapter:', mcpResponse);
|
|
42
|
+
return {
|
|
43
|
+
jsonrpc: '2.0',
|
|
44
|
+
error: {
|
|
45
|
+
code: ErrorCode.InternalError,
|
|
46
|
+
message: 'Internal error: Unexpected response format from MCP server',
|
|
47
|
+
data: 'Expected JSONRPCResponse or JSONRPCError',
|
|
48
|
+
},
|
|
49
|
+
id: request.id,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
// Return JSON-RPC error response
|
|
55
|
+
return {
|
|
56
|
+
jsonrpc: '2.0',
|
|
57
|
+
error: {
|
|
58
|
+
code: ErrorCode.InternalError,
|
|
59
|
+
message: 'Internal error',
|
|
60
|
+
data: error instanceof Error ? error.message : 'Unknown error',
|
|
61
|
+
},
|
|
62
|
+
id: request.id,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { ErrorCode, } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import { StdioServerAdapterRequestHandler } from './stdio_server_adapter_request_handler.js';
|
|
3
|
+
import * as stdioServerAdapter from './stdio_server_adapter.js';
|
|
4
|
+
// Mock the stdioServerAdapter function
|
|
5
|
+
jest.mock('./stdio_server_adapter.js', () => ({
|
|
6
|
+
stdioServerAdapter: jest.fn(),
|
|
7
|
+
}));
|
|
8
|
+
const mockStdioServerAdapter = stdioServerAdapter.stdioServerAdapter;
|
|
9
|
+
const mockServerParams = {
|
|
10
|
+
command: 'node',
|
|
11
|
+
args: ['test-server.js'],
|
|
12
|
+
};
|
|
13
|
+
const mockContext = {
|
|
14
|
+
callbackWaitsForEmptyEventLoop: true,
|
|
15
|
+
functionName: 'test-function',
|
|
16
|
+
functionVersion: '1',
|
|
17
|
+
invokedFunctionArn: 'test-arn',
|
|
18
|
+
memoryLimitInMB: '128',
|
|
19
|
+
awsRequestId: 'test-id',
|
|
20
|
+
logGroupName: 'test-group',
|
|
21
|
+
logStreamName: 'test-stream',
|
|
22
|
+
getRemainingTimeInMillis: () => 1000,
|
|
23
|
+
done: () => { },
|
|
24
|
+
fail: () => { },
|
|
25
|
+
succeed: () => { },
|
|
26
|
+
};
|
|
27
|
+
describe('StdioServerAdapterRequestHandler', () => {
|
|
28
|
+
let handler;
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
handler = new StdioServerAdapterRequestHandler(mockServerParams);
|
|
31
|
+
jest.clearAllMocks();
|
|
32
|
+
});
|
|
33
|
+
describe('handleRequest', () => {
|
|
34
|
+
test('should return JSONRPCResponse when stdioServerAdapter returns valid response', async () => {
|
|
35
|
+
const request = {
|
|
36
|
+
jsonrpc: '2.0',
|
|
37
|
+
id: 1,
|
|
38
|
+
method: 'test',
|
|
39
|
+
params: { arg: 'value' },
|
|
40
|
+
};
|
|
41
|
+
const expectedResponse = {
|
|
42
|
+
jsonrpc: '2.0',
|
|
43
|
+
id: 1,
|
|
44
|
+
result: { success: true },
|
|
45
|
+
};
|
|
46
|
+
mockStdioServerAdapter.mockResolvedValue(expectedResponse);
|
|
47
|
+
const result = await handler.handleRequest(request, mockContext);
|
|
48
|
+
expect(mockStdioServerAdapter).toHaveBeenCalledWith(mockServerParams, request, mockContext);
|
|
49
|
+
expect(result).toEqual(expectedResponse);
|
|
50
|
+
});
|
|
51
|
+
test('should return JSONRPCError when stdioServerAdapter returns error', async () => {
|
|
52
|
+
const request = {
|
|
53
|
+
jsonrpc: '2.0',
|
|
54
|
+
id: 1,
|
|
55
|
+
method: 'test',
|
|
56
|
+
};
|
|
57
|
+
const expectedError = {
|
|
58
|
+
jsonrpc: '2.0',
|
|
59
|
+
error: {
|
|
60
|
+
code: ErrorCode.MethodNotFound,
|
|
61
|
+
message: 'Method not found',
|
|
62
|
+
},
|
|
63
|
+
id: 1,
|
|
64
|
+
};
|
|
65
|
+
mockStdioServerAdapter.mockResolvedValue(expectedError);
|
|
66
|
+
const result = await handler.handleRequest(request, mockContext);
|
|
67
|
+
expect(mockStdioServerAdapter).toHaveBeenCalledWith(mockServerParams, request, mockContext);
|
|
68
|
+
expect(result).toEqual(expectedError);
|
|
69
|
+
});
|
|
70
|
+
test('should return internal error when stdioServerAdapter returns unexpected format', async () => {
|
|
71
|
+
const request = {
|
|
72
|
+
jsonrpc: '2.0',
|
|
73
|
+
id: 1,
|
|
74
|
+
method: 'test',
|
|
75
|
+
};
|
|
76
|
+
const unexpectedResponse = { invalid: 'response' };
|
|
77
|
+
mockStdioServerAdapter.mockResolvedValue(unexpectedResponse);
|
|
78
|
+
const result = await handler.handleRequest(request, mockContext);
|
|
79
|
+
expect(result).toEqual({
|
|
80
|
+
jsonrpc: '2.0',
|
|
81
|
+
error: {
|
|
82
|
+
code: ErrorCode.InternalError,
|
|
83
|
+
message: 'Internal error: Unexpected response format from MCP server',
|
|
84
|
+
data: 'Expected JSONRPCResponse or JSONRPCError',
|
|
85
|
+
},
|
|
86
|
+
id: 1,
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
test('should return internal error when stdioServerAdapter throws exception', async () => {
|
|
90
|
+
const request = {
|
|
91
|
+
jsonrpc: '2.0',
|
|
92
|
+
id: 1,
|
|
93
|
+
method: 'test',
|
|
94
|
+
};
|
|
95
|
+
const error = new Error('Connection failed');
|
|
96
|
+
mockStdioServerAdapter.mockRejectedValue(error);
|
|
97
|
+
const result = await handler.handleRequest(request, mockContext);
|
|
98
|
+
expect(result).toEqual({
|
|
99
|
+
jsonrpc: '2.0',
|
|
100
|
+
error: {
|
|
101
|
+
code: ErrorCode.InternalError,
|
|
102
|
+
message: 'Internal error',
|
|
103
|
+
data: 'Connection failed',
|
|
104
|
+
},
|
|
105
|
+
id: 1,
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
test('should handle non-Error exceptions', async () => {
|
|
109
|
+
const request = {
|
|
110
|
+
jsonrpc: '2.0',
|
|
111
|
+
id: 1,
|
|
112
|
+
method: 'test',
|
|
113
|
+
};
|
|
114
|
+
mockStdioServerAdapter.mockRejectedValue('String error');
|
|
115
|
+
const result = await handler.handleRequest(request, mockContext);
|
|
116
|
+
expect(result).toEqual({
|
|
117
|
+
jsonrpc: '2.0',
|
|
118
|
+
error: {
|
|
119
|
+
code: ErrorCode.InternalError,
|
|
120
|
+
message: 'Internal error',
|
|
121
|
+
data: 'Unknown error',
|
|
122
|
+
},
|
|
123
|
+
id: 1,
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
test('should pass server parameters correctly to stdioServerAdapter', async () => {
|
|
127
|
+
const customServerParams = {
|
|
128
|
+
command: 'python',
|
|
129
|
+
args: ['custom-server.py', '--port', '8080'],
|
|
130
|
+
env: { NODE_ENV: 'test' },
|
|
131
|
+
};
|
|
132
|
+
const customHandler = new StdioServerAdapterRequestHandler(customServerParams);
|
|
133
|
+
const request = {
|
|
134
|
+
jsonrpc: '2.0',
|
|
135
|
+
id: 1,
|
|
136
|
+
method: 'test',
|
|
137
|
+
};
|
|
138
|
+
const response = {
|
|
139
|
+
jsonrpc: '2.0',
|
|
140
|
+
id: 1,
|
|
141
|
+
result: {},
|
|
142
|
+
};
|
|
143
|
+
mockStdioServerAdapter.mockResolvedValue(response);
|
|
144
|
+
await customHandler.handleRequest(request, mockContext);
|
|
145
|
+
expect(mockStdioServerAdapter).toHaveBeenCalledWith(customServerParams, request, mockContext);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws/run-mcp-servers-with-aws-lambda",
|
|
3
3
|
"description": "Run Model Context Protocol (MCP) servers with AWS Lambda",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"author": {
|
|
@@ -39,22 +39,22 @@
|
|
|
39
39
|
"dist"
|
|
40
40
|
],
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@eslint/js": "^9.
|
|
43
|
-
"@tsconfig/recommended": "^1.0.
|
|
44
|
-
"@types/jest": "^
|
|
45
|
-
"@types/node": "^
|
|
42
|
+
"@eslint/js": "^9.30.1",
|
|
43
|
+
"@tsconfig/recommended": "^1.0.10",
|
|
44
|
+
"@types/jest": "^30.0.0",
|
|
45
|
+
"@types/node": "^24.0.10",
|
|
46
46
|
"aws-sdk-client-mock": "^4.1.0",
|
|
47
47
|
"aws-sdk-client-mock-jest": "^4.1.0",
|
|
48
|
-
"eslint": "^9.
|
|
49
|
-
"jest": "^
|
|
50
|
-
"ts-jest": "^29.
|
|
51
|
-
"tsx": "^4.
|
|
48
|
+
"eslint": "^9.30.1",
|
|
49
|
+
"jest": "^30.0.4",
|
|
50
|
+
"ts-jest": "^29.4.0",
|
|
51
|
+
"tsx": "^4.20.3",
|
|
52
52
|
"typescript": "^5.8.3",
|
|
53
|
-
"typescript-eslint": "^8.
|
|
53
|
+
"typescript-eslint": "^8.35.1"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@aws-sdk/client-lambda": "^3.
|
|
57
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
56
|
+
"@aws-sdk/client-lambda": "^3.840.0",
|
|
57
|
+
"@modelcontextprotocol/sdk": "^1.15.0",
|
|
58
58
|
"@types/aws-lambda": "^8.10.149",
|
|
59
59
|
"winston": "^3.17.0"
|
|
60
60
|
}
|
|
File without changes
|