Table of Contents [expand]
Last updated September 04, 2025
The /v1/mcp/servers endpoint returns a list of MCP servers registered to your Heroku Managed Inference and Agents chat model. This list includes details about each server and the tools it exposes.
If you haven’t deployed and registered an MCP server, requests made to /v1/mcp/servers return an empty list.
Authentication
The /v1/mcp/servers endpoint requires a valid INFERENCE_KEY for a Heroku chat model you have provisioned.
Required Headers
| Header | Type | Description |
|---|---|---|
Authorization |
string | a bearer token with your INFERENCE_KEY |
Example Request
Retrieve your INFERENCE_URL and INFERENCE_KEY values by running heroku config -a $APP_NAME against an app you’ve attached a chat model to.
curl $INFERENCE_URL/v1/mcp/servers -H "Authorization: Bearer $INFERENCE_KEY" | jq
With example values filled in:
curl https://us.inference.heroku.com/v1/mcp/servers -H Authorization: Bearer inf-123abc9f-2a6c-441a-9f72-e2dc15cdcaaa | jq
Response Format
v1/mcp/servers requests return an array of MCP Server Objects, one per MCP server attached to your model.
Example response:
[
{
"id": "15ac9382-5804-49ac-bf94-8bab2f4b62ce",
"app_id": "434eb878-6bc1-4677-928d-80d27047ad5a",
"process_type": "mcp",
"process_command": "python -m src.stdio_server",
"created_at": "2025-05-07T16:44:34.259Z",
"updated_at": "2025-05-07T16:44:38.291Z",
"namespace": "acute-partridge",
"server_status": "registered",
"primitives_status": "synced",
"tools": [ ... ]
}
]
See a full example response below.
MCP Server Object
| Field | Type | Description | Example |
|---|---|---|---|
| id | string (uuid) | unique server ID | "15ac9382-..." |
| app_id | string (uuid) | Heroku app ID where server is running | "434eb878-..." |
| process_type | string | process type used to start server, specified in the MCP app’s Procfile - must start with ‘mcp’ | "mcp-my-cool-server" |
| process_command | string | command used to run MCP STDIO server, specified in the MCP app’s Profile (process_type: process_command) |
"python -m src.stdio_server" |
| created_at | string (ISO 8601) | timestamp when server was registered | "2025-05-07T16:44:34.259Z" |
| updated_at | string (ISO 8601) | timestamp when server was last updated | "2025-05-07T16:44:38.291Z" |
| namespace | string | name used to namespace tools served by this server | "acute-partridge" |
| server_status | enum<string> | status of server one of: registered, disconnected |
"registered" |
| primitives_status | enum<string> | status of the server’s tools list one of: syncing, synced, error |
"synced" |
| tools | array | list of tools exposed by this server |
Tool Object
Each server can expose multiple MCP tools.
| Field | Type | Description | Example |
|---|---|---|---|
| name | string | tool name that’s unique within its server namespace for the specified model resource | "code_exec_ruby" |
| namespaced_name | string | fully-qualified tool name, formatted as namespace/tool_name |
"acute-partridge/code_exec_ruby" |
| description | string | (optional) plain-text description for model grounding | "Executes a Ruby code snippet..." |
| input_schema | object | input schema for tool call arguments, using JSON Schema | see input schema example |
| annotations | object | annotations containing optional hints about the tool’s functionality and dangers (for example, destructiveHint) |
{} |
Input Schema Example
{
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "The Ruby code to execute as a string."
},
"packages": {
"type": "array",
"items": { "type": "string" },
"description": "Optional list of gem names to install before execution."
},
"use_temp_dir": {
"type": "boolean",
"description": "If true, run code in an isolated temp directory."
}
},
"required": ["code"]
}
Annotations Object
| Field | Type | Description | Example |
|---|---|---|---|
| title | string | (optional) UI-facing title for the tool | "Awesome Code Executor" |
| readOnlyHint | boolean | true if tool has no side effects | false |
| destructiveHint | boolean | true if the tool may delete or irreversibly modify data | true |
| idempotentHint | boolean | true if calling the tool multiple times with the same arguments will have no marginal effect | false |
| openWorldHint | boolean | true if the tool queries external or evolving real-world information | true |
Notes
- Use
/v1/agents/herokuto invoke tools registered by this endpoint. - Only tools from servers with
server_status: "registered"andprimitives_status: "synced"will be accessible in/v1/agents/herokurequests. Until you deploy and register an MCP server, requests made to/v1/mcp/serverswill return an empty list, and your tools will not be accessible in/v1/agents/herokurequests. - MCP Tool and Server (Procfile process) names must be unique within a given add-on’s namespace.
- Tool input schemas must follow the JSON Schema format.
Full Example Response
[
{
"id": "a3bda372-085b-458f-8b1e-6f5704d528fe",
"app_id": "434eb878-6bc1-4677-928d-80d27047ad5a",
"process_type": "mcp",
"process_command": "python -m src.stdio_server",
"created_at": "2025-05-09T15:23:42.318541Z",
"updated_at": "2025-05-09T15:23:45.890484Z",
"tools": [
{
"name": "code_exec_ruby",
"namespaced_name": "mcp/code_exec_ruby",
"description": "Executes a Ruby code snippet with optional gem dependencies.\n\n When `use_temp_dir` is True, the code and any installed gems are run in a throwaway temporary directory,\n and gems are isolated. When False, gems are installed to ~/.gem.\n\n The Ruby runtime has access to networking, the filesystem, and standard libraries.\n A non-zero exit code is an error and should be fixed.\n\n Returns:\n JSON containing:\n - 'returncode': Exit status of the execution.\n - 'stdout': Captured standard output.\n - 'stderr': Captured standard error or install failure messages.\n ",
"input_schema": {
"type": "object",
"properties": {
"code": {
"type": "string",
"title": "Code",
"description": "The Ruby code to execute as a string."
},
"packages": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Packages",
"default": null,
"description": "Optional list of gem names to install before execution."
},
"use_temp_dir": {
"type": "boolean",
"title": "Use Temp Dir",
"default": false,
"description": "If True, code and dependencies are run in a temporary working directory. Gems are installed in an isolated directory and will not affect or reuse the user's ~/.gem folder. Not a secure sandbox."
}
},
"required": [
"code"
]
},
"annotations": {}
}
],
"server_status": "registered",
"primitives_status": "synced",
"namespace": "mcp"
}
]