README.md
Instead of manually setting each variable, use the Heroku CLI to pull the correct values.
export APP_NAME=<your-heroku-app-name>
heroku create $APP_NAME
heroku buildpacks:add --index 1 heroku/nodejs
heroku buildpacks:add --index 2 heroku/python
# set a private API key that you create, for example:
heroku config:set API_KEY=$(openssl rand -hex 32) -a $APP_NAME
heroku config:set STDIO_MODE_ONLY=<true/false> -a $APP_NAME
# set the remote server type (module) that your web process will use (only relevant for web deployments)
heroku config:set REMOTE_SERVER_TRANSPORT_MODULE=<streamable_http_server/sse_server>
Note: we recommend setting STDIO_MODE_ONLY
to true
for security and code execution isolation security in non-dev environments.
If you only want local & deployed STDIO
capabilities (no SSE server
), run:
heroku ps:scale web=0 -a $APP_NAME
If you do want a deployed SSE
server, run:
heroku ps:scale web=1 -a $APP_NAME
heroku config:set WEB_CONCURRENCY=1 -a $APP_NAME
Optionally, put these config variables into a local .env file for local development:
heroku config -a $APP_NAME --shell | tee .env > /dev/null
Next, connect your app to your git repo:
heroku git:remote -a $APP_NAME
And deploy!
git push heroku main
View logs with:
heroku logs --tail -a $APP_NAME
One-time packages installation:
virtualenv venv
source venv/bin/activate
pip install -r requirements.txt
If you're testing (stateless) Streamable HTTP OR SSE, in one terminal pane you'll need to start the server:
source venv/bin/activate
export API_KEY=$(heroku config:get API_KEY -a $APP_NAME)
# Either run src.streamable_http_server or src.sse_server, here:
uvicorn src.streamable_http_server:app --reload
Running with --reload
is optional, but great for local development
Next, in a new pane, you can try running some queries against your server:
First run:
export API_KEY=$(heroku config:get API_KEY -a $APP_NAME)
In the following commands, use either example_clients/streamable_http_client.py
if you ran the streamable HTTP server above, or example_clients/sse_client.py
if you're running the SSE server.
List tools:
python example_clients/streamable_http_client.py mcp list_tools | jq
Example tool call request:
NOTE: this will intentionally NOT work if you have set STDIO_MODE_ONLY
to true
.
python example_clients/streamable_http_client.py mcp call_tool --args '{
"name": "code_exec_node",
"arguments": {
"code": "console.log(Array.from({length: 50}, () => Math.random()));",
"packages": []
}
}' | jq
There are two ways to easily test out your MCP server in STDIO mode:
List tools:
python example_clients/stdio_client.py mcp list_tools | jq
Example tool call request:
python example_clients/stdio_client.py mcp call_tool --args '{
"name": "code_exec_node",
"arguments": {
"code": "import { evaluate, pi } from \\"mathjs\\";\\nconst result = evaluate(\\"sin(2 * pi / 3) + cos(pi / 6)\\");\\nconsole.log(\\"Result:\\", result);",
"packages": ["mathjs"],
"use_temp_dir": true
}
}' | jq
Example tool call request:
cat <<EOF | python -m src.stdio_server
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"0.1.0","capabilities":{},"clientInfo":{"name":"tes...