Connect an MCP Server
This guide is for platform engineers who want to connect external MCP (Model Context Protocol) servers to Orloj. You will register an MCP server, verify tool discovery, selectively import tools, and assign them to agents.
Prerequisites
- Orloj server (
orlojd) running with--embedded-worker orlojctlavailable (orgo run ./cmd/orlojctl)- An MCP server to connect (stdio-based or remote HTTP)
If you have not set up Orloj yet, follow the Install and Quickstart guides first.
Background
MCP servers are external processes or services that expose tools via the Model Context Protocol. Unlike regular Orloj tools (which are 1:1 -- one resource, one capability), a single MCP server can provide many tools.
Orloj bridges this gap with the McpServer resource kind. When you register an MCP server, the controller:
- Connects using the configured transport (stdio or Streamable HTTP)
- Calls
tools/listto discover available tools - Auto-generates a
Toolresource (type=mcp) for each discovered tool - Keeps tools in sync on every reconcile cycle
Generated tools are first-class Tool resources. Agents reference them by name just like any other tool.
Step 1: Register an MCP Server (stdio)
Stdio MCP servers run as child processes. Orloj spawns the process, communicates via stdin/stdout using JSON-RPC 2.0, and manages its lifecycle.
Create a manifest (github-mcp.yaml):
apiVersion: orloj.dev/v1
kind: McpServer
metadata:
name: github-mcp
spec:
transport: stdio
command: npx @github/mcp-server
args:
- "--token-from-env"
env:
- name: GITHUB_TOKEN
secretRef: github-tokenCreate the secret for the token:
apiVersion: orloj.dev/v1
kind: Secret
metadata:
name: github-token
spec:
stringData:
value: ghp_your_github_token_hereApply both:
orlojctl apply -f github-token-secret.yaml
orlojctl apply -f github-mcp.yamlStep 2: Register an MCP Server (HTTP)
Remote MCP servers communicate over HTTP using the Streamable HTTP transport. Use this for MCP servers running as hosted services.
apiVersion: orloj.dev/v1
kind: McpServer
metadata:
name: remote-mcp
spec:
transport: http
endpoint: https://mcp.example.com/rpc
auth:
secretRef: mcp-api-key
profile: bearerApply:
orlojctl apply -f remote-mcp.yamlStep 3: Verify Tool Discovery
After applying, check the McpServer status:
orlojctl get mcp-serversNAME TRANSPORT STATUS TOOLS LAST_SYNCED
github-mcp stdio Ready 12 2025-03-18T14:30:00Z
remote-mcp http Ready 5 2025-03-18T14:30:05ZList the auto-generated tools:
orlojctl get toolsEach generated tool follows the naming convention {server}--{mcp-tool-name}:
NAME TYPE STATUS
github-mcp--create-issue mcp Ready
github-mcp--search-repos mcp Ready
github-mcp--list-prs mcp Ready
...Inspect a specific generated tool to see its rich schema:
orlojctl get tools github-mcp--create-issue -o jsonThe tool's spec.input_schema is populated directly from the MCP server's tools/list response. The model gateway uses this schema when formatting tool definitions for the LLM, giving it structured parameter information instead of the generic {input: string} fallback.
Step 4: Filter Tools (Optional)
By default, all tools discovered from an MCP server are imported. If a server exposes many tools and you only need a subset, use spec.tool_filter.include:
apiVersion: orloj.dev/v1
kind: McpServer
metadata:
name: github-mcp
spec:
transport: stdio
command: npx @github/mcp-server
args:
- "--token-from-env"
env:
- name: GITHUB_TOKEN
secretRef: github-token
tool_filter:
include:
- create_issue
- search_reposOnly the listed tools will be generated as Tool resources. Tools not in the allowlist are still discovered (visible in status.discoveredTools) but are not imported.
Re-apply the manifest to update:
orlojctl apply -f github-mcp.yamlTools that were previously generated but are no longer in the allowlist are automatically deleted on the next reconcile cycle.
Step 5: Assign Tools to an Agent
Generated MCP tools are referenced by name in agent.spec.tools, exactly like any other tool:
apiVersion: orloj.dev/v1
kind: Agent
metadata:
name: github-agent
spec:
model_ref: openai-default
prompt: |
You are a GitHub assistant. Use your tools to help
the user manage issues and search repositories.
tools:
- github-mcp--create-issue
- github-mcp--search-repos
limits:
max_steps: 8
timeout: 60sApply and submit a task:
orlojctl apply -f github-agent.yamlWhen the agent runs, the LLM sees the rich tool schemas from the MCP server and can call tools with structured arguments. The GovernedToolRuntime automatically routes type=mcp tools through the MCPToolRuntime, which sends tools/call to the MCP server via the session manager.
Step 6: Configure Reconnection (Optional)
MCP server connections can drop. The reconnect policy controls how aggressively Orloj retries:
spec:
reconnect:
max_attempts: 5
backoff: 2sDefaults: 3 attempts with 2s backoff. If all attempts fail, the McpServer enters the Error phase. The controller retries on the next reconcile cycle.
How It Works
The data flow for an MCP tool call:
Agent step
→ GovernedToolRuntime (policy, timeout, retry)
→ MCPToolRuntime (resolves mcp_server_ref)
→ McpSessionManager (connection pool)
→ McpTransport (stdio or HTTP)
→ MCP Server (tools/call JSON-RPC 2.0)Key implementation details:
- Session pooling: One session per McpServer. Sessions are reused across tool calls and reconcile cycles.
- Schema propagation:
spec.input_schemaandspec.descriptionfrom tool discovery flow through to the model gateway, so the LLM gets rich parameter definitions. - Garbage collection: Generated tools carry an
orloj.dev/mcp-serverlabel. When an MCP server is deleted, all its generated tools are cleaned up. - Governance: MCP tools participate in the full governance pipeline. You can create
ToolPermissionandAgentRoleresources for them, same as any other tool.
McpServer Spec Reference
| Field | Description |
|---|---|
transport | Required. stdio or http. |
command | stdio: command to spawn the MCP server process. |
args | stdio: command arguments. |
env | stdio: environment variables. Each entry has name, value (literal), or secretRef (resolved from Secret resource). |
endpoint | http: the MCP server URL. |
auth.secretRef | http: secret for authentication. |
auth.profile | http: auth profile (bearer, api_key_header). Defaults to bearer. |
tool_filter.include | Optional allowlist of MCP tool names to import. When empty, all tools are imported. |
reconnect.max_attempts | Max reconnection attempts. Defaults to 3. |
reconnect.backoff | Backoff duration between attempts. Defaults to 2s. |
Status Fields
| Field | Description |
|---|---|
phase | Pending, Connecting, Ready, or Error. |
discoveredTools | All tool names from tools/list, regardless of filter. |
generatedTools | Tool resource names actually created. |
lastSyncedAt | Timestamp of last successful reconcile. |
lastError | Last error message, if any. |
Next Steps
- Tools and Isolation -- concept deep-dive on tool types and isolation modes
- Build a Custom Tool -- for non-MCP tools that need custom implementation
- Set Up Multi-Agent Governance -- enforce authorization on MCP tools
- Resource Reference -- full spec for all resource kinds