# MCP Server

GearBox includes a built-in MCP (Model Context Protocol) server that exposes your gear collection to AI assistants. It runs inside the Hono process — no separate service is needed.

The MCP server implements the [Streamable HTTP transport](https://modelcontextprotocol.io/specification) from `@modelcontextprotocol/sdk` and is mounted at `/mcp`.

---

## Table of Contents

- [Enabling and Disabling](#enabling-and-disabling)
- [Authentication](#authentication)
- [Connecting an AI Client](#connecting-an-ai-client)
  - [Claude Code](#claude-code)
  - [Claude Desktop](#claude-desktop)
- [Tools](#tools)
- [Resources](#resources)
- [Recommended Workflow](#recommended-workflow)
- [Example Session](#example-session)
- [Implementation Structure](#implementation-structure)

---

## Enabling and Disabling

The MCP server is **enabled by default**. To disable it, set the environment variable:

```bash
GEARBOX_MCP=false bun run dev:server
```

Or in your environment file:

```bash
GEARBOX_MCP=false
```

When disabled, the `/mcp` route is not registered and any requests to it return 404.

---

## Authentication

The MCP server requires an API key when the app has been set up (i.e., at least one user exists). Pass the key via the `X-API-Key` header in your MCP client configuration.

To create an API key:
1. Log in to the web UI.
2. Go to **Settings > API Keys**.
3. Click **New Key**, give it a name, and copy the full key shown.

The full key is only shown once. Store it in your client configuration immediately.

See [authentication.md](authentication.md) for full API key documentation.

---

## Connecting an AI Client

### Claude Code

Add the MCP server to `.claude/settings.json` in your project or globally at `~/.claude/settings.json`:

```json
{
  "mcpServers": {
    "gearbox": {
      "type": "streamable-http",
      "url": "http://localhost:3000/mcp",
      "headers": {
        "X-API-Key": "your-api-key-here"
      }
    }
  }
}
```

### Claude Desktop

Add the server to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "gearbox": {
      "type": "streamable-http",
      "url": "http://localhost:3000/mcp",
      "headers": {
        "X-API-Key": "your-api-key-here"
      }
    }
  }
}
```

On macOS, the config file is at `~/Library/Application Support/Claude/claude_desktop_config.json`.

After updating the config, restart Claude Desktop (or reload the window in Claude Code) for the server to connect.

---

## Tools

The MCP server exposes 18 tools across five categories.

### Items

| Tool           | Description                                                                                                |
|----------------|------------------------------------------------------------------------------------------------------------|
| `list_items`   | List all items in the gear collection, optionally filtered by `categoryId`.                               |
| `get_item`     | Get a single item by ID with all details.                                                                  |
| `create_item`  | Add a new item directly to the collection. Use for items already decided on; use `create_thread` for research. |
| `update_item`  | Update an existing item's fields.                                                                          |
| `delete_item`  | Delete an item from the collection by ID.                                                                  |

### Categories

| Tool              | Description                          |
|-------------------|--------------------------------------|
| `list_categories` | List all gear categories.            |
| `create_category` | Create a new gear category.          |

### Threads

| Tool             | Description                                                                                          |
|------------------|------------------------------------------------------------------------------------------------------|
| `list_threads`   | List research threads. Pass `includeResolved: true` to include resolved threads.                    |
| `get_thread`     | Get a thread with all its candidates for detailed comparison.                                        |
| `create_thread`  | Start a new research thread for a gear slot. Preferred entry point for gear research.               |
| `resolve_thread` | Resolve a thread by picking the winning candidate. Automatically creates a new item in the collection. |

### Candidates

| Tool               | Description                                                           |
|--------------------|-----------------------------------------------------------------------|
| `add_candidate`    | Add a candidate option to a research thread for comparison.          |
| `update_candidate` | Update a candidate's details (name, price, pros, cons, status, etc.).|
| `remove_candidate` | Remove a candidate from a research thread.                           |

### Setups

| Tool            | Description                                                                                           |
|-----------------|-------------------------------------------------------------------------------------------------------|
| `list_setups`   | List all gear setups with item counts and weight/cost totals.                                        |
| `get_setup`     | Get a setup with all its items and details.                                                          |
| `create_setup`  | Create a new gear setup (e.g., "Bikepacking weekend").                                              |
| `update_setup`  | Update a setup's name and/or replace its item list by passing `itemIds`.                            |

### Images

| Tool                    | Description                                                                                      |
|-------------------------|--------------------------------------------------------------------------------------------------|
| `upload_image_from_url` | Fetch an image from a URL and save it locally. Returns a `filename` to use with items or candidates. |

---

## Resources

### `gearbox://collection/summary`

Returns a JSON overview of the entire gear collection, including:
- Total item count, weight, and cost
- Per-category breakdowns
- Active research thread count

Read this resource first to orient yourself before running queries or making changes.

---

## Recommended Workflow

Tool descriptions are written to guide AI assistants toward the research thread workflow rather than creating items directly. The intended flow for evaluating a new piece of gear is:

1. **`create_thread`** — open a research thread for the gear slot (e.g., "Handlebar bag")
2. **`add_candidate`** — add options with prices, weights, pros, and cons
3. **`get_thread`** — review all candidates side by side
4. **`resolve_thread`** — pick the winner; it becomes a new item in the collection automatically

Use `create_item` directly only when you already know exactly what you're adding and no research is needed.

---

## Example Session

The following illustrates a typical assistant interaction via the MCP server.

**User:** "I need a new handlebar bag. Can you research some options and add them?"

**Assistant actions:**

```
1. list_categories
   -> finds "Bags" category (id: 2)

2. create_thread { name: "Handlebar bag", categoryId: 2 }
   -> thread id: 7

3. upload_image_from_url { url: "https://revelatedesigns.com/sweetroll.jpg" }
   -> filename: "1710000000000-uuid.jpg"

4. add_candidate {
     threadId: 7,
     name: "Revelate Sweetroll",
     categoryId: 2,
     weightGrams: 290,
     priceCents: 13500,
     productUrl: "https://revelatedesigns.com/...",
     imageFilename: "1710000000000-uuid.jpg",
     pros: "Waterproof, 16L, fits most drop bars",
     cons: "Expensive, bulky profile"
   }

5. add_candidate {
     threadId: 7,
     name: "Apidura Backcountry Handlebar Pack",
     categoryId: 2,
     weightGrams: 230,
     priceCents: 11000,
     pros: "Lighter, packable, good attachment system",
     cons: "Smaller capacity"
   }

6. add_candidate { ... }

7. get_thread { id: 7 }
   -> presents comparison to user

8. resolve_thread { threadId: 7, candidateId: 14 }
   -> Revelate Sweetroll added to collection as item id: 42
```

---

## Implementation Structure

The MCP server source lives under `src/server/mcp/`:

```
src/server/mcp/
  index.ts              # Server factory, transport handling, auth middleware, Hono route registration
  tools/
    items.ts            # list_items, get_item, create_item, update_item, delete_item
    categories.ts       # list_categories, create_category
    threads.ts          # list_threads, get_thread, create_thread, resolve_thread,
                        # add_candidate, update_candidate, remove_candidate
    setups.ts           # list_setups, get_setup, create_setup, update_setup
    images.ts           # upload_image_from_url
  resources/
    collection.ts       # gearbox://collection/summary resource handler
```

Each tool file exports a `*ToolDefinitions` array (name, description, inputSchema) and a `register*Tools(db)` factory function that returns handler implementations. The server in `index.ts` iterates over definitions and registers each handler with the MCP `McpServer` instance.

Session management uses the `WebStandardStreamableHTTPServerTransport` with UUID-based session IDs tracked in an in-memory `Map`. Sessions are cleaned up when the transport closes.
