# Get ToolMesh running with Docker Compose

> Set up ToolMesh in minutes with Docker Compose. Covers git clone, .env (TOOLMESH_AUTH_PASSWORD, TOOLMESH_API_KEY), docker compose up, and `claude mcp add`.

Canonical: https://www.toolmesh.io/en/getting-started/

ToolMesh runs as a single Go binary or Docker container. It exposes an MCP server that AI agents connect to.

## Prerequisites

- Docker and Docker Compose
- An AI agent that speaks MCP (Claude Desktop, Claude Code, Claude.ai, or any MCP client)
- Optional: a reverse proxy for TLS (Caddy, Cloudflare Tunnel, nginx)

## Quick Start

```bash
# Clone the repository
git clone https://github.com/DunkelCloud/ToolMesh.git
cd ToolMesh

# Create your configuration
cp .env.example .env
```

Open `.env` and set at least one authentication method:

```bash
# For interactive login (Claude Desktop, Claude.ai):
TOOLMESH_AUTH_PASSWORD=my-secure-password

# For programmatic access (Claude Code, scripts):
TOOLMESH_API_KEY=my-api-key
```

**Without a password or API key, all requests are rejected.**

> **Production note:** By default, ToolMesh starts with `OPENFGA_MODE=bypass` (no authorization checks). This is fine for local development, but for production use you should set `OPENFGA_MODE=restrict` and configure OpenFGA. See [Authorization](/en/authorization/) for details.

```bash
# Start ToolMesh
docker compose up -d

# Verify it's running (default port: 8123)
curl http://localhost:8123/health
```

The MCP endpoint is available at `http://localhost:8123/mcp`.

:::tip[Applying config changes]
After editing `.env`, a simple `docker compose restart` does **not** reload environment variables. Use:
```bash
docker compose down && docker compose up -d
```
:::

## TLS (Important)

ToolMesh serves plain HTTP. **Most MCP clients — including Claude Desktop — require HTTPS** and will reject `http://` URLs. You need a TLS-terminating reverse proxy in front of ToolMesh:

| Option | When to use |
|--------|-------------|
| **Caddy** | Self-hosted with a public domain — automatic Let's Encrypt certs |
| **Cloudflare Tunnel** | No open ports needed, zero-config TLS |
| **nginx / Traefik** | Already in your stack |

For **local development only**, you can bypass TLS by editing `claude_desktop_config.json` by hand (the GUI enforces `https://`).

## Connect an AI Agent

### Claude Desktop

Add to your Claude Desktop MCP config (`claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "toolmesh": {
      "url": "https://toolmesh.example.com/mcp"
    }
  }
}
```

For local development without TLS proxy:

```json
{
  "mcpServers": {
    "toolmesh": {
      "url": "http://localhost:8123/mcp"
    }
  }
}
```

### Claude.ai (Custom Connector)

ToolMesh supports OAuth 2.1 with PKCE S256 for remote access. Configure users in `config/users.yaml` and use the public HTTPS URL as the MCP endpoint.

### Claude Code

Claude Code connects via API key. Set `TOOLMESH_API_KEY` in your `.env`, then add the MCP endpoint:

```bash
claude mcp add -t http -H "Authorization: Bearer MY_API_KEY" -s user toolmesh http://localhost:8123/mcp
```

## Add a Backend

Backends are configured in `config/backends.yaml`.

### MCP Backend (proxy an existing MCP server)

```yaml
backends:
  - name: memorizer
    transport: http
    url: "https://memorizer.example.com/mcp"
    api_key_env: "MEMORIZER_API_KEY"
```

Set the credential as an environment variable in `.env`:

```bash
CREDENTIAL_MEMORIZER_API_KEY=sk-mem-xxxxx
```

Credentials are injected at runtime — the LLM never sees API keys.

### REST Backend (via DADL)

Instead of building an MCP wrapper server, describe the REST API declaratively in a `.dadl` file:

```yaml
backends:
  - name: github
    transport: rest
    dadl: /app/dadl/github.dadl
    url: "https://api.github.com"
```

Download DADL files from the [DADL Registry](https://dadl.ai/browse) or generate one with your LLM:

> "Create a DADL for the GitHub API — list repos, open issues, and create pull requests."

## What's Next

- [Architecture](/en/architecture/) — understand the execution pipeline
- [DADL](/en/dadl/) — describe REST APIs without code
- [Configuration](/en/configuration/) — all environment variables
- [Authentication](/en/authentication/) — OAuth 2.1, API keys, multi-user
