MCPEx.Client (MCPEx v0.1.0)

An implementation of the MCP client for Elixir.

This client provides a complete, spec-compliant implementation of the Model Context Protocol (MCP) client side, supporting version 2025-03-26 of the specification.

Features

  • Full protocol implementation with capability negotiation
  • Multiple transport options (stdio, HTTP)
  • Resource handling with subscriptions
  • Tool invocation support
  • Prompt template handling
  • Sampling interface for LLM interaction

Usage

# Create a new client connected to a server via stdio
{:ok, client} = MCPEx.Client.start_link(
  transport: :stdio,
  command: "/path/to/server",
  capabilities: [:sampling, :roots]
)

# Or with HTTP transport
{:ok, client} = MCPEx.Client.start_link(
  transport: :http,
  url: "https://example.com/mcp",
  capabilities: [:sampling, :roots]
)

# List available resources
{:ok, %{resources: resources}} = MCPEx.Client.list_resources(client)

# Read a specific resource
{:ok, %{contents: contents}} = MCPEx.Client.read_resource(client, "file:///path/to/resource")

# Call a tool
{:ok, result} = MCPEx.Client.call_tool(client, "get_weather", %{location: "New York"})

Summary

Types

Client options for initialization

t()

Client state

Functions

Calls a tool on the server.

Returns a specification to start this module under a supervisor.

Gets a specific prompt by name with optional parameters.

Returns the server capabilities negotiated during initialization.

Returns information about the connected server.

Lists available prompts from the server.

Lists available resource templates from the server.

Lists available resources from the server.

Lists available tools from the server.

Sends a ping to the server to check if it's still alive.

Reads the contents of a specific resource from the server.

Starts a new MCP client as a linked process.

Stops the client and terminates the connection.

Subscribes to updates for a specific resource.

Unsubscribes from updates for a specific resource.

Types

options()

@type options() :: [
  transport: :stdio | :http | pid(),
  command: String.t() | nil,
  url: String.t() | nil,
  capabilities: [atom()],
  client_info: map(),
  shell_type: :none | :interactive | :login | :plain
]

Client options for initialization

t()

@type t() :: pid()

Client state

Functions

call_tool(client, name, args)

@spec call_tool(t(), String.t(), map()) :: {:ok, map()} | {:error, term()}

Calls a tool on the server.

Parameters

  • name - The name of the tool to call
  • args - The arguments to pass to the tool

Returns

  • {:ok, result} - The result of the tool call
  • {:error, reason} - Failed to call the tool

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

get_prompt(client, name, args \\ %{})

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

Gets a specific prompt by name with optional parameters.

Parameters

  • name - The name of the prompt to get
  • args - Optional arguments to apply to the prompt template

Returns

  • {:ok, %{description: String.t(), messages: [...]}} - Successfully fetched prompt with messages
  • {:error, reason} - Failed to fetch prompt

get_server_capabilities(client)

@spec get_server_capabilities(t()) :: {:ok, map()} | {:error, term()}

Returns the server capabilities negotiated during initialization.

Returns

  • {:ok, map()} - Server capabilities
  • {:error, reason} - Failed to get capabilities

get_server_info(client)

@spec get_server_info(t()) :: {:ok, map()} | {:error, term()}

Returns information about the connected server.

Returns

  • {:ok, map()} - Server information
  • {:error, reason} - Failed to get server information

list_prompts(client, cursor \\ nil)

@spec list_prompts(t(), String.t() | nil) :: {:ok, map()} | {:error, term()}

Lists available prompts from the server.

Parameters

  • cursor - An optional pagination cursor for fetching the next page of results

Returns

  • {:ok, %{prompts: [...], next_cursor: cursor}} - Successfully fetched prompts
  • {:error, reason} - Failed to fetch prompts

list_resource_templates(client, cursor \\ nil)

@spec list_resource_templates(t(), String.t() | nil) ::
  {:ok, map()} | {:error, term()}

Lists available resource templates from the server.

Parameters

  • cursor - An optional pagination cursor for fetching the next page of results

Returns

  • {:ok, %{resource_templates: [...], next_cursor: cursor}} - Successfully fetched templates
  • {:error, reason} - Failed to fetch templates

list_resources(client, cursor \\ nil)

@spec list_resources(t(), String.t() | nil) :: {:ok, map()} | {:error, term()}

Lists available resources from the server.

Parameters

  • cursor - An optional pagination cursor for fetching the next page of results

Returns

  • {:ok, %{resources: [...], next_cursor: cursor}} - Successfully fetched resources
  • {:error, reason} - Failed to fetch resources

list_tools(client, cursor \\ nil)

@spec list_tools(t(), String.t() | nil) :: {:ok, map()} | {:error, term()}

Lists available tools from the server.

Parameters

  • cursor - An optional pagination cursor for fetching the next page of results

Returns

  • {:ok, %{tools: [...], next_cursor: cursor}} - Successfully fetched tools
  • {:error, reason} - Failed to fetch tools

ping(client, timeout \\ 5000)

@spec ping(t(), integer()) :: {:ok, map()} | {:error, term()}

Sends a ping to the server to check if it's still alive.

Parameters

  • client - The client process
  • timeout - Optional timeout in milliseconds (default: 5000)

Returns

  • {:ok, _} - The server responded to the ping
  • {:error, reason} - The ping failed

read_resource(client, uri)

@spec read_resource(t(), String.t()) :: {:ok, map()} | {:error, term()}

Reads the contents of a specific resource from the server.

Parameters

  • uri - The URI of the resource to read

Returns

  • {:ok, %{contents: [...]}} - Successfully read the resource
  • {:error, reason} - Failed to read the resource

start_link(options)

@spec start_link(options()) :: {:ok, t()} | {:error, term()}

Starts a new MCP client as a linked process.

Options

  • :transport - The transport mechanism to use (:stdio or :http)
  • :command - The command to run for stdio transport (required for stdio)
  • :url - The URL to connect to for HTTP transport (required for http)
  • :capabilities - A list of capabilities to advertise to the server
  • :client_info - Information about the client implementation (name, version)

Returns

  • {:ok, pid} - The client was started successfully
  • {:error, reason} - The client failed to start

stop(client)

@spec stop(t()) :: :ok

Stops the client and terminates the connection.

Returns

  • :ok - The client was stopped successfully

subscribe_to_resource(client, uri)

@spec subscribe_to_resource(t(), String.t()) :: :ok | {:error, term()}

Subscribes to updates for a specific resource.

Parameters

  • uri - The URI of the resource to subscribe to

Returns

  • :ok - Successfully subscribed
  • {:error, reason} - Failed to subscribe

unsubscribe_from_resource(client, uri)

@spec unsubscribe_from_resource(t(), String.t()) :: :ok | {:error, term()}

Unsubscribes from updates for a specific resource.

Parameters

  • uri - The URI of the resource to unsubscribe from

Returns

  • :ok - Successfully unsubscribed
  • {:error, reason} - Failed to unsubscribe