MCP/JSONRPC client GenServer.
Manages connection state (URL, auth tokens, request IDs, mTLS identity) and provides high-level methods for MCP protocol operations and DataGrout extensions.
Usage
{:ok, client} = DatagroutConduit.Client.start_link(
url: "https://gateway.datagrout.ai/servers/{uuid}/mcp",
auth: {:bearer, "token"}
)
{:ok, tools} = DatagroutConduit.Client.list_tools(client)
{:ok, result} = DatagroutConduit.Client.call_tool(client, "tool-name", %{arg: "val"})Options
:url- Remote server URL (required):auth- Authentication:{:bearer, token},{:api_key, key},{:basic, user, pass}, or{:oauth, pid}:transport-:mcp(default) or:jsonrpc:transport_mod- Override transport module directly (e.g. for testing):identity-%DatagroutConduit.Identity{}for mTLS (auto-discovered for DG URLs):use_intelligent_interface- Filter@-containing tools fromlist_tools(default:truefor DG URLs):name- GenServer registration name
Summary
Functions
Bootstrap an mTLS identity and start a client with it.
Bootstrap an mTLS identity using OAuth client_credentials.
Bootstrap by performing the autonomous DG onramp flow.
Calls a tool on the remote server.
Returns a specification to start this module under a supervisor.
Call any DataGrout first-party tool by its short name.
Semantic discovery: find tools matching a goal.
Estimate cost of calling a tool without executing it.
Gets a prompt with the given arguments.
Start or continue a guided execution session.
Lists prompts available on the remote server.
Lists resources available on the remote server.
Lists tools available on the remote server.
Execute a tool with DG extensions (demux, refract, chart).
Execute multiple tool calls in a single gateway request.
Plan tool execution for a goal using semantic discovery.
Reads a resource from the remote server.
Starts the client GenServer. See module docs for options.
Subscribe to a server-push topic (WebSocket transport only).
Cancel a server-side push subscription.
Types
@type auth() :: {:bearer, String.t()} | {:api_key, String.t()} | {:basic, String.t(), String.t()} | {:oauth, GenServer.server()} | nil
Functions
Bootstrap an mTLS identity and start a client with it.
Checks for an existing identity first. If found and not near expiry, starts a client with it. Otherwise generates a keypair, registers with DataGrout, saves the identity to disk, and starts a client.
Options
:url- Remote server URL (required):auth_token- Bearer token for registration (required for first run):name- Human-readable label (default:"conduit-client"):identity_dir- Directory to store identity files (default:~/.conduit/):endpoint- Registration endpoint (default: DG substrate endpoint):threshold_days- Days before expiry to trigger rotation (default: 7)- All other options are forwarded to
start_link/1
Bootstrap an mTLS identity using OAuth client_credentials.
Like bootstrap_identity/1 but performs the OAuth token exchange
inline instead of requiring a pre-obtained bearer token.
Options
:url- Remote server URL (required):client_id- OAuth client ID (required):client_secret- OAuth client secret (required):token_endpoint- OAuth token endpoint (derived from:urlif absent):scope- OAuth scope (optional)- All other options from
bootstrap_identity/1
Bootstrap by performing the autonomous DG onramp flow.
The all-in-one flow: onramp (no prior credentials required) → OAuth token exchange → mTLS identity registration and persistence.
On subsequent runs the saved mTLS identity is auto-discovered and no credentials are needed.
Options
:opts-%DatagroutConduit.Onramp.OnrampOptions{}(required):url- MCP server URL; required when the onramp response omitsmcp_url:name- Human-readable identity label (default:"conduit-client"):identity_dir- Custom directory for identity persistence- All other options from
bootstrap_identity/1
@spec call_tool(GenServer.server(), String.t(), map()) :: {:ok, DatagroutConduit.Types.ToolResult.t()} | {:error, term()}
Calls a tool on the remote server.
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec dg(GenServer.server(), String.t(), map()) :: {:ok, map()} | {:error, term()}
Call any DataGrout first-party tool by its short name.
The short name (e.g. "prism.render") is automatically prefixed with data-grout/.
DatagroutConduit.Client.dg(client, "prism.render", %{"payload" => data})
@spec discover( GenServer.server(), keyword() ) :: {:ok, DatagroutConduit.Types.DiscoverResult.t()} | {:error, term()}
Semantic discovery: find tools matching a goal.
@spec estimate_cost(GenServer.server(), String.t(), map()) :: {:ok, DatagroutConduit.Types.CreditEstimate.t()} | {:error, term()}
Estimate cost of calling a tool without executing it.
@spec get_prompt(GenServer.server(), String.t(), map()) :: {:ok, [DatagroutConduit.Types.PromptMessage.t()]} | {:error, term()}
Gets a prompt with the given arguments.
@spec guide( GenServer.server(), keyword() ) :: {:ok, DatagroutConduit.Types.GuideState.t()} | {:error, term()}
Start or continue a guided execution session.
Options
:goal- Natural language description (required for new sessions):session_id- Continue an existing session:choice- Make a choice in the current session
@spec list_prompts(GenServer.server()) :: {:ok, [DatagroutConduit.Types.Prompt.t()]} | {:error, term()}
Lists prompts available on the remote server.
@spec list_resources(GenServer.server()) :: {:ok, [DatagroutConduit.Types.Resource.t()]} | {:error, term()}
Lists resources available on the remote server.
@spec list_tools(GenServer.server()) :: {:ok, [DatagroutConduit.Types.Tool.t()]} | {:error, term()}
Lists tools available on the remote server.
@spec perform(GenServer.server(), String.t(), map(), keyword()) :: {:ok, DatagroutConduit.Types.ToolResult.t()} | {:error, term()}
Execute a tool with DG extensions (demux, refract, chart).
@spec perform_batch(GenServer.server(), [map()]) :: {:ok, list()} | {:error, term()}
Execute multiple tool calls in a single gateway request.
Each element should be a map with "tool" and "args" keys.
Returns a list of results in the same order as the input calls.
Example
calls = [
%{"tool" => "data-grout/data.count", "args" => %{"data" => [1, 2, 3]}},
%{"tool" => "data-grout/data.keys", "args" => %{"data" => %{"a" => 1}}}
]
{:ok, results} = Client.perform_batch(client, calls)
@spec plan( GenServer.server(), keyword() ) :: {:ok, map()} | {:error, term()}
Plan tool execution for a goal using semantic discovery.
At least one of :goal or :query must be provided.
Options
:goal- Natural language goal:query- Semantic search query:server- Restrict to a specific server:k- Number of candidates to consider:policy- Execution policy:have- Tools or data already available:return_call_handles- Include call handles in response:expose_virtual_skills- Include virtual skills in candidates:model_overrides- Override model selection
@spec read_resource(GenServer.server(), String.t()) :: {:ok, [DatagroutConduit.Types.ResourceContent.t()]} | {:error, term()}
Reads a resource from the remote server.
Starts the client GenServer. See module docs for options.
@spec subscribe(GenServer.server(), String.t()) :: {:ok, String.t()} | {:error, term()}
Subscribe to a server-push topic (WebSocket transport only).
Requires transport: :websocket when starting the client.
Events arrive as {:subscription_event, subscription_id, event} messages
in the calling process's mailbox, where event is a map with :event and
:data keys.
{:ok, sub_id} = DatagroutConduit.Client.subscribe(client, "agents.my-agent-id.events")
receive do
{:subscription_event, ^sub_id, %{event: e, data: d}} -> IO.inspect({e, d})
end
:ok = DatagroutConduit.Client.unsubscribe(client, sub_id)Returns {:ok, subscription_id} or {:error, :not_ws_transport}.
@spec unsubscribe(GenServer.server(), String.t()) :: :ok | {:error, term()}
Cancel a server-side push subscription.
Requires transport: :websocket. Returns :ok.