BundleUp doesn’t ship an MCP client. It works with the one you already use. There are two ways to run one, and the difference is where your API key goes.
With model-hosted MCP, the model provider calls mcp.bundleup.io itself, so your API key is sent to the model provider. With an MCP client in your backend, your backend calls mcp.bundleup.io and passes tool definitions and results to the model, so your API key stays with you.
Model-hosted MCP
OpenAI’s Responses API and Anthropic’s Messages API can connect to an MCP server themselves. Both accept a single bearer credential, so pass the API key and connection ID joined by a dot. The SDK’s hosted() returns the URL and that token.
Without the SDK, the values are:
- URL:
https://mcp.bundleup.io (exactly; any path you add is ignored)
- Token:
YOUR_API_KEY.CONNECTION_ID
On this path your BundleUp API key is sent to the model provider, and their servers make the MCP calls. If that isn’t acceptable, run the MCP client in your own backend.
MCP client in your backend
Use the official MCP SDK (or any client that speaks streamable HTTP) with the two headers. The BundleUp SDK’s transport() returns the URL and headers.
Pass the tool list to your model in its tool format, run the calls the model makes through the MCP client, and return the results. Your API key never leaves your backend.
Sending JSON-RPC yourself
The SDKs’ mcp.post() and mcp.delete() send raw messages and return the response untouched. You’re then responsible for the MCP handshake: send initialize, keep the Mcp-Session-Id it returns, send notifications/initialized, and include the session ID on every later message. Responses can be JSON or text/event-stream. See the JavaScript SDK for a full example.
Handy for checking a connection works before wiring it into an agent.
Desktop MCP clients that only support OAuth discovery can’t connect directly. Use mcp-remote as a local bridge with static headers.