README.md

# 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`:

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

## Usage

### Define your MCP server

```elixir
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](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#annotations) to provide hints about a tool's behavior:

```elixir
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

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

### Route requests to the transport

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

### Origin validation

Restrict which origins can connect by passing `allowed_origins`:

```elixir
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