AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Ex Mcp

mcp-azmaveth-ex-mcp · by azmaveth

Model Context Protocol (MCP) and Agent Client Protocol (ACP) client/server library for Elixir

— No reviews yet
0 installs
33 views
0.0% view→install

Install

$ agentstack add mcp-azmaveth-ex-mcp

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ✓ Network access No
  • ✓ Filesystem access No
  • ● Shell / process execution Used
  • ✓ Environment & secrets No
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-azmaveth-ex-mcp)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
● 3mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Ex Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

ExMCP

[](https://hex.pm/packages/exmcp) [](https://hexdocs.pm/exmcp) [](https://github.com/azmaveth/exmcp/actions) [](https://codecov.io/gh/azmaveth/exmcp) [](https://github.com/azmaveth/ex_mcp/blob/master/LICENSE)

A complete Elixir implementation of the Model Context Protocol (MCP) and Agent Client Protocol (ACP)

Getting Started | [User Guide](docs/guides/USERGUIDE.md) | API Docs | Examples | [Changelog](CHANGELOG.md)


Overview

ExMCP is a comprehensive Elixir implementation of the Model Context Protocol and the Agent Client Protocol, enabling AI models to securely interact with local and remote resources through standardized protocols. It provides both client and server implementations with multiple transport options, including native Phoenix integration via Plug compatibility, plus the ability to control coding agents like Gemini CLI, Claude Code, and Codex via ACP.

Key Features

  • Full MCP compliance -- protocol versions 2024-11-05, 2025-03-26, 2025-06-18, and 2025-11-25
  • 100% MCP conformance -- 226/226 client checks, 39/39 server checks (official test suite)
  • Multiple transports -- HTTP/SSE, stdio, and BEAM-local MCP (~15μs local calls)
  • Phoenix Plug -- native Phoenix integration with ExMCP.HttpPlug
  • DSL and Handler APIs -- declarative tool/resource/prompt definitions or callback-based handlers
  • OAuth 2.1 -- automatic 401→discover→PKCE→token flow, scope step-up, CIMD, JWT client auth (private_key_jwt), enterprise SSO (ID-JAG), token revocation (RFC 7009), pluggable auth providers
  • OTP-native -- supervision trees, auto-reconnection with exponential backoff, 88 telemetry events
  • Agent Client Protocol (ACP) -- control coding agents and build native Elixir ACP agents
  • 3100+ tests -- comprehensive suite including official MCP conformance, integration, and performance

Installation

Add ex_mcp to your dependencies in mix.exs:

def deps do
  [
    {:ex_mcp, "~> 1.0.0-rc.1"}
  ]
end

Quick Start

Phoenix Integration

Add MCP server capabilities to your Phoenix app:

# 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, %{
      protocolVersion: ExMCP.protocol_version(),
      serverInfo: %{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, %{content: [%{type: "text", text: "Total users: #{count}"}]}, state}
  end
end

> Note: The example above uses raw ExMCP.Server.Handler callbacks (useful for dynamic capabilities). Most Phoenix apps will be simpler with the DSL — see the "DSL Server" section below and the [Phoenix Guide](docs/guides/PHOENIX_GUIDE.md).

DSL Server

Define tools, resources, and prompts next to their handlers:

defmodule MyServer do
  use ExMCP.Server.Handler
  use ExMCP.Server.DSL

  tool "greet", "Greets a person by name" do
    title "Greeting"
    param :name, :string, required: true, description: "Person to greet"

    run fn %{name: name}, state ->
      {:ok, %{text: "Hello, #{name}!"}, state}
    end
  end

  resource "info://about", "Server information" do
    title "About"
    mime_type "text/plain"

    read fn %{uri: uri}, state ->
      {:ok, %{uri: uri, text: "MyServer v1.0", mimeType: "text/plain"}, state}
    end
  end

  prompt "motivate", "Create a short motivational message" do
    arg :topic, required: true, description: "Topic to encourage"

    render fn %{topic: topic}, state ->
      {:ok,
       %{
         messages: [
           %{role: "user", content: %{type: "text", text: "Encourage me about #{topic}"}}
         ]
       }, state}
    end
  end
end

See the [DSL Guide](docs/DSLGUIDE.md) and examples for more patterns.

Standalone Client

# 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-Local MCP

For trusted Elixir processes in the same VM, use the BEAM-local transport. It carries MCP-shaped messages as Elixir terms, so local calls avoid JSON encode/decode while still using the normal MCP client/server lifecycle.

defmodule MyToolService do
  use ExMCP.Server.Handler
  use ExMCP.Server.DSL

  tool "ping", "Test tool" do
    run fn _args, state ->
      {:ok, %{content: [%{type: "text", text: "Pong!"}]}, state}
    end
  end
end

{:ok, server} = MyToolService.start_link(transport: :beam)

{:ok, client} =
  ExMCP.Client.start_link(
    transport: :beam,
    server: server
  )

{:ok, tools} = ExMCP.Client.list_tools(client)
{:ok, result} = ExMCP.Client.call_tool(client, "ping", %{})

Fast verification: From the repo root (after mix compile), run mix examples.getting_started for a quick in-process demo of these patterns.

ACP: Control and Build Coding Agents

Use the Agent Client Protocol to control coding agents programmatically or expose an Elixir process as an ACP agent:

# 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")

# Claude Code via the SDK-compatible adapter
{:ok, client} = ExMCP.ACP.start_client(
  command: ["claude"],
  adapter: ExMCP.ACP.Adapters.ClaudeSDK,
  adapter_opts: [model: "sonnet", cwd: "/my/project"]
)

# Pi coding agent through the ACP-native adapter
{:ok, client} = ExMCP.ACP.start_client(
  command: ["pi"],
  adapter: ExMCP.ACP.Adapters.Pi,
  adapter_opts: [model: "anthropic/claude-sonnet-4", thinking_level: "medium"]
)

# Native Elixir ACP agent over stdio
{:ok, agent} = ExMCP.ACP.start_agent(
  handler: MyApp.AgentHandler,
  agent_info: %{"name" => "my-agent", "version" => "1.0.0"}
)

See the [ACP Guide](docs/ACP_GUIDE.md) for full details.

Transport Performance

| Transport | Latency | Best For | |-----------|---------|----------| | BEAM-local | ~15us | Local Elixir processes in one VM | | stdio | ~1-5ms | Subprocess communication | | HTTP/SSE | ~5-20ms | Web applications, remote APIs |

Documentation

Getting Started

Guides

  • [User Guide](docs/guides/USER_GUIDE.md) -- Complete feature walkthrough
  • [Phoenix Integration](docs/guides/PHOENIX_GUIDE.md) -- Detailed Phoenix/Plug integration
  • [DSL Guide](docs/DSL_GUIDE.md) -- Declarative server definitions
  • [ACP Guide](docs/ACP_GUIDE.md) -- Agent Client Protocol for controlling coding agents
  • [Transport Guide](docs/TRANSPORT_GUIDE.md) -- Transport selection and optimization
  • [Configuration](docs/CONFIGURATION.md) -- All configuration options
  • [Security](docs/SECURITY.md) -- Authentication, TLS, and best practices
  • [Troubleshooting](docs/TROUBLESHOOTING.md) -- Common issues and solutions

Development & API

  • [Development Guide](docs/DEVELOPMENT.md) -- Setup, testing, and contributing
  • API Documentation -- Complete API reference
  • [Architecture](docs/ARCHITECTURE.md) -- Internal design decisions
  • Examples -- Real-world patterns

Contributing

Contributions welcome! See the [Development Guide](docs/DEVELOPMENT.md) for setup and testing instructions.

  1. Fork the repository
  2. Create a feature branch
  3. Run make quality to ensure code quality
  4. Submit a pull request

License

MIT -- see LICENSE.

Acknowledgments

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.