Skip to content

Commit 594e496

Browse files
author
robertlestak
committed
add streamable http transport support to memory and sequentialthinking
1 parent d1d6a12 commit 594e496

File tree

5 files changed

+186
-10
lines changed

5 files changed

+186
-10
lines changed

package-lock.json

Lines changed: 0 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/memory/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,31 @@ The server can be configured using the following environment variables:
182182

183183
- `MEMORY_FILE_PATH`: Path to the memory storage JSONL file (default: `memory.jsonl` in the server directory)
184184

185+
#### HTTP Transport
186+
187+
To run the server with HTTP transport instead of stdio:
188+
189+
```json
190+
{
191+
"mcpServers": {
192+
"memory": {
193+
"command": "npx",
194+
"args": [
195+
"-y",
196+
"@modelcontextprotocol/server-memory"
197+
],
198+
"env": {
199+
"MCP_TRANSPORT": "http",
200+
"PORT": "3000"
201+
}
202+
}
203+
}
204+
}
205+
```
206+
207+
- `MCP_TRANSPORT`: Set to `http` to use HTTP transport (default: stdio)
208+
- `PORT`: HTTP port number (default: 3000)
209+
185210
# VS Code Installation Instructions
186211

187212
For quick installation, use one of the one-click installation buttons below:

src/memory/index.ts

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
44
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
56
import { z } from "zod";
67
import { promises as fs } from 'fs';
78
import path from 'path';
@@ -460,9 +461,73 @@ async function main() {
460461
// Initialize knowledge graph manager with the memory file path
461462
knowledgeGraphManager = new KnowledgeGraphManager(MEMORY_FILE_PATH);
462463

463-
const transport = new StdioServerTransport();
464-
await server.connect(transport);
465-
console.error("Knowledge Graph MCP Server running on stdio");
464+
// Use HTTP transport if MCP_TRANSPORT=http, otherwise stdio
465+
if (process.env.MCP_TRANSPORT === 'http') {
466+
const { createServer } = await import('http');
467+
const transports: Record<string, StreamableHTTPServerTransport> = {};
468+
469+
const httpServer = createServer(async (req, res) => {
470+
const sessionId = req.headers['mcp-session-id'] as string | undefined;
471+
472+
if (req.method === 'POST') {
473+
let body = '';
474+
req.on('data', chunk => body += chunk);
475+
req.on('end', async () => {
476+
const parsedBody = body.trim() ? JSON.parse(body) : undefined;
477+
478+
let transport: StreamableHTTPServerTransport;
479+
if (sessionId && transports[sessionId]) {
480+
transport = transports[sessionId];
481+
} else if (!sessionId) {
482+
transport = new StreamableHTTPServerTransport({
483+
sessionIdGenerator: () => crypto.randomUUID(),
484+
onsessioninitialized: (sid) => {
485+
transports[sid] = transport;
486+
console.error('Session initialized:', sid);
487+
},
488+
onsessionclosed: (sid) => {
489+
delete transports[sid];
490+
console.error('Session closed:', sid);
491+
}
492+
});
493+
await server.connect(transport);
494+
} else {
495+
res.writeHead(400);
496+
res.end('Invalid session ID');
497+
return;
498+
}
499+
500+
await transport.handleRequest(req, res, parsedBody);
501+
});
502+
} else if (req.method === 'GET') {
503+
if (!sessionId || !transports[sessionId]) {
504+
res.writeHead(400);
505+
res.end('Invalid or missing session ID');
506+
return;
507+
}
508+
await transports[sessionId].handleRequest(req, res);
509+
} else if (req.method === 'DELETE') {
510+
if (!sessionId || !transports[sessionId]) {
511+
res.writeHead(400);
512+
res.end('Invalid or missing session ID');
513+
return;
514+
}
515+
await transports[sessionId].handleRequest(req, res);
516+
} else {
517+
res.writeHead(405);
518+
res.end('Method not allowed');
519+
}
520+
});
521+
522+
const port = parseInt(process.env.PORT || '3000');
523+
httpServer.listen(port, () => {
524+
console.error(`Knowledge Graph MCP Server running on HTTP port ${port}`);
525+
});
526+
} else {
527+
const transport = new StdioServerTransport();
528+
await server.connect(transport);
529+
console.error("Knowledge Graph MCP Server running on stdio");
530+
}
466531
}
467532

468533
main().catch((error) => {

src/sequentialthinking/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,32 @@ Add this to your `claude_desktop_config.json`:
7878
```
7979

8080
To disable logging of thought information set env var: `DISABLE_THOUGHT_LOGGING` to `true`.
81+
82+
#### HTTP Transport
83+
84+
To run the server with HTTP transport instead of stdio:
85+
86+
```json
87+
{
88+
"mcpServers": {
89+
"sequential-thinking": {
90+
"command": "npx",
91+
"args": [
92+
"-y",
93+
"@modelcontextprotocol/server-sequential-thinking"
94+
],
95+
"env": {
96+
"MCP_TRANSPORT": "http",
97+
"PORT": "3000"
98+
}
99+
}
100+
}
101+
}
102+
```
103+
104+
- `MCP_TRANSPORT`: Set to `http` to use HTTP transport (default: stdio)
105+
- `PORT`: HTTP port number (default: 3000)
106+
81107
Comment
82108

83109
### Usage with VS Code

src/sequentialthinking/index.ts

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
44
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
56
import { z } from "zod";
67
import { SequentialThinkingServer } from './lib.js';
78

@@ -107,9 +108,72 @@ You should:
107108
);
108109

109110
async function runServer() {
110-
const transport = new StdioServerTransport();
111-
await server.connect(transport);
112-
console.error("Sequential Thinking MCP Server running on stdio");
111+
if (process.env.MCP_TRANSPORT === 'http') {
112+
const { createServer } = await import('http');
113+
const transports: Record<string, StreamableHTTPServerTransport> = {};
114+
115+
const httpServer = createServer(async (req, res) => {
116+
const sessionId = req.headers['mcp-session-id'] as string | undefined;
117+
118+
if (req.method === 'POST') {
119+
let body = '';
120+
req.on('data', chunk => body += chunk);
121+
req.on('end', async () => {
122+
const parsedBody = body.trim() ? JSON.parse(body) : undefined;
123+
124+
let transport: StreamableHTTPServerTransport;
125+
if (sessionId && transports[sessionId]) {
126+
transport = transports[sessionId];
127+
} else if (!sessionId) {
128+
transport = new StreamableHTTPServerTransport({
129+
sessionIdGenerator: () => crypto.randomUUID(),
130+
onsessioninitialized: (sid) => {
131+
transports[sid] = transport;
132+
console.error('Session initialized:', sid);
133+
},
134+
onsessionclosed: (sid) => {
135+
delete transports[sid];
136+
console.error('Session closed:', sid);
137+
}
138+
});
139+
await server.connect(transport);
140+
} else {
141+
res.writeHead(400);
142+
res.end('Invalid session ID');
143+
return;
144+
}
145+
146+
await transport.handleRequest(req, res, parsedBody);
147+
});
148+
} else if (req.method === 'GET') {
149+
if (!sessionId || !transports[sessionId]) {
150+
res.writeHead(400);
151+
res.end('Invalid or missing session ID');
152+
return;
153+
}
154+
await transports[sessionId].handleRequest(req, res);
155+
} else if (req.method === 'DELETE') {
156+
if (!sessionId || !transports[sessionId]) {
157+
res.writeHead(400);
158+
res.end('Invalid or missing session ID');
159+
return;
160+
}
161+
await transports[sessionId].handleRequest(req, res);
162+
} else {
163+
res.writeHead(405);
164+
res.end('Method not allowed');
165+
}
166+
});
167+
168+
const port = parseInt(process.env.PORT || '3000');
169+
httpServer.listen(port, () => {
170+
console.error(`Sequential Thinking MCP Server running on HTTP port ${port}`);
171+
});
172+
} else {
173+
const transport = new StdioServerTransport();
174+
await server.connect(transport);
175+
console.error("Sequential Thinking MCP Server running on stdio");
176+
}
113177
}
114178

115179
runServer().catch((error) => {

0 commit comments

Comments
 (0)