Packages

An Elixir client library for the Anthropic API, providing comprehensive support for Claude models including Messages API, Batches API, streaming, tool calling, prompt caching, and vision capabilities.

Current section

Files

Jump to
claudio lib claudio mcp adapters mcp_ex.ex
Raw

lib/claudio/mcp/adapters/mcp_ex.ex

defmodule Claudio.MCP.Adapters.MCPEx do
@moduledoc """
Adapter for the mcp_ex library.
Requires `{:mcp_ex, "~> 0.3"}` in your dependencies.
## Usage
{:ok, client} = MCPEx.Client.start_link(transport: :stdio, command: "server")
{:ok, tools} = Claudio.MCP.Adapters.MCPEx.list_tools(client)
"""
@behaviour Claudio.MCP.Client
alias Claudio.MCP.Client.{Tool, Resource, Prompt}
@impl true
def list_tools(client, opts \\ []) do
cursor = Keyword.get(opts, :cursor)
with {:ok, response} <- do_call(:list_tools, [client, cursor]) do
tools =
(response[:tools] || response["tools"] || [])
|> Enum.map(&normalize_tool/1)
{:ok, tools}
end
end
@impl true
def call_tool(client, name, args, _opts \\ []) do
do_call(:call_tool, [client, name, args])
end
@impl true
def list_resources(client, opts \\ []) do
cursor = Keyword.get(opts, :cursor)
with {:ok, response} <- do_call(:list_resources, [client, cursor]) do
resources =
(response[:resources] || response["resources"] || [])
|> Enum.map(&normalize_resource/1)
{:ok, resources}
end
end
@impl true
def read_resource(client, uri, _opts \\ []) do
do_call(:read_resource, [client, uri])
end
@impl true
def list_prompts(client, opts \\ []) do
cursor = Keyword.get(opts, :cursor)
with {:ok, response} <- do_call(:list_prompts, [client, cursor]) do
prompts =
(response[:prompts] || response["prompts"] || [])
|> Enum.map(&normalize_prompt/1)
{:ok, prompts}
end
end
@impl true
def get_prompt(client, name, args \\ %{}, _opts \\ []) do
do_call(:get_prompt, [client, name, args])
end
@impl true
def ping(client, opts \\ []) do
timeout = Keyword.get(opts, :timeout, 5_000)
case do_call(:ping, [client, timeout]) do
{:ok, _} -> :ok
error -> error
end
end
defp do_call(function, args) do
apply(MCPEx.Client, function, args)
rescue
UndefinedFunctionError ->
{:error, :mcp_ex_not_available}
end
defp normalize_tool(tool) when is_map(tool) do
%Tool{
name: get_field(tool, :name, "name"),
description: get_field(tool, :description, "description"),
input_schema:
get_field(tool, :inputSchema, "inputSchema") ||
get_field(tool, :input_schema, "input_schema") || %{}
}
end
defp normalize_resource(resource) when is_map(resource) do
%Resource{
uri: get_field(resource, :uri, "uri"),
name: get_field(resource, :name, "name"),
description: get_field(resource, :description, "description"),
mime_type:
get_field(resource, :mimeType, "mimeType") ||
get_field(resource, :mime_type, "mime_type")
}
end
defp normalize_prompt(prompt) when is_map(prompt) do
%Prompt{
name: get_field(prompt, :name, "name"),
description: get_field(prompt, :description, "description"),
arguments: get_field(prompt, :arguments, "arguments") || []
}
end
defp get_field(map, atom_key, string_key) do
map[atom_key] || map[string_key]
end
end