Mcp42 (mcp42 v0.1.1)

Copy Markdown

MCP (Model Context Protocol) server library for Elixir.

Transport-agnostic protocol core (Mcp42.Protocol, Mcp42.Dispatcher) with a ready-made Streamable HTTP transport (Mcp42.Plug) and session management (Mcp42.Session, Mcp42.SessionRegistry).

The boundary

mcp42 knows the MCP protocol and transports — nothing else. Host applications implement the Mcp42.Server behaviour with their tools and business logic; authentication happens in the host's own Plug pipeline before Mcp42.Plug.

Quick start

defmodule MyApp.MCP do
  use Mcp42.Server, name: "myapp", version: "1.0.0"

  @impl true
  def tools do
    [
      %{
        name: "greet",
        description: "Greets someone",
        inputSchema: %{
          type: "object",
          properties: %{"name" => %{type: "string"}},
          required: ["name"]
        }
      }
    ]
  end

  @impl true
  def handle_tool("greet", %{"name" => name}, _ctx), do: {:ok, "Hello " <> name <> "!"}
  def handle_tool(_other, _args, _ctx), do: {:error, "unknown tool"}
end

Router:

# auth first — your app's pipeline, your rules
pipeline :mcp do
  plug MyApp.McpAuth
end

scope "/mcp" do
  pipe_through [:mcp]
  forward "/", Mcp42.Plug, server: MyApp.MCP
end

Supervisor (for session registry):

children = [
  Mcp42.SessionRegistry
]

Tool result shapes

{:ok, "text"}            # single text content
{:ok, [%{type: "text", text: "a"}, %{type: "text", text: "b"}]}
{:error, "message"}      # tool error -> isError: true result

Raises inside handle_tool are caught and returned as JSON-RPC internal errors (-32603) — the transport never 500s on a host bug.

Spec coverage (v0.1.0)

  • Streamable HTTP transport (2025-06-18): POST/GET/DELETE, Mcp-Session-Id
  • JSON-RPC 2.0 without batching (removed in 2025-06-18)
  • initialize / ping / tools/list / tools/call / notifications/*
  • Origin validation (cross-origin 403, localhost default-allow)

Not yet: resources, prompts, sampling, elicitation, OAuth (host-provided).

Summary

Functions

Returns the MCP protocol versions this library supports, newest first.

Functions

supported_versions()

@spec supported_versions() :: [String.t()]

Returns the MCP protocol versions this library supports, newest first.