NexusMCP

MCP (Model Context Protocol) server library for Elixir with per-session GenServer architecture and Streamable HTTP transport.

Installation

Add nexus_mcp to your list of dependencies in mix.exs:

def deps do
  [
    {:nexus_mcp, "~> 0.2.0"}
  ]
end

Usage

Define your MCP server

defmodule MyApp.MCP do
  use NexusMCP.Server,
    name: "my-app",
    version: "1.0.0"

  deftool "hello", "Say hello",
    params: [name: {:string!, "Person's name"}] do
    {:ok, "Hello, #{params["name"]}!"}
  end
end

Tool annotations

You can add MCP tool annotations to provide hints about a tool's behavior:

deftool "list_items", "List all items",
  params: [],
  annotations: %{readOnlyHint: true, destructiveHint: false} do
  {:ok, Items.list_all()}
end

deftool "delete_item", "Delete an item",
  params: [id: {:string!, "Item ID"}],
  annotations: %{readOnlyHint: false, destructiveHint: true, idempotentHint: true} do
  Items.delete!(params["id"])
  {:ok, %{deleted: true}}
end

Supported annotation keys: readOnlyHint, destructiveHint, idempotentHint, openWorldHint, title.

Add the supervisor to your application

children = [
  {NexusMCP.Supervisor, []},
  # ...
]

Route requests to the transport

forward "/mcp", NexusMCP.Transport, server: MyApp.MCP

Origin validation

Restrict which origins can connect by passing allowed_origins:

forward "/mcp", NexusMCP.Transport,
  server: MyApp.MCP,
  allowed_origins: ["https://myapp.com", "https://studio.myapp.com"]

When set, requests with an Origin header not in the list are rejected with 403 Forbidden. Requests without an Origin header are allowed (e.g. server-to-server calls).

License

MIT