Client-side support for the Model Context Protocol.
Condukt agents and workflows can declare external MCP servers and call
the tools those servers expose alongside their own statically defined
tools. Each declared server is started as a supervised
Condukt.MCP.Client process for the lifetime of the session or workflow
run, the server's tools/list is fetched, and each remote tool is
exposed to the model as a prefixed entry in the tool registry
(<server>.<tool> by default).
Declaring servers on an agent
Add an optional mcp_servers/0 function to a module that uses
Condukt. Return a list of Condukt.MCP.Server structs or maps
describing the transport and (for HTTP transports) authentication.
defmodule MyApp.Agent do
use Condukt
@impl true
def tools do
[Condukt.Tools.Read, Condukt.Tools.Bash]
end
def mcp_servers do
[
%Condukt.MCP.Server{
name: "github",
transport: {:stdio, command: "github-mcp-server", args: []},
env: ["GITHUB_TOKEN"]
},
%Condukt.MCP.Server{
name: "linear",
transport: {:streamable_http, url: "https://mcp.linear.app/mcp"},
auth: {:bearer, {:env, "LINEAR_API_KEY"}}
}
]
end
endServers can also be supplied per-call through the :mcp_servers option
on Condukt.run/3 and through an agent module's start_link/1.
Declaring servers in HCL workflows
Workflows declare servers with top-level mcp_server blocks and
reference their tools from tool and agent steps using the prefixed
id:
mcp_server "linear" {
transport = "streamable_http"
url = "https://mcp.linear.app/mcp"
auth = {
type = "bearer"
env = "LINEAR_API_KEY"
}
}
tool "list_issues" {
id = "linear.list_issues"
args = { team_id = input.team }
}Authentication
v1 supports two HTTP authentication modes declared on the server:
{:bearer, secret_ref}adds anAuthorization: Bearer <token>header. The secret reference uses the same shape asCondukt.Secretsentries:{:env, "NAME"},{:static, "value"},{:op, "op://..."}, or{provider_module, opts}.{:client_credentials, opts}performs an OAuth 2.0 client credentials grant against:token_urlusing:client_id/:client_secret(or_envvariants) and caches the access token until a request fails with401, at which point it refreshes once.
Interactive OAuth flows that require a browser are intentionally not supported by the headless library. Resolve such tokens out of band (for example via a separate one-time CLI login) and surface the resulting refresh or access token through one of the provider shapes above.
For stdio transports the :auth field is unused; credentials flow
into the spawned subprocess as environment variables declared on the
server's :env field.
Sandbox interaction
Stdio MCP servers are user-configured external binaries that Condukt
spawns as part of session setup. They are not routed through
Condukt.Sandbox for the same reason Condukt.Tools.Command is
exempt: the binary is selected by the operator, not by the model.
HTTP and streamable HTTP transports issue plain HTTP requests through
Req and have nothing to sandbox.
Summary
Functions
Starts a list of MCP clients in parallel and returns a registry value describing the running connections and the tools they expose.
Starts an MCP client for the given server spec.
Stops the connections held by a registry value returned by start_all/2.
Returns the inline Condukt.Tool specs for every tool exposed by the
servers in a registry.
Functions
Starts a list of MCP clients in parallel and returns a registry value describing the running connections and the tools they expose.
The return value is opaque; pass it to Condukt.MCP.Registry.tools/1
to obtain the list of inline tool specs ready to be merged into an
agent or workflow tool list, and to Condukt.MCP.Registry.stop_all/1 for
cleanup.
Starts an MCP client for the given server spec.
This returns once the initialize handshake and tools/list exchange
have completed. Use Condukt.MCP.Client.call_tool/4 to invoke tools
on the connected server.
Stops the connections held by a registry value returned by start_all/2.
Returns the inline Condukt.Tool specs for every tool exposed by the
servers in a registry.