ExMCP
    
模型上下文协议(MCP)和代理客户端协议(ACP)的完整Elixir实现
______________________________________________________________________
概述
ExMCP是Elixir的全面实施 模型上下文协议 和那个 代理客户端协议,使人工智能模型能够通过标准化协议与本地和远程资源安全交互。它为客户端和服务器实现提供了多种传输选项,包括通过Plug兼容性进行本机Phoenix集成,以及通过ACP控制Gemini CLI、Claude Code和Codex等编码代理的能力。
主要特点
- 完全符合MCP --协议版本2024-11-05、2025-03-26、2025-06-18和2025-11-25
- 100%MCP合规性 --223/223客户端检查,39/39服务器检查(官方测试套件)
- 多个传输 --HTTP/SSE、stdio和本机BEAM(约15μs本地调用)
- 凤凰插头 --本地凤凰城与
ExMCP.HttpPlug - DSL和处理程序API --声明性工具/资源/提示定义或基于回调的处理程序
- OAuth 2.1 --自动401→发现→PKCE→令牌流、作用域升级、CIMD、JWT客户端身份验证(
private_key_jwt)、企业SSO(ID-JAG)、令牌撤销(RFC 7009)、可插拔身份验证提供者 - OTP本机 --监控树、指数回退自动重连、88个遥测事件
- 代理客户端协议(ACP) --控制任何运输的编码代理(Gemini CLI、Claude Code、Codex、Pi、Hermes等)
- 3100+次测试 --全面的套件,包括官方MCP合规性、集成和性能
安装
添加 ex_mcp 您的依赖关系 mix.exs:
def deps do
[
{:ex_mcp, "~> 0.9.0"}
]
end快速开始
凤凰集成
将MCP服务器功能添加到您的Phoenix应用程序中:
# In your Phoenix router
defmodule MyAppWeb.Router do
use MyAppWeb, :router
scope "/api/mcp" do
forward "/", ExMCP.HttpPlug,
handler: MyApp.MCPHandler,
server_info: %{name: "my-phoenix-app", version: "1.0.0"},
sse_enabled: true,
cors_enabled: true
end
end
# Create your MCP handler
defmodule MyApp.MCPHandler do
use ExMCP.Server.Handler
@impl true
def init(_args), do: {:ok, %{}}
@impl true
def handle_initialize(_params, state) do
{:ok, %{
name: "my-phoenix-app",
version: "1.0.0",
capabilities: %{tools: %{}, resources: %{}}
}, state}
end
@impl true
def handle_list_tools(_cursor, state) do
tools = [
%{
name: "get_user_count",
description: "Get total number of users",
inputSchema: %{type: "object", properties: %{}}
}
]
{:ok, tools, nil, state}
end
@impl true
def handle_call_tool("get_user_count", _args, state) do
count = MyApp.Accounts.count_users()
{:ok, [%{type: "text", text: "Total users: #{count}"}], state}
end
endDSL服务器
以声明方式定义工具、资源和提示:
defmodule MyServer do
use ExMCP.Server
deftool "greet" do
meta do
name "Greet"
description "Greets a person by name"
end
input_schema %{
type: "object",
properties: %{name: %{type: "string", description: "Person to greet"}},
required: ["name"]
}
end
defresource "info://about" do
meta do
name "About"
description "Server information"
end
mime_type "text/plain"
end
@impl true
def handle_tool_call("greet", %{"name" => name}, state) do
{:ok, %{content: [text("Hello, #{name}!")]}, state}
end
@impl true
def handle_resource_read("info://about", _uri, state) do
{:ok, [text("MyServer v1.0")], state}
end
end独立客户端
# Connect to a stdio-based server
{:ok, client} = ExMCP.Client.start_link(
transport: :stdio,
command: ["node", "my-mcp-server.js"]
)
# List available tools
{:ok, tools} = ExMCP.Client.list_tools(client)
# Call a tool
{:ok, result} = ExMCP.Client.call_tool(client, "search", %{
query: "Elixir programming",
limit: 10
})本地BEAM传输
对于受信任的Elixir集群,请使用本机BEAM传输:
defmodule MyToolService do
use ExMCP.Service, name: :my_tools
@impl true
def handle_mcp_request("list_tools", _params, state) do
tools = [
%{
"name" => "ping",
"description" => "Test tool",
"inputSchema" => %{"type" => "object", "properties" => %{}}
}
]
{:ok, %{"tools" => tools}, state}
end
@impl true
def handle_mcp_request("tools/call", %{"name" => "ping"}, state) do
{:ok, %{"content" => [%{"type" => "text", "text" => "Pong!"}]}, state}
end
end
# Start your service (automatically registers with ExMCP.Native)
{:ok, _} = MyToolService.start_link()
# Direct service calls (~15us latency)
{:ok, tools} = ExMCP.Native.call(:my_tools, "list_tools", %{})ACP:控制编码代理
使用 代理客户端协议 以编程方式控制编码代理。ACP适用于任何传输方式(stdio、HTTP/SSE、原生BEAM):
# Native ACP agents over stdio (Gemini CLI, Hermes, OpenCode, Qwen Code, etc.)
{:ok, client} = ExMCP.ACP.start_client(command: ["gemini", "--acp"])
# Create a session and send a prompt
{:ok, %{"sessionId" => sid}} = ExMCP.ACP.Client.new_session(client, "/my/project")
{:ok, %{"stopReason" => _}} = ExMCP.ACP.Client.prompt(client, sid, "Fix the failing tests")
# Adapters for non-native agents (Claude Code, Codex, Pi)
{:ok, client} = ExMCP.ACP.start_client(
command: ["claude"],
adapter: ExMCP.ACP.Adapters.Claude
)
# Pi coding agent with full RPC support
{:ok, client} = ExMCP.ACP.start_client(
command: ["pi"],
adapter: ExMCP.ACP.Adapters.Pi,
adapter_opts: [model: "anthropic/claude-sonnet-4"]
)看 ACP指南 了解全部细节。
传输性能
| 传输 | 延迟 | 最适合 |
|---|---|---|
| 原生BEAM | ~15us | Elixir集群通信 |
| 标准 | ~1-5ms | 子进程通信 |
| HTTP/SSE | ~5-20ms | Web应用程序、远程API |
文档
入门指南
指南
- 用户指南 --完整的功能演练
- 凤凰集成 --详细的Phoenix/Plug集成
- DSL指南 --声明性服务器定义
- ACP指南 --用于控制编码代理的代理客户端协议
- 交通指南 --运输选择和优化
- 配置 --所有配置选项
- 安全 --身份验证、TLS和最佳实践
- 故障排除 --常见问题和解决方案
开发与API
贡献
欢迎投稿!看 开发指南 有关设置和测试说明。
- 分叉存储库
- 创建要素分支
- 跑
make quality确保代码质量 - 提交拉取请求
许可证
麻省理工学院——见 许可证.
