@ttoss/http-server-mcp 0.3.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024, Terezinha Tech Operations (ttoss)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,214 @@
1
+ # @ttoss/http-server-mcp
2
+
3
+ [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server integration for [@ttoss/http-server](https://ttoss.dev/docs/modules/packages/http-server).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @ttoss/http-server-mcp
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { App, bodyParser, cors } from '@ttoss/http-server';
15
+ import {
16
+ createMcpRouter,
17
+ Server as McpServer,
18
+ z,
19
+ } from '@ttoss/http-server-mcp';
20
+
21
+ // Create MCP server
22
+ const mcpServer = new McpServer({
23
+ name: 'my-mcp-server',
24
+ version: '1.0.0',
25
+ });
26
+
27
+ // Register tools
28
+ mcpServer.registerTool(
29
+ 'get-weather',
30
+ {
31
+ description: 'Get weather information for a location',
32
+ inputSchema: {
33
+ location: z.string().describe('City name'),
34
+ },
35
+ },
36
+ async ({ location }) => ({
37
+ content: [
38
+ {
39
+ type: 'text',
40
+ text: `Weather in ${location}: Sunny, 72°F`,
41
+ },
42
+ ],
43
+ })
44
+ );
45
+
46
+ // Create HTTP server
47
+ const app = new App();
48
+ app.use(cors());
49
+ app.use(bodyParser());
50
+
51
+ // Mount MCP router
52
+ const mcpRouter = createMcpRouter(mcpServer);
53
+ app.use(mcpRouter.routes());
54
+
55
+ app.listen(3000, () => {
56
+ console.log('MCP server running on http://localhost:3000/mcp');
57
+ });
58
+ ```
59
+
60
+ ## API Reference
61
+
62
+ ### `createMcpRouter(server, options?)`
63
+
64
+ Creates a Koa router configured to handle MCP protocol requests.
65
+
66
+ **Parameters:**
67
+
68
+ - `server` (`McpServer`) - MCP server instance with registered tools and resources
69
+ - `options` (`McpRouterOptions`) - Optional configuration
70
+ - `path` (`string`) - HTTP path for MCP endpoint (default: `'/mcp'`)
71
+ - `sessionIdGenerator` (`() => string`) - Session ID generator for stateful servers (default: `undefined` for stateless)
72
+
73
+ **Returns:** `Router` - Koa router instance
74
+
75
+ ## Examples
76
+
77
+ ### Basic Tool
78
+
79
+ ```typescript
80
+ import { Server as McpServer, z } from '@ttoss/http-server-mcp';
81
+
82
+ const server = new McpServer({
83
+ name: 'calculator',
84
+ version: '1.0.0',
85
+ });
86
+
87
+ server.registerTool(
88
+ 'add',
89
+ {
90
+ description: 'Add two numbers',
91
+ inputSchema: {
92
+ a: z.number().describe('First number'),
93
+ b: z.number().describe('Second number'),
94
+ },
95
+ },
96
+ async ({ a, b }) => ({
97
+ content: [
98
+ {
99
+ type: 'text',
100
+ text: `${a} + ${b} = ${a + b}`,
101
+ },
102
+ ],
103
+ })
104
+ );
105
+ ```
106
+
107
+ ### Multiple Tools
108
+
109
+ ```typescript
110
+ server.registerTool(
111
+ 'multiply',
112
+ {
113
+ description: 'Multiply two numbers',
114
+ inputSchema: {
115
+ a: z.number(),
116
+ b: z.number(),
117
+ },
118
+ },
119
+ async ({ a, b }) => ({
120
+ content: [{ type: 'text', text: String(a * b) }],
121
+ })
122
+ );
123
+
124
+ server.registerTool(
125
+ 'divide',
126
+ {
127
+ description: 'Divide two numbers',
128
+ inputSchema: {
129
+ a: z.number(),
130
+ b: z.number(),
131
+ },
132
+ },
133
+ async ({ a, b }) => {
134
+ if (b === 0) {
135
+ throw new Error('Division by zero');
136
+ }
137
+ return {
138
+ content: [{ type: 'text', text: String(a / b) }],
139
+ };
140
+ }
141
+ );
142
+ ```
143
+
144
+ ### Custom Path
145
+
146
+ ```typescript
147
+ const router = createMcpRouter(server, {
148
+ path: '/api/mcp',
149
+ });
150
+ ```
151
+
152
+ ### Resources
153
+
154
+ ```typescript
155
+ server.resource(
156
+ 'config://app',
157
+ 'Application configuration',
158
+ 'application/json',
159
+ async () => ({
160
+ contents: [
161
+ {
162
+ uri: 'config://app',
163
+ mimeType: 'application/json',
164
+ text: JSON.stringify({ version: '1.0.0', env: 'production' }),
165
+ },
166
+ ],
167
+ })
168
+ );
169
+ ```
170
+
171
+ ### With CORS and Multiple Endpoints
172
+
173
+ ```typescript
174
+ import { App, bodyParser, cors, Router } from '@ttoss/http-server';
175
+ import { createMcpRouter } from '@ttoss/http-server-mcp';
176
+
177
+ const app = new App();
178
+ app.use(cors());
179
+ app.use(bodyParser());
180
+
181
+ // Health check endpoint
182
+ const healthRouter = new Router();
183
+ healthRouter.get('/health', (ctx) => {
184
+ ctx.body = { status: 'ok' };
185
+ });
186
+
187
+ // MCP endpoint
188
+ const mcpRouter = createMcpRouter(mcpServer);
189
+
190
+ app.use(healthRouter.routes());
191
+ app.use(mcpRouter.routes());
192
+
193
+ app.listen(3000);
194
+ ```
195
+
196
+ ## Protocol Details
197
+
198
+ This package implements the [Model Context Protocol](https://spec.modelcontextprotocol.io/) over HTTP using JSON responses (no SSE streaming). It uses the `StreamableHTTPServerTransport` from the MCP SDK with `enableJsonResponse: true` and adapts Koa's context-based middleware to work with the MCP SDK's Node.js request/response expectations.
199
+
200
+ **Supported HTTP methods:**
201
+
202
+ - `POST /mcp` - Send JSON-RPC requests/notifications
203
+ - `DELETE /mcp` - Terminate session (optional)
204
+
205
+ ## Related Packages
206
+
207
+ - [@ttoss/http-server](https://ttoss.dev/docs/modules/packages/http-server) - HTTP server foundation
208
+ - [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/sdk) - MCP SDK
209
+
210
+ ## Resources
211
+
212
+ - [MCP Documentation](https://modelcontextprotocol.io)
213
+ - [MCP Specification](https://spec.modelcontextprotocol.io/)
214
+ - [MCP SDK TypeScript](https://github.com/modelcontextprotocol/typescript-sdk)
@@ -0,0 +1,52 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ var __defProp = Object.defineProperty;
3
+ var __name = (target, value) => __defProp(target, "name", {
4
+ value,
5
+ configurable: true
6
+ });
7
+
8
+ // src/index.ts
9
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
10
+ import { Router } from "@ttoss/http-server";
11
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
12
+ import { z } from "zod";
13
+ var createMcpRouter = /* @__PURE__ */__name((server, options = {}) => {
14
+ const {
15
+ path = "/mcp",
16
+ sessionIdGenerator
17
+ } = options;
18
+ const transport = new StreamableHTTPServerTransport({
19
+ sessionIdGenerator,
20
+ enableJsonResponse: true
21
+ });
22
+ server.connect(transport);
23
+ const router = new Router();
24
+ router.post(path, async ctx => {
25
+ try {
26
+ await transport.handleRequest(ctx.req, ctx.res, ctx.request.body);
27
+ ctx.respond = false;
28
+ } catch (error) {
29
+ if (!ctx.res.headersSent) {
30
+ ctx.status = 500;
31
+ ctx.body = {
32
+ error: error instanceof Error ? error.message : "Internal server error"
33
+ };
34
+ }
35
+ }
36
+ });
37
+ router.delete(path, async ctx => {
38
+ try {
39
+ await transport.handleRequest(ctx.req, ctx.res, void 0);
40
+ ctx.respond = false;
41
+ } catch (error) {
42
+ if (!ctx.res.headersSent) {
43
+ ctx.status = 500;
44
+ ctx.body = {
45
+ error: error instanceof Error ? error.message : "Internal server error"
46
+ };
47
+ }
48
+ }
49
+ });
50
+ return router;
51
+ }, "createMcpRouter");
52
+ export { McpServer as Server, createMcpRouter, z };
@@ -0,0 +1,61 @@
1
+ import * as _koa_router from '@koa/router';
2
+ import * as koa from 'koa';
3
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
+ export { McpServer, McpServer as Server } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ export { z } from 'zod';
6
+
7
+ /**
8
+ * Options for configuring the MCP router
9
+ */
10
+ interface McpRouterOptions {
11
+ /**
12
+ * The HTTP path where the MCP server will be mounted
13
+ * @default '/mcp'
14
+ */
15
+ path?: string;
16
+ /**
17
+ * Optional session ID generator for stateful MCP servers
18
+ * Set to undefined for stateless servers
19
+ */
20
+ sessionIdGenerator?: () => string;
21
+ }
22
+ /**
23
+ * Creates a Koa router configured to handle MCP protocol requests
24
+ *
25
+ * @param server - The MCP server instance with registered tools and resources
26
+ * @param options - Configuration options for the router
27
+ * @returns A Koa Router instance configured for MCP
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * import { App, bodyParser } from '@ttoss/http-server';
32
+ * import { createMcpRouter, Server as McpServer, z } from '@ttoss/http-server-mcp';
33
+ *
34
+ * const mcpServer = new McpServer({
35
+ * name: 'my-server',
36
+ * version: '1.0.0',
37
+ * });
38
+ *
39
+ * mcpServer.registerTool(
40
+ * 'hello',
41
+ * {
42
+ * description: 'Say hello',
43
+ * inputSchema: { name: z.string() },
44
+ * },
45
+ * async ({ name }) => ({
46
+ * content: [{ type: 'text', text: `Hello, ${name}!` }],
47
+ * })
48
+ * );
49
+ *
50
+ * const app = new App();
51
+ * app.use(bodyParser());
52
+ *
53
+ * const mcpRouter = createMcpRouter(mcpServer);
54
+ * app.use(mcpRouter.routes());
55
+ *
56
+ * app.listen(3000);
57
+ * ```
58
+ */
59
+ declare const createMcpRouter: (server: McpServer, options?: McpRouterOptions) => _koa_router.RouterInstance<koa.DefaultState, koa.DefaultContext>;
60
+
61
+ export { type McpRouterOptions, createMcpRouter };
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@ttoss/http-server-mcp",
3
+ "version": "0.3.0",
4
+ "description": "Model Context Protocol (MCP) server integration for @ttoss/http-server",
5
+ "license": "MIT",
6
+ "author": "ttoss",
7
+ "contributors": [
8
+ "Pedro Arantes <pedro@arantespp.com> (https://arantespp.com)"
9
+ ],
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/ttoss/ttoss.git",
13
+ "directory": "packages/http-server-mcp"
14
+ },
15
+ "type": "module",
16
+ "exports": {
17
+ ".": {
18
+ "import": "./dist/esm/index.js",
19
+ "types": "./dist/index.d.ts"
20
+ }
21
+ },
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "sideEffects": false,
26
+ "dependencies": {
27
+ "@modelcontextprotocol/sdk": "^1.0.4",
28
+ "zod": "^3.25.76",
29
+ "@ttoss/http-server": "^0.3.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/koa": "^3.0.1",
33
+ "jest": "^30.2.0",
34
+ "supertest": "^7.1.4",
35
+ "tsup": "^8.5.1",
36
+ "@ttoss/config": "^1.35.12"
37
+ },
38
+ "keywords": [
39
+ "ai",
40
+ "koa",
41
+ "llm",
42
+ "mcp",
43
+ "model-context-protocol",
44
+ "server"
45
+ ],
46
+ "publishConfig": {
47
+ "access": "public",
48
+ "provenance": true
49
+ },
50
+ "scripts": {
51
+ "build": "tsup",
52
+ "test": "jest --projects tests/unit"
53
+ }
54
+ }