Noizu.MCP.Client (Noizu MCP v0.1.1)

Copy Markdown View Source

MCP client: connect to an MCP server over a transport and call its tools, resources, and prompts.

children = [
  {Noizu.MCP.Client,
   name: MyApp.FS,
   transport:
     {:stdio,
      command: "npx",
      args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]},
   client_info: %{name: "my_app", version: "1.0.0"},
   handler: MyApp.MCPHandler,
   roots: [Noizu.MCP.Types.Root.new("file:///workspace", name: "Workspace")]}
]

{:ok, tools} = Noizu.MCP.Client.list_tools(MyApp.FS)
{:ok, result} = Noizu.MCP.Client.call_tool(MyApp.FS, "read_file", %{"path" => "/tmp/a"})

Options

  • :transport (required) — {:stdio, command: "...", args: [...], env: %{}, cd: "..."} to spawn a subprocess, {:test, server: MyServer} for an in-memory connection to a Noizu.MCP.Server in the same VM, or {module, opts} for a custom Noizu.MCP.Transport.Client implementation
  • :name — optional registered name
  • :client_info%{name: _, version: _} advertised to the server
  • :handlermodule or {module, arg} implementing Noizu.MCP.Client.Handler; implemented callbacks advertise the sampling/elicitation capabilities
  • :roots — initial Noizu.MCP.Types.Root list (advertises the roots capability); update later with set_roots/2
  • :on_notification — pid mirrored every server notification as {:mcp_notification, method, params}
  • :request_timeout — default per-request timeout in ms (30_000)

Calls made before the handshake completes are queued and dispatched once the connection is ready. Per-call :timeout overrides auto-cancel the request (notifications/cancelled) on expiry. Pass progress: fun/1 to receive progress notifications for a call.

Summary

Functions

Issue a request without blocking; returns a reference for await/3 / cancel/3.

Block until the initialize handshake completes.

Call a tool. Returns {:ok, %ToolResult{}}. Args use string keys.

Cancel an async/4 request (notifications/cancelled).

Returns a specification to start this module under a supervisor.

Close the connection.

Request completion values. ref is {:prompt, name} or {:resource_template, uri_template}.

Get a prompt. Returns {:ok, %{description: _, messages: [%PromptMessage{}]}}.

The server's instructions string, if any.

List all prompts (auto-paginates).

List all resource templates (auto-paginates).

List all resources (auto-paginates).

List all tools (auto-paginates; pass page: cursor for manual paging).

Send a one-way notification to the server.

Ping the server.

Read a resource. Returns {:ok, [%ResourceContents{}]}.

Issue a raw MCP request. Returns {:ok, result_map} | {:error, reason} where reason is a Noizu.MCP.Error, :timeout, or :closed.

The server's negotiated capabilities (wire-format map).

The server's Implementation info (after ready).

Set the server's log level for this session.

Replace the advertised roots and emit notifications/roots/list_changed.

Subscribe to update notifications for a resource URI.

Unsubscribe from update notifications for a resource URI.

Functions

async(client, method, params \\ nil, opts \\ [])

@spec async(GenServer.server(), String.t(), map() | nil, keyword()) :: {:ok, term()}

Issue a request without blocking; returns a reference for await/3 / cancel/3.

await(client, ref, timeout \\ :infinity)

@spec await(GenServer.server(), term(), timeout()) :: {:ok, map()} | {:error, term()}

Await an async/4 request.

await_ready(client, timeout \\ 10000)

@spec await_ready(GenServer.server(), timeout()) :: :ok | {:error, term()}

Block until the initialize handshake completes.

call_tool(client, name, args \\ %{}, opts \\ [])

@spec call_tool(GenServer.server(), String.t(), map(), keyword()) ::
  {:ok, Noizu.MCP.Types.ToolResult.t()} | {:error, term()}

Call a tool. Returns {:ok, %ToolResult{}}. Args use string keys.

cancel(client, ref, reason \\ nil)

@spec cancel(GenServer.server(), term(), String.t() | nil) :: :ok

Cancel an async/4 request (notifications/cancelled).

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

close(client)

@spec close(GenServer.server()) :: :ok

Close the connection.

complete(client, ref, arg_name, value)

@spec complete(GenServer.server(), tuple(), String.t(), String.t()) ::
  {:ok, map()} | {:error, term()}

Request completion values. ref is {:prompt, name} or {:resource_template, uri_template}.

get_prompt(client, name, args \\ %{}, opts \\ [])

@spec get_prompt(GenServer.server(), String.t(), map(), keyword()) ::
  {:ok, map()} | {:error, term()}

Get a prompt. Returns {:ok, %{description: _, messages: [%PromptMessage{}]}}.

instructions(client)

@spec instructions(GenServer.server()) :: String.t() | nil

The server's instructions string, if any.

list_prompts(client, opts \\ [])

@spec list_prompts(
  GenServer.server(),
  keyword()
) :: {:ok, [Noizu.MCP.Types.Prompt.t()]} | {:error, term()}

List all prompts (auto-paginates).

list_resource_templates(client, opts \\ [])

@spec list_resource_templates(
  GenServer.server(),
  keyword()
) :: {:ok, [Noizu.MCP.Types.ResourceTemplate.t()]} | {:error, term()}

List all resource templates (auto-paginates).

list_resources(client, opts \\ [])

@spec list_resources(
  GenServer.server(),
  keyword()
) :: {:ok, [Noizu.MCP.Types.Resource.t()]} | {:error, term()}

List all resources (auto-paginates).

list_tools(client, opts \\ [])

@spec list_tools(
  GenServer.server(),
  keyword()
) :: {:ok, [Noizu.MCP.Types.Tool.t()]} | {:error, term()}

List all tools (auto-paginates; pass page: cursor for manual paging).

notify(client, method, params \\ nil)

@spec notify(GenServer.server(), String.t(), map() | nil) :: :ok

Send a one-way notification to the server.

ping(client)

@spec ping(GenServer.server()) :: :ok | {:error, term()}

Ping the server.

read_resource(client, uri, opts \\ [])

@spec read_resource(GenServer.server(), String.t(), keyword()) ::
  {:ok, [Noizu.MCP.Types.ResourceContents.t()]} | {:error, term()}

Read a resource. Returns {:ok, [%ResourceContents{}]}.

request(client, method, params \\ nil, opts \\ [])

@spec request(GenServer.server(), String.t(), map() | nil, keyword()) ::
  {:ok, map()} | {:error, term()}

Issue a raw MCP request. Returns {:ok, result_map} | {:error, reason} where reason is a Noizu.MCP.Error, :timeout, or :closed.

server_capabilities(client)

@spec server_capabilities(GenServer.server()) :: map() | nil

The server's negotiated capabilities (wire-format map).

server_info(client)

@spec server_info(GenServer.server()) :: Noizu.MCP.Types.Implementation.t() | nil

The server's Implementation info (after ready).

set_log_level(client, level)

@spec set_log_level(GenServer.server(), atom() | String.t()) :: :ok | {:error, term()}

Set the server's log level for this session.

set_roots(client, roots)

@spec set_roots(GenServer.server(), [Noizu.MCP.Types.Root.t()]) :: :ok

Replace the advertised roots and emit notifications/roots/list_changed.

start_link(opts)

subscribe_resource(client, uri)

@spec subscribe_resource(GenServer.server(), String.t()) :: :ok | {:error, term()}

Subscribe to update notifications for a resource URI.

unsubscribe_resource(client, uri)

@spec unsubscribe_resource(GenServer.server(), String.t()) :: :ok | {:error, term()}

Unsubscribe from update notifications for a resource URI.