REST API

MCP Hangar exposes a full REST API alongside the MCP protocol layer. The API is mounted at /api/ when running in HTTP mode and provides CRUD operations, real-time WebSocket streams, and operational endpoints.

Quick Start

Start Hangar in HTTP mode:

mcp-hangar serve --http --port 8000

The REST API is available at http://localhost:8000/api/.

# List all mcp_servers
curl http://localhost:8000/api/mcp_servers

# Get system info
curl http://localhost:8000/api/system

# Start a mcp_server
curl -X POST http://localhost:8000/api/mcp_servers/math/start

Authentication

When authentication is enabled, pass your API key in the X-API-Key header:

curl -H "X-API-Key: mcp_your_key_here" http://localhost:8000/api/mcp_servers

See the Authentication guide for setup instructions.

Endpoints Overview

All endpoints return JSON. Error responses follow the envelope format:

{
  "error": "McpServerNotFoundError",
  "message": "MCP Server 'unknown' not found",
  "status_code": 404
}

MCP servers

MethodPathDescription
GET/api/mcp_serversList all MCP servers (optional ?state=ready filter)
POST/api/mcp_serversCreate a new MCP server
GET/api/mcp_servers/{id}Get MCP server details
PUT/api/mcp_servers/{id}Update MCP server configuration
DELETE/api/mcp_servers/{id}Delete a MCP server (stops it first)
POST/api/mcp_servers/{id}/startStart a MCP server
POST/api/mcp_servers/{id}/stopStop a MCP server
GET/api/mcp_servers/{id}/toolsList MCP server tools
GET/api/mcp_servers/{id}/healthGet health status
GET/api/mcp_servers/{id}/logsGet buffered log lines (?lines=100)
GET/api/mcp_servers/{id}/tools/historyTool invocation history

Groups

MethodPathDescription
GET/api/groupsList all MCP server groups
POST/api/groupsCreate a new group
GET/api/groups/{id}Get group details
PUT/api/groups/{id}Update group configuration
DELETE/api/groups/{id}Delete a group
POST/api/groups/{id}/rebalanceTrigger group rebalance
POST/api/groups/{id}/membersAdd a member to the group
DELETE/api/groups/{id}/members/{member_id}Remove a member

Discovery

Note: All discovery endpoints return 404 when no discovery: block is configured. See the Discovery guide for setup.

MethodPathDescription
GET/api/discovery/sourcesList discovery sources
POST/api/discovery/sourcesRegister a new source
PUT/api/discovery/sources/{id}Update a source
DELETE/api/discovery/sources/{id}Remove a source
POST/api/discovery/sources/{id}/scanTrigger immediate scan
PUT/api/discovery/sources/{id}/enableEnable/disable a source
GET/api/discovery/pendingList MCP servers pending approval
GET/api/discovery/quarantinedList quarantined MCP servers
POST/api/discovery/approve/{name}Approve a pending MCP server
POST/api/discovery/reject/{name}Reject a pending MCP server

Configuration

MethodPathDescription
GET/api/configGet sanitized current configuration
POST/api/config/reloadTrigger hot-reload from disk
POST/api/config/exportExport current state as YAML
POST/api/config/backupCreate a rotating config backup
GET/api/config/diffDiff on-disk vs in-memory configuration

System

MethodPathDescription
GET/api/systemSystem info (uptime, version, metrics summary)

Auth Management (Enterprise)

MethodPathDescription
POST/api/auth/keysCreate an API key
GET/api/auth/keysList API keys
DELETE/api/auth/keys/{key_id}Revoke an API key
GET/api/auth/rolesList roles
POST/api/auth/rolesCreate a custom role
GET/api/auth/roles/allList all roles (including built-in)
POST/api/auth/roles/assignAssign a role to a principal
DELETE/api/auth/roles/revokeRevoke a role from a principal
GET/api/auth/roles/{role_name}Get role details
DELETE/api/auth/roles/{role_name}Delete a custom role
PATCH/api/auth/roles/{role_name}Update a custom role
GET/api/auth/principalsList principals
GET/api/auth/principals/rolesGet roles for a principal
GET/api/auth/permissionsList all permissions
POST/api/auth/check-permissionCheck if a principal has permission
GET/api/auth/policies/{scope}/{target_id}Get tool access policy
POST/api/auth/policies/{scope}/{target_id}Set tool access policy
DELETE/api/auth/policies/{scope}/{target_id}Clear tool access policy

Health Probes and Metrics

These endpoints are outside the /api/ prefix and skip authentication:

MethodPathDescription
GET/health/liveLiveness probe
GET/health/readyReadiness probe
GET/health/startupStartup probe
GET/metricsPrometheus metrics

WebSockets

PathDescription
/api/ws/eventsReal-time domain event stream (filterable)

See the WebSockets guide for connection details.

Examples

Create a MCP Server

curl -X POST http://localhost:8000/api/mcp_servers \
  -H "Content-Type: application/json" \
  -d '{
    "mcp_server_id": "my-llm",
    "mode": "subprocess",
    "command": ["python", "-m", "llm_server"],
    "idle_ttl_s": 600,
    "description": "LLM inference mcp_server"
  }'
{"mcp_server_id": "my-llm", "created": true}

Create a Group with Members

# Create group
curl -X POST http://localhost:8000/api/groups \
  -H "Content-Type: application/json" \
  -d '{
    "group_id": "llm-pool",
    "strategy": "round_robin",
    "min_healthy": 1
  }'

# Add members
curl -X POST http://localhost:8000/api/groups/llm-pool/members \
  -H "Content-Type: application/json" \
  -d '{"member_id": "my-llm", "weight": 1, "priority": 1}'

Export and Diff Configuration

# Export current state
curl -X POST http://localhost:8000/api/config/export

# See what changed vs disk
curl http://localhost:8000/api/config/diff

Register a Discovery Source

curl -X POST http://localhost:8000/api/discovery/sources \
  -H "Content-Type: application/json" \
  -d '{
    "source_type": "docker",
    "mode": "additive",
    "enabled": true,
    "config": {"socket_path": "/var/run/docker.sock"}
  }'

CORS

CORS is configured via environment variables:

VariableDefaultDescription
MCP_CORS_ORIGINS*Allowed origins (comma-separated)
MCP_CORS_METHODS*Allowed methods
MCP_CORS_HEADERS*Allowed headers

For production, restrict origins to your dashboard URL:

export MCP_CORS_ORIGINS="https://dashboard.example.com"

Error Handling

All domain exceptions are mapped to HTTP status codes:

ExceptionStatus Code
McpServerNotFoundError404
ValidationError422
RateLimitExceeded429
CompactionError500
Other MCPError500

The error envelope always contains error (exception class name), message, and status_code.

Full Reference

For complete request/response schemas, see the REST API Reference.