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-community/apt -a $APP_NAME
heroku buildpacks:add --index 2 heroku/python -a $APP_NAME
# 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_go",
"arguments": {
"code": "package main\\nimport (\\n \\"github.com/fatih/color\\"\\n)\\nfunc main() {\\n color.NoColor = false\\n color.Red(\\"This should be red!\\")\\n}",
"packages": ["github.com/fatih/color"]
}
}' | jq -r '.content[0].text' | jq -r .stdout
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_go",
"arguments": {
"code": "package main\\nimport (\\n \\"fmt\\"\\n \\"math/rand\\"\\n)\\nfunc main() {\\n for i := 0; i < 50; i++ {\\n fmt.Printf(\\"%f \\", rand.Float64())\\n }\\n}",
"packages": []
}
}' | jq
Example tool call request:
cat <<EOF | python -m src.stdio_server
...