Test helpers for exercising Noizu.MCP.Server modules over an in-memory
transport — no sockets, async: true safe.
defmodule MyApp.MCPTest do
use ExUnit.Case, async: true
import Noizu.MCP.Test
setup do
%{client: connect(MyApp.MCP)}
end
test "weather tool", %{client: client} do
assert {:ok, result} = call_tool(client, "get_weather", %{"location" => "NYC"})
assert [%{type: :text}] = result.content
assert_progress(client)
end
endThe returned client handle is bound to the calling process: server output is
delivered to your mailbox and consumed by these helpers. Notifications that
arrive while awaiting a response are buffered and visible to
assert_notification/3 / assert_progress/2.
Summary
Functions
Assert the server emitted a notification with method; returns its params.
When match (a map) is given, every key/value in it must be present in the
notification params.
Assert the server emitted at least one notifications/progress; returns its params.
Await the response for a previously sent request id.
Call a tool. Returns {:ok, %ToolResult{}} | {:error, error_map}. Args use string keys.
Send notifications/cancelled for an in-flight request id.
Request completion values. ref is {:prompt, name} or
{:resource_template, uri_template}. Returns
{:ok, %{values: _, total: _, has_more: _}}.
Start a session against server (a use Noizu.MCP.Server module) and run
the initialize handshake. Starts the server's supervision tree if it is not
already running.
Send a raw wire binary (escape hatch for malformed-input tests).
Ensure server's supervision tree is running (shared across tests),
detached from the calling process. Safe under concurrent async: true
callers — waits until the tree is fully started before returning.
Get a prompt. Returns {:ok, %{description: _, messages: [%PromptMessage{}]}}.
Args use string keys.
List all prompts (auto-paginates). Returns {:ok, [%Prompt{}]}.
List all resource templates (auto-paginates).
List all resources (auto-paginates). Returns {:ok, [%Resource{}]}.
List all tools (auto-paginates). Returns {:ok, [%Tool{}]} | {:error, error_map}.
Send a notification to the server.
Read a resource. Returns {:ok, [%ResourceContents{}]} | {:error, error_map}.
Assert no notification with method arrives within opts[:timeout] (default 100ms).
Send a request and await its result. Returns {:ok, result} | {:error, error_map}.
Send a request and return its id without awaiting the response.
Set the MCP log level for this session.
Subscribe to resource update notifications for uri.
Unsubscribe from resource update notifications for uri.
Functions
@spec assert_notification( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, String.t(), map() | nil, keyword() ) :: map() | nil
Assert the server emitted a notification with method; returns its params.
When match (a map) is given, every key/value in it must be present in the
notification params.
@spec assert_progress( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, keyword() ) :: map()
Assert the server emitted at least one notifications/progress; returns its params.
@spec await( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, integer(), keyword() ) :: {:ok, map()} | {:error, map()}
Await the response for a previously sent request id.
@spec call_tool( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, String.t(), map(), keyword() ) :: {:ok, Noizu.MCP.Types.ToolResult.t()} | {:error, map()}
Call a tool. Returns {:ok, %ToolResult{}} | {:error, error_map}. Args use string keys.
@spec cancel( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, integer(), String.t() | nil ) :: :ok
Send notifications/cancelled for an in-flight request id.
@spec complete( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, tuple(), String.t(), String.t() ) :: {:ok, map()} | {:error, map()}
Request completion values. ref is {:prompt, name} or
{:resource_template, uri_template}. Returns
{:ok, %{values: _, total: _, has_more: _}}.
@spec connect( module(), keyword() ) :: %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }
Start a session against server (a use Noizu.MCP.Server module) and run
the initialize handshake. Starts the server's supervision tree if it is not
already running.
Options: :client_info (map), :client_capabilities (wire-format map),
:protocol_version.
@spec deliver_raw( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, binary() ) :: :ok
Send a raw wire binary (escape hatch for malformed-input tests).
@spec ensure_server_started(module()) :: :ok
Ensure server's supervision tree is running (shared across tests),
detached from the calling process. Safe under concurrent async: true
callers — waits until the tree is fully started before returning.
@spec get_prompt( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, String.t(), map(), keyword() ) :: {:ok, map()} | {:error, map()}
Get a prompt. Returns {:ok, %{description: _, messages: [%PromptMessage{}]}}.
Args use string keys.
@spec list_prompts( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, keyword() ) :: {:ok, [Noizu.MCP.Types.Prompt.t()]} | {:error, map()}
List all prompts (auto-paginates). Returns {:ok, [%Prompt{}]}.
@spec list_resource_templates( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, keyword() ) :: {:ok, [Noizu.MCP.Types.ResourceTemplate.t()]} | {:error, map()}
List all resource templates (auto-paginates).
@spec list_resources( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, keyword() ) :: {:ok, [Noizu.MCP.Types.Resource.t()]} | {:error, map()}
List all resources (auto-paginates). Returns {:ok, [%Resource{}]}.
@spec list_tools( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, keyword() ) :: {:ok, [Noizu.MCP.Types.Tool.t()]} | {:error, map()}
List all tools (auto-paginates). Returns {:ok, [%Tool{}]} | {:error, error_map}.
@spec notify( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, String.t(), map() | nil ) :: :ok
Send a notification to the server.
@spec read_resource( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, String.t(), keyword() ) :: {:ok, [Noizu.MCP.Types.ResourceContents.t()]} | {:error, map()}
Read a resource. Returns {:ok, [%ResourceContents{}]} | {:error, error_map}.
@spec refute_notification( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, String.t(), keyword() ) :: :ok
Assert no notification with method arrives within opts[:timeout] (default 100ms).
@spec request( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, String.t(), map() | nil, keyword() ) :: {:ok, map()} | {:error, map()}
Send a request and await its result. Returns {:ok, result} | {:error, error_map}.
@spec send_request( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, String.t(), map() | nil ) :: integer()
Send a request and return its id without awaiting the response.
@spec set_log_level( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, atom() | String.t() ) :: {:ok, map()} | {:error, map()}
Set the MCP log level for this session.
@spec subscribe( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, String.t() ) :: {:ok, map()} | {:error, map()}
Subscribe to resource update notifications for uri.
@spec unsubscribe( %Noizu.MCP.Test.Client{ capabilities: term(), counter: term(), instructions: term(), ref: term(), server: term(), server_info: term(), session: term() }, String.t() ) :: {:ok, map()} | {:error, map()}
Unsubscribe from resource update notifications for uri.