earl

AI Agent Integration (MCP)

Use earl templates as tools in AI agents via the Model Context Protocol

Earl implements a Model Context Protocol (MCP) server (protocol version 2024-11-05), letting AI agents discover and invoke your API templates as native tools.

earl mcp [stdio|http] [--mode full|discovery] [--listen ADDR] [--yes] [--allow-unauthenticated]

Modes

Earl exposes templates to agents in two modes. Choose the one that fits your template library size and agent capabilities.

Full Mode

earl mcp stdio --mode full

Every template in the catalog becomes a separate MCP tool. The agent sees all tools in its tools/list response and can call any of them directly.

Best when you have a small number of templates (under ~30) and want the agent to see everything at once.

Discovery Mode

earl mcp stdio --mode discovery

Instead of exposing every template, discovery mode registers only two meta-tools:

earl.tool_search — Find matching templates by natural-language query.

ParameterTypeRequiredDefaultDescription
querystringYesNatural-language intent to match against metadata
limitintegerNo10Maximum matches to return (1–50)
modestringNoFilter by read or write
providerstringNoFilter by provider name (e.g., github)
categorystringNoFilter by category

Returns a ranked list of matching tools with name, score, summary, mode, categories, and the full tool schema.

earl.tool_call — Execute a discovered template tool.

ParameterTypeRequiredDefaultDescription
namestringYesExact tool name returned by earl.tool_search
argumentsobjectNo{}Arguments for the selected template tool

In discovery mode, the server also returns an instructions field during initialization that guides the agent to use the two-step search-then-call workflow.

Full vs Discovery Trade-offs

ConcernFullDiscovery
Context window costOne tool definition per templateAlways two tool definitions
LatencySingle tool callTwo calls (search + invoke)
ScalabilityDegrades with hundreds of templatesConstant overhead regardless of catalog size
Agent compatibilityWorks with any MCP clientRequires agent capable of multi-step tool use

Discovery mode is recommended when your catalog exceeds ~30 templates. The search scoring considers tool names, titles, summaries, descriptions, categories, and parameter names.

Claude Desktop

Add earl to your claude_desktop_config.json:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "earl": {
      "command": "earl",
      "args": ["mcp", "stdio", "--mode", "full", "--yes"]
    }
  }
}
{
  "mcpServers": {
    "earl": {
      "command": "earl",
      "args": ["mcp", "stdio", "--mode", "discovery", "--yes"]
    }
  }
}

If earl was installed via cargo install, Claude Desktop may not find it on PATH. Use the full binary path instead. Find it with which earl (macOS/Linux) or where earl (Windows):

{
  "mcpServers": {
    "earl": {
      "command": "/absolute/path/to/earl",
      "args": ["mcp", "stdio", "--mode", "full", "--yes"]
    }
  }
}

Claude Code

Add earl as an MCP server in your Claude Code settings (.claude/settings.json or ~/.claude/settings.json):

{
  "mcpServers": {
    "earl": {
      "command": "earl",
      "args": ["mcp", "stdio", "--mode", "discovery", "--yes"]
    }
  }
}

Discovery mode is recommended for Claude Code since it keeps the tool list small and avoids consuming the agent's context window.

Transports

Stdio

The default transport. Earl reads JSON-RPC requests from stdin and writes responses to stdout.

earl mcp stdio --mode full --yes

The stdio transport supports two framing formats:

  • Content-Length framing — HTTP-style headers (Content-Length: N\r\n\r\n<body>). This is the format earl uses when writing responses.
  • Line-delimited JSON — One JSON object per line (newline-terminated). Earl accepts this as input for compatibility with simpler clients.

Both formats can be mixed on the input side; earl auto-detects which format each incoming message uses.

HTTP

For non-stdio integrations, earl can serve MCP over HTTP:

earl mcp http --listen 127.0.0.1:8977 --mode full --yes --allow-unauthenticated
EndpointMethodDescription
/mcpPOSTJSON-RPC endpoint for MCP requests
/healthGETHealth check — returns 204 No Content

The --listen flag defaults to 127.0.0.1:8977.

The HTTP transport requires authentication by default. You must either configure JWT authentication (see Authentication below) or explicitly pass --allow-unauthenticated to opt out. The two options are mutually exclusive — earl will refuse to start if both are set.

Authentication

When using the HTTP transport, earl supports JWT-based authentication to control who can access your MCP tools.

JWT Configuration

Add an [auth.jwt] section to your config file (~/.config/earl/config.toml):

[auth.jwt]
audience = "https://api.example.com"
issuer = "https://accounts.example.com"
jwks_uri = "https://accounts.example.com/.well-known/jwks.json"

Alternatively, use OIDC discovery to auto-resolve the issuer and JWKS URI:

[auth.jwt]
audience = "https://api.example.com"
oidc_discovery_url = "https://accounts.example.com/.well-known/openid-configuration"
FieldTypeRequiredDefaultDescription
audiencestringYesExpected aud claim in the JWT
oidc_discovery_urlstringIf issuer/jwks_uri not setOIDC discovery endpoint to resolve issuer and JWKS URI
issuerstringIf oidc_discovery_url not setExpected iss claim in the JWT
jwks_uristringIf oidc_discovery_url not setURL to fetch the JSON Web Key Set for token verification
algorithmsstring[]No["RS256"]Allowed signing algorithms (RS256, RS384, RS512, ES256, ES384, PS256, PS384, PS512, EdDSA)
clock_skew_secondsintegerNo30Maximum clock skew tolerance in seconds (capped at 300)
jwks_cache_max_age_secondsintegerNo900How long to cache JWKS keys before refreshing

When JWT is configured, clients must include a Bearer token in the Authorization header. The token must contain exp, sub, iss, and aud claims. The sub claim identifies the authenticated subject for policy evaluation.

earl mcp http --listen 127.0.0.1:8977 --mode full --yes

Unauthenticated Access

For development or trusted environments, you can skip authentication:

earl mcp http --listen 127.0.0.1:8977 --allow-unauthenticated

Using --allow-unauthenticated is not recommended for production. Without authentication, anyone who can reach the server can call your tools.

Policy Engine

When JWT authentication is enabled, you can define access control policies that restrict which subjects can call which tools. Policies are defined as [[policy]] entries in your config file.

[[policy]]
subjects = ["user:alice", "group:admins"]
tools = ["github.*"]
effect = "allow"

[[policy]]
subjects = ["*"]
tools = ["github.delete_repo"]
modes = ["write"]
effect = "deny"
FieldTypeRequiredDescription
subjectsstring[]YesJWT sub values to match (supports * glob)
toolsstring[]YesTool name patterns to match (supports * glob per segment)
modesstring[]NoRestrict to read and/or write tools (omit for both)
effectstringYesallow or deny

Evaluation Rules

Policies use a deny-overrides model:

  1. All matching policies (by subject, tool, and mode) are collected.
  2. If any matching policy has effect = "deny", the call is denied.
  3. If any matching policy has effect = "allow" (and none deny), the call is allowed.
  4. If no policies match, the call is denied (default deny).

Glob Patterns

The * wildcard matches any characters within a single segment (separated by .). A lone * matches everything.

PatternMatchesDoes Not Match
github.*github.create_issueslack.send_message
*.delete_*github.delete_repogithub.admin.delete
*any tool

Policies only apply to authenticated requests. Unauthenticated requests (when using --allow-unauthenticated) bypass the policy engine entirely and are gated only by the --yes flag for write-mode tools.

Write-Mode Safety

Write-mode tools (templates with annotations.mode = "write") are blocked by default. When a write-mode tool is called without opt-in, the server returns an error:

  • Error code: -32001
  • Message: write-mode tools are disabled on this server instance

Pass --yes when starting the server to allow write-mode tool execution:

earl mcp stdio --mode full --yes

This prevents agents from performing destructive actions without explicit operator opt-in.

Troubleshooting

Run earl doctor to validate templates and configuration before starting the MCP server.

Earl logs errors to stderr. To capture logs when running as an MCP server, redirect stderr to a file in your shell before launching, or check your MCP client's server log output.

earl mcp stdio --mode full --yes 2>/tmp/earl-mcp.log

On this page