Skip to main content

guides/getting-started.md

# Getting Started

This guide will help you get started with barrel_mcp, an Erlang library implementing
the Model Context Protocol (MCP) specification.

## Installation

Add barrel_mcp to your `rebar.config` dependencies:

```erlang
{deps, [
    {barrel_mcp, "1.0.0"}
]}.
```

Or from git:

```erlang
{deps, [
    {barrel_mcp, {git, "https://github.com/barrel-db/barrel_mcp.git", {tag, "v1.0.0"}}}
]}.
```

## Starting the Application

```erlang
%% Start the barrel_mcp application
application:ensure_all_started(barrel_mcp).

%% Wait for registry to be ready (recommended)
ok = barrel_mcp_registry:wait_for_ready().
```

## Your First MCP Server

### 1. Register a Tool

Tools are functions that can be called by MCP clients (like Claude):

```erlang
-module(my_tools).
-export([greet/1]).

%% Arity-1 handler — gets only the call arguments. The simplest
%% shape; pick this when you don't need progress, cancellation, or
%% session context. For arity-2 handlers (with a Ctx parameter),
%% see the Tools guide.
greet(Args) ->
    Name = maps:get(<<"name">>, Args, <<"World">>),
    <<"Hello, ", Name/binary, "!">>.
```

Register it:

```erlang
barrel_mcp:reg_tool(<<"greet">>, my_tools, greet, #{
    description => <<"Greet someone by name">>,
    input_schema => #{
        <<"type">> => <<"object">>,
        <<"properties">> => #{
            <<"name">> => #{
                <<"type">> => <<"string">>,
                <<"description">> => <<"Name to greet">>
            }
        }
    }
}).
```

### 2. Start the HTTP Server

```erlang
{ok, _} = barrel_mcp:start_http_stream(#{port => 9090}).
```

The Streamable HTTP server binds to `127.0.0.1` by default and
validates the `Origin` header on every request. Public binds (any
non-loopback IP) require an explicit `allowed_origins` — see the
[Streamable HTTP guide](http-stream.md) for the security defaults.

The legacy plain-HTTP transport (`start_http/1`, JSON-RPC only,
protocol `2024-11-05`) is still available for clients that don't
speak the Streamable HTTP transport.

### 3. Test Your Server

Using curl:

```bash
# Initialize
curl -X POST http://localhost:9090/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'

# List tools
curl -X POST http://localhost:9090/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'

# Call your tool
curl -X POST http://localhost:9090/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"greet","arguments":{"name":"Erlang"}}}'
```

## Using with Claude Desktop

For Claude Desktop integration, use the stdio transport:

1. Create an escript or release that calls `barrel_mcp:start_stdio()`
2. Configure Claude Desktop's `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "my-server": {
      "command": "/path/to/my_app",
      "args": ["mcp"]
    }
  }
}
```

## Next Steps

- [Tools, Resources & Prompts](tools-resources-prompts.md) — handler shapes (arity 1 / arity 2 with `Ctx`), tool errors, structured output, long-running tasks, completions, resource templates, server notifications.
- [Streamable HTTP transport](http-stream.md) — security defaults, CORS, `Origin` validation, response codes, replay.
- [Authentication](authentication.md) — bearer / API key / basic, modern hash formats.
- [Features matrix](features.md) — what's supported on the wire.
- [Building a client](building-a-client.md) — task-oriented walkthrough for hosting MCP clients.
- [Client internals](internals.md) — architecture and behaviour contracts.
- [MCP Client (reference)](client.md) - Older API reference, kept for cross-linking