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.