fix(mcp): enable JSON response mode for HTTP transport
Avoid SSE stream response for finite HTTP MCP tool calls by enabling enableJsonResponse option on transport.
This commit is contained in:
parent
4e45a313b7
commit
27181988b0
|
|
@ -0,0 +1,51 @@
|
||||||
|
import { describe, expect, it, mock } from 'bun:test'
|
||||||
|
|
||||||
|
process.env.MCP_SECRET = 'test-secret'
|
||||||
|
|
||||||
|
mock.module('@/utils/archive', () => ({
|
||||||
|
archiveVideo: async (input: string) => {
|
||||||
|
// Integration delay simulation to test async handler waiting
|
||||||
|
await Bun.sleep(50)
|
||||||
|
return { success: true, message: 'Video archived successfully.', videoId: input }
|
||||||
|
},
|
||||||
|
addToSizeWhitelist: async () => ({ success: true, message: 'Whitelisted.' }),
|
||||||
|
getVideoMetadata: async () => ({ success: true, metadata: {} }),
|
||||||
|
extractVideoId: (input: string) => input
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Dynamic import required so mock.module executes before mcp module is imported
|
||||||
|
const { default: app } = await import('./mcp')
|
||||||
|
|
||||||
|
describe('HTTP MCP Transport', () => {
|
||||||
|
it('returns JSON response for delayed tool call without streaming SSE', async () => {
|
||||||
|
const startTime = Date.now()
|
||||||
|
const response = await app.handle(
|
||||||
|
new Request('http://localhost/api/mcp/', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Bearer test-secret',
|
||||||
|
'Accept': 'application/json, text/event-stream',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Mcp-Protocol-Version': '2025-03-26'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
id: 1,
|
||||||
|
method: 'tools/call',
|
||||||
|
params: {
|
||||||
|
name: 'archive_video',
|
||||||
|
arguments: { videoId: 'dQw4w9WgXcQ' }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
const duration = Date.now() - startTime
|
||||||
|
expect(duration).toBeLessThan(1000)
|
||||||
|
expect(response.status).toBe(200)
|
||||||
|
expect(response.headers.get('content-type')).toContain('application/json')
|
||||||
|
|
||||||
|
const body = await response.json()
|
||||||
|
expect(body.result.content[0].text).toContain('Video archived successfully.')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
@ -83,7 +83,7 @@ function createMcpServer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleMcpStreamRequest(request: Request): Promise<Response> {
|
async function handleMcpStreamRequest(request: Request): Promise<Response> {
|
||||||
const transport = new WebStandardStreamableHTTPServerTransport()
|
const transport = new WebStandardStreamableHTTPServerTransport({ enableJsonResponse: true })
|
||||||
const mcpServer = createMcpServer()
|
const mcpServer = createMcpServer()
|
||||||
await mcpServer.connect(transport)
|
await mcpServer.connect(transport)
|
||||||
return await transport.handleRequest(request)
|
return await transport.handleRequest(request)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue