Skip to content

Commit 2802a69

Browse files
committed
fix(http): create transport per request for stateless mode
The StreamableHTTPServerTransport requires a fresh transport + server connection per request in stateless mode. Previous implementation reused a single transport instance, causing requests to hang.
1 parent 141270f commit 2802a69

File tree

3 files changed

+215
-222
lines changed

3 files changed

+215
-222
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ RUN pnpm build
1818
EXPOSE 3000
1919

2020
# Start server with HTTP transport
21-
CMD ["node", "bin/cli.js", "--transport=http", "--host=0.0.0.0", "--port=3000", "--path=/mcp", "--stateless"]
21+
CMD ["node", "bin/cli.js", "--transport=http", "--host=0.0.0.0", "--port=3000", "--path=/mcp"]

src/index.ts

Lines changed: 36 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,88 +7,76 @@
77
import 'dotenv/config'
88

99
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
10+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
1011

1112
import { intro } from './cli/intro.js'
1213
import packageJson from '../package.json' with { type: 'json' }
1314

1415
import { registerPrompts } from '#prompts/index'
1516
import { registerResources } from '#resources/index'
1617
import { registerTools } from '#tools/index'
17-
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
18-
import { HttpTransport } from '#transports/http'
19-
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'
20-
21-
const server = new McpServer({
22-
name: 'Vuetify',
23-
version: packageJson.version,
24-
capabilities: {
25-
resources: {
26-
description: 'No resources required for Vuetify assistance.',
27-
},
28-
tools: {
29-
description: 'Tools to help with Vuetify component properties, layouts, and documentation.',
30-
},
31-
prompts: {
32-
description: 'Prompts to assist with Vuetify component usage and best practices.',
33-
},
34-
},
35-
})
36-
37-
await registerResources(server)
38-
await registerPrompts(server)
39-
await registerTools(server)
18+
import { startHttpServer } from '#transports/http'
4019

4120
function parseArgs () {
4221
const args = process.argv.slice(2)
4322
let transport = 'stdio'
4423
let port = 3000
4524
let host = 'localhost'
4625
let path = '/mcp'
47-
let stateless = false
4826

4927
for (let i = 0; i < args.length; i++) {
5028
const arg = args[i]
5129
if (arg === '--transport' && i + 1 < args.length) {
5230
transport = args[++i]
53-
}
54-
else if (arg === '--port' && i + 1 < args.length) {
55-
port = parseInt(args[++i], 10)
56-
}
57-
else if (arg === '--host' && i + 1 < args.length) {
31+
} else if (arg === '--port' && i + 1 < args.length) {
32+
port = Number.parseInt(args[++i], 10)
33+
} else if (arg === '--host' && i + 1 < args.length) {
5834
host = args[++i]
59-
}
60-
else if (arg === '--path' && i + 1 < args.length) {
35+
} else if (arg === '--path' && i + 1 < args.length) {
6136
path = args[++i]
6237
}
63-
else if (arg === '--stateless') {
64-
stateless = true
65-
}
6638
}
6739

68-
return { transport, port, host, path, stateless }
40+
return { transport, port, host, path }
6941
}
7042

71-
function createTransport (options: ReturnType<typeof parseArgs>): Transport {
43+
async function main () {
44+
const options = parseArgs()
45+
7246
if (options.transport === 'http') {
73-
return new HttpTransport({
47+
// HTTP transport handles its own server creation per-request
48+
await startHttpServer({
7449
port: options.port,
7550
host: options.host,
7651
path: options.path,
77-
stateless: options.stateless,
7852
})
79-
}
80-
return new StdioServerTransport()
81-
}
53+
} else {
54+
// Stdio transport - single server instance
55+
intro()
8256

83-
async function main () {
84-
const options = parseArgs()
57+
const server = new McpServer({
58+
name: 'Vuetify',
59+
version: packageJson.version,
60+
capabilities: {
61+
resources: {
62+
description: 'No resources required for Vuetify assistance.',
63+
},
64+
tools: {
65+
description: 'Tools to help with Vuetify component properties, layouts, and documentation.',
66+
},
67+
prompts: {
68+
description: 'Prompts to assist with Vuetify component usage and best practices.',
69+
},
70+
},
71+
})
8572

86-
if (options.transport === 'stdio') {
87-
intro()
88-
}
73+
await registerResources(server)
74+
await registerPrompts(server)
75+
await registerTools(server)
8976

90-
const transport = createTransport(options)
91-
await server.connect(transport)
77+
const transport = new StdioServerTransport()
78+
await server.connect(transport)
79+
}
9280
}
9381

9482
main().catch(error => {

0 commit comments

Comments
 (0)