WardrikMCP (wardrik_mcp v0.1.0-rc.1)
Copy MarkdownGives WardrikCore agents the tools of any MCP server.
Start it with the servers it connects to:
children = [
{WardrikMCP,
name: MyApp.MCP,
servers: [
github: [
transport: {:stdio, command: "github-mcp-server", args: ["stdio"]},
only: ["search_issues", "create_issue"]
],
linear: [
transport:
{:streamable_http,
url: "https://mcp.linear.app/mcp",
headers: %{"authorization" => "Bearer " <> System.fetch_env!("LINEAR_TOKEN")}}
]
]}
]Then give an agent their tools as a WardrikCore.Capability:
WardrikCore.start_agent(
agent_id: "triage",
model: "anthropic:claude-haiku-4-5",
capabilities: [{WardrikMCP, name: MyApp.MCP, servers: [:github, :linear]}]
)The model sees each tool as github__search_issues, with the server's own description and JSON
Schema. See WardrikMCP.Server for every server option.
Use it when the tools an agent needs already exist as an MCP server.
Connections
Each server connects on its own. A server that's down offers no tools and doesn't block the others. It's retried with backoff, up to a minute between tries. When a server says its tools changed, they're listed again.
Annotations
Each tool carries the server's hints as WardrikCore.Tool annotations: read_only,
destructive, idempotent and open_world. A hint the server doesn't give isn't set.
- A read-only tool is also
idempotent. - A tool is
gatedunless it's read-only. The server'sgatedoption overrides this. - Answers are labelled
"outside"unless the server istrusted.
Errors
A call that fails transiently raises WardrikMCP.Unavailable. This covers a dropped connection,
a timeout or a server error. The tool runner then retries read-only and idempotent tools. See
WardrikCore.Retry.
An error the tool itself returns is passed to the model as the call's error.
Telemetry
[:wardrik_mcp, :tools] is emitted each time a server's tools change.
- Measurements:
:count, the number of tools the server offers.0while it's down. - Metadata:
:mcp, theWardrikMCPname, and:server, the server's name.
Summary
Functions
Adds the server name at runtime.
Returns a specification to start this module under a supervisor.
Re-reads the servers in the store now, picking up those added or removed on other nodes.
Removes the server name and closes every connection to it.
Returns the names of all servers, sorted.
Starts WardrikMCP and connects to each of its servers.
Returns the tools of the named servers.
Functions
Adds the server name at runtime.
Takes the same options as a server in :servers, but only as data, not functions. With a
:store, every node reaches it.
:ok =
WardrikMCP.add(MyApp.MCP, "linear",
transport: {:streamable_http, url: "https://mcp.linear.app/mcp"},
credential_name: "linear"
)
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec reconcile(atom()) :: :ok
Re-reads the servers in the store now, picking up those added or removed on other nodes.
Removes the server name and closes every connection to it.
Returns {:error, :not_found} if there's no such server, and {:error, reason} for a server
given in :servers.
Returns the names of all servers, sorted.
@spec start_link(keyword()) :: Supervisor.on_start()
Starts WardrikMCP and connects to each of its servers.
WardrikMCP.start_link(
name: MyApp.MCP,
servers: [github: [transport: {:stdio, command: "github-mcp-server", args: ["stdio"]}]],
store: store,
check: &MyApp.Egress.public/1
)Options
:name- required. The name agents and functions reach it by.:servers- servers to start with, as a keyword list of name and options. SeeWardrikMCP.Server.[]unless set.:store- aWardrikStorefor servers added at runtime. Without it,add/3only adds a server on this node.:reconcile- milliseconds between re-reads of the store, or:infinity.60_000unless set.:check- a function called on each URL of a server added at runtime. It returns:okor{:error, reason}. It's called when the server is added and each time a connection starts. With a check, runtime servers must use HTTP; commands are refused. Use one when users supply the URLs.
Returns the tools of the named servers.
Options
:name- required. TheWardrikMCPname.:servers- required. A server name or a list of them, as:githubor["github", "linear"].