Skip to content

MCP Server ​

The MCP server publishes SeyalRun as Model Context Protocol tools and resources, so an AI agent can list hosts, read the audit log, or run an approved playbook — under the same permissions and audit trail as a human operator.

It ships as the mcp-server service and is routed by edge-proxy at /mcp.

Connecting ​

EndpointPOST https://<your-seyalrun-host>:8443/mcp
TransportStreamable HTTP, JSON-RPC 2.0 (single messages and batches)
Protocol version2025-06-18
AuthAuthorization: Bearer sr_<token> — a Personal Access Token
Server identityseyalrun

Point any streamable-HTTP MCP client at that URL with the token as its bearer credential. There is no SeyalRun-specific client library to install.

The auth handshake ​

A request with no bearer token gets a 401 carrying a WWW-Authenticate header that points at the protected-resource metadata document:

WWW-Authenticate: Bearer resource_metadata="https://host:8443/.well-known/oauth-protected-resource"
sh
curl -sk https://your-seyalrun-host:8443/.well-known/oauth-protected-resource
json
{
  "resource": "https://your-seyalrun-host:8443/mcp",
  "authorization_servers": ["https://your-seyalrun-host:8443"],
  "bearer_methods_supported": ["header"]
}

This is RFC 9728 discovery: a client that hits /mcp without credentials learns where the resource lives and who issues tokens for it. SeyalRun is its own authority — tokens come from Admin → Security, not from an external OAuth provider. There is no dynamic client registration and no browser consent flow; an admin issues a scoped token deliberately.

Try it with curl ​

sh
SR=https://your-seyalrun-host:8443
TOK=sr_your_scoped_token
H=(-H "Authorization: Bearer $TOK" -H 'Content-Type: application/json')

# 1. initialize
curl -sk -X POST "$SR/mcp" "${H[@]}" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize"}'

# 2. what can this token do?
curl -sk -X POST "$SR/mcp" "${H[@]}" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"whoami","arguments":{}}}'

# 3. list the tools
curl -sk -X POST "$SR/mcp" "${H[@]}" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/list"}'

# 4. use one (needs inventory:read)
curl -sk -X POST "$SR/mcp" "${H[@]}" \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"list_hosts","arguments":{}}}'

Supported methods: initialize, ping, tools/list, tools/call, resources/list, resources/read, and the notifications/initialized / notifications/cancelled notifications (answered with 202, no body).

What an agent should do first ​

Call whoami. It is the one tool with no scope requirement, and it returns the token's identity, role, and exact scope list — so an agent can discover what it's allowed to do instead of discovering it by collecting 403s.

Authorization failures ​

The MCP server authorizes nothing itself. A tool the token lacks the scope for is forwarded to api-gateway, which refuses it; the refusal comes back as a tool result with isError: true and the gateway's message:

json
{"content": [{"type": "text", "text": "{\"detail\":\"forbidden: token scope does not permit this action\"}"}],
 "isError": true}

That is the intended design: one security path, exercised identically whether the caller is a browser, a script, or an agent. Nothing about MCP is a bypass.

Architecture ​

AI agent ──MCP/JSON-RPC (Bearer sr_…)──▶ edge-proxy ──▶ mcp-server
                                                            │  same Bearer
                                                            ▼
                                                       api-gateway
                                              scopes ∩ role ∩ authorization
                                                   + audit chain row
                                                            │
                                                            ▼
                                              inventory / automation / …

mcp-server holds no database, no credentials, and no session state. It is a stateless translator from MCP call to REST call. If it were compromised it would gain nothing it cannot already do with the token it was handed.

Deployment ​

The service is part of the standard stack — nothing to enable:

Imageseyalrun-mcp-server
Port8110 (internal only; never published to the host)
EnvGATEWAY_URL — defaults to http://api-gateway:8000
HealthGET /health → {"status":"ok","tools":13}
Edge routes/mcp and /.well-known/oauth-protected-resource

The container runs read-only with a tmpfs /tmp, and waits for api-gateway to report healthy before starting.

It's defined in both the prebuilt-image compose file and the build-from-source one, so Quick Install and Manual Setup both get it. Under the internal-TLS overlay it serves HTTPS from its own certificate and calls api-gateway over HTTPS, like every other service.

Not exposing MCP at all ​

If you don't want an agent surface on a given deployment, remove the mcp-server service from your compose file — edge-proxy will then return a gateway error for /mcp, and every other part of SeyalRun is unaffected. The stricter control is simply to issue no tokens: with no PAT, /mcp answers 401 to everyone.

Next ​

Secure. Controlled. Automated. — Released under the Apache License 2.0.