-
Notifications
You must be signed in to change notification settings - Fork 2.3k
core (ai/mcp): update experimental MCP client documentation for Streamable HTTP transport usage #5972
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
iteratetograceness
merged 24 commits into
vercel:main
from
iteratetograceness:http-transport
Apr 30, 2025
Merged
core (ai/mcp): update experimental MCP client documentation for Streamable HTTP transport usage #5972
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
e1b3fc5
add resumption token
iteratetograceness e83fe38
feat: strict mode config
iteratetograceness d91f0ec
prettier
iteratetograceness ca8dd22
next-mcp example
iteratetograceness e8abc3b
fix type/prettier
iteratetograceness 099b21b
fix tests
iteratetograceness 22be6b3
remove resumetoken
iteratetograceness 0a3c55b
merge latest
iteratetograceness 155b281
smol docs changes
iteratetograceness 7692c18
changeset
iteratetograceness f074ee3
fix: move example to next-openai
iteratetograceness 79b709f
lockflie
iteratetograceness 943840b
rename to strictMode
iteratetograceness ff5a3e6
Merge branch 'main' into http-transport
iteratetograceness dbc5348
final touches
iteratetograceness 2871524
address comments
iteratetograceness 870bc4b
parse down to minimal functionality
iteratetograceness 6e4bdb7
remove
iteratetograceness b174f68
pls remove
iteratetograceness abbbe65
Update mcp-client.ts
iteratetograceness 6a2d7aa
remove package changes
iteratetograceness c488ab6
Merge branch 'main' into http-transport
iteratetograceness bfba72a
Merge branch 'main' into http-transport
iteratetograceness 6f56a96
Merge branch 'main' into http-transport
iteratetograceness File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { openai } from '@ai-sdk/openai'; | ||
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp'; | ||
import { experimental_createMCPClient, generateText } from 'ai'; | ||
import 'dotenv/config'; | ||
|
||
async function main() { | ||
const transport = new StreamableHTTPClientTransport( | ||
new URL('http://localhost:3000/mcp'), | ||
); | ||
|
||
const mcpClient = await experimental_createMCPClient({ | ||
transport, | ||
}); | ||
|
||
try { | ||
const tools = await mcpClient.tools(); | ||
|
||
const { text: answer } = await generateText({ | ||
model: openai('gpt-4o-mini'), | ||
tools, | ||
maxSteps: 10, | ||
onStepFinish: async ({ toolResults }) => { | ||
console.log(`STEP RESULTS: ${JSON.stringify(toolResults, null, 2)}`); | ||
}, | ||
system: 'You are a helpful chatbot', | ||
prompt: 'Look up information about user with the ID foo_123', | ||
}); | ||
|
||
console.log(`FINAL ANSWER: ${answer}`); | ||
} catch (error) { | ||
console.error('Error:', error); | ||
} finally { | ||
await mcpClient.close(); | ||
} | ||
} | ||
|
||
main(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; | ||
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; | ||
import express from 'express'; | ||
import { z } from 'zod'; | ||
|
||
// Stateless Mode: see https://github.com/modelcontextprotocol/typescript-sdk/tree/main/src/examples#stateless-mode for more details | ||
|
||
const app = express(); | ||
app.use(express.json()); | ||
|
||
app.post('/mcp', async (req, res) => { | ||
const server = new McpServer({ | ||
name: 'example-http-server', | ||
version: '1.0.0', | ||
}); | ||
|
||
server.tool( | ||
'get-user-info', | ||
'Get user info', | ||
{ | ||
userId: z.string(), | ||
}, | ||
async ({ userId }) => { | ||
return { | ||
content: [ | ||
{ | ||
type: 'text', | ||
text: `Here is information about user ${userId}:`, | ||
}, | ||
{ | ||
type: 'text', | ||
text: `Name: John Doe`, | ||
}, | ||
{ | ||
type: 'text', | ||
text: `Email: [email protected]`, | ||
}, | ||
{ | ||
type: 'text', | ||
text: `Age: 30`, | ||
}, | ||
], | ||
}; | ||
}, | ||
); | ||
|
||
try { | ||
const transport = new StreamableHTTPServerTransport({ | ||
sessionIdGenerator: undefined, | ||
}); | ||
await server.connect(transport); | ||
await transport.handleRequest(req, res, req.body); | ||
res.on('close', () => { | ||
transport.close(); | ||
server.close(); | ||
}); | ||
} catch (error) { | ||
console.error('Error handling MCP request:', error); | ||
if (!res.headersSent) { | ||
res.status(500).json({ | ||
jsonrpc: '2.0', | ||
error: { | ||
code: -32603, | ||
message: 'Internal server error', | ||
}, | ||
id: null, | ||
}); | ||
} | ||
} | ||
}); | ||
|
||
app.get('/mcp', async (_req, res) => { | ||
console.log('Received GET MCP request'); | ||
res.writeHead(405).end( | ||
JSON.stringify({ | ||
jsonrpc: '2.0', | ||
error: { | ||
code: -32000, | ||
message: 'Method not allowed.', | ||
}, | ||
id: null, | ||
}), | ||
); | ||
}); | ||
|
||
app.delete('/mcp', async (_req, res) => { | ||
console.log('Received DELETE MCP request'); | ||
res.writeHead(405).end( | ||
JSON.stringify({ | ||
jsonrpc: '2.0', | ||
error: { | ||
code: -32000, | ||
message: 'Method not allowed.', | ||
}, | ||
id: null, | ||
}), | ||
); | ||
}); | ||
|
||
app.listen(3000); | ||
|
||
process.on('SIGINT', async () => { | ||
console.log('Shutting down server...'); | ||
process.exit(0); | ||
}); |
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { openai } from '@ai-sdk/openai'; | ||
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp'; | ||
import { experimental_createMCPClient, streamText } from 'ai'; | ||
|
||
export async function POST(req: Request) { | ||
const url = new URL('http://localhost:3000/mcp/server'); | ||
const transport = new StreamableHTTPClientTransport(url); | ||
|
||
const [client, { messages }] = await Promise.all([ | ||
experimental_createMCPClient({ | ||
transport, | ||
}), | ||
req.json(), | ||
]); | ||
|
||
try { | ||
const tools = await client.tools(); | ||
|
||
const result = streamText({ | ||
model: openai('gpt-4o-mini'), | ||
tools, | ||
maxSteps: 5, | ||
onStepFinish: async ({ toolResults }) => { | ||
console.log(`STEP RESULTS: ${JSON.stringify(toolResults, null, 2)}`); | ||
}, | ||
system: 'You are a helpful chatbot capable of basic arithmetic problems', | ||
messages, | ||
onFinish: async () => { | ||
await client.close(); | ||
}, | ||
// Optional, enables immediate clean up of resources but connection will not be retained for retries: | ||
// onError: async error => { | ||
// await client.close(); | ||
// }, | ||
}); | ||
|
||
return result.toDataStreamResponse(); | ||
} catch (error) { | ||
console.error(error); | ||
return Response.json({ error: 'Unexpected error' }, { status: 500 }); | ||
} | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.