MCP Integration

Connecting MCP servers to Orchid agents: none, passthrough, and OAuth auth modes.

Orchid agents can call any MCP server over Streamable HTTP or SSE transport. The connection is configured per-server in agents.yaml; the framework handles capability discovery, caching, and per-user authentication transparently.

The MCP client interface

OrchidMCPClient in orchid_ai/core/mcp.py combines two narrower ABCs:

  • OrchidMCPToolCaller — code that only invokes tools depends on this
  • OrchidMCPDiscoverable — code that discovers capabilities depends on this

StreamableHttpMCPClient in orchid_ai/mcp/client.py is the concrete implementation. It keeps an in-memory capability cache that is populated once (proactively at startup or session-start) and flushed only via explicit invalidate_cache() calls.

Three auth modes

Each MCP server declaration carries exactly one field under auth: — the mode. No credentials, no endpoints, no client IDs live in config.

mcp_servers:
- name: public-weather
  url: https://weather.example.com/mcp
  # auth defaults to: mode: none

- name: tenant-catalog
  url: https://catalog.example.com/mcp
  auth:
    mode: passthrough

- name: external-crm
  url: https://crm.example.com/mcp
  auth:
    mode: oauth
ModeBehaviour
none (default)No auth headers. For local or public servers.
passthroughForwards the graph's OrchidAuthContext bearer token on every call. The MCP server and Orchid share the same identity provider.
oauthFull MCP 2025-03-26 flow. On the first 401 the framework discovers everything — protected resource metadata, authorization server metadata, and dynamic client registration — and stores per-user tokens in OrchidMCPTokenStore. See OAuth & Authentication.

cache_ttl is rejected

OrchidMCPServerConfig is declared with extra="forbid". Adding cache_ttl: to a server block raises a Pydantic validation error at startup. Capability caches have no TTL; they live for the process lifetime and are flushed via invalidate_cache() or OrchidSessionWarmer.invalidate_user().

Proactive capability warming

The framework warms MCP capability caches at well-defined boundaries so the per-request hot path never pays discovery cost:

BoundaryWhat gets warmed
Process startupEvery auth.mode: none server
User session start (POST /session/warm)Every passthrough and oauth server
Post-OAuth callbackThe freshly-authorised server

OrchidSessionWarmer drives all three boundaries. It is idempotent per (tenant_key, user_id) pair.

External reading