# TrucoPilot Tickets — MCP API Documentation

> **Base URL:** `https://trucopilot.com/api/mcp/v1`
> **Auth:** Bearer token in `Authorization` header
> **Protocol:** MCP (Model Context Protocol) Streamable HTTP at `/mcp`

---

## Quick Start

### Step 1: Generate an API Token

Go to your project's **Settings > MCP Connection** in the TrucoPilot web UI and click "Generate Token".

### Step 2: Connect Claude Code

**Quickest way (one command):**

```bash
claude mcp add --transport http trucopilot-tickets \
  https://trucopilot.com/api/mcp/v1/mcp \
  --header "Authorization: Bearer YOUR_TOKEN_HERE"
```

**Or add manually to `~/.claude.json`** (recommended — private, not git-tracked, scoped to your project):

```json
{
  "projects": {
    "/path/to/your/project": {
      "mcpServers": {
        "trucopilot-tickets": {
          "type": "http",
          "url": "https://trucopilot.com/api/mcp/v1/mcp",
          "headers": {
            "Authorization": "Bearer YOUR_TOKEN_HERE"
          }
        }
      }
    }
  }
}
```

### Step 3: Start Using

Tell your AI: "Create a ticket for implementing login", "Move ticket 5 to In Process", "What's the project status?", etc.

---

## Rules for LLMs / AI Agents

**You MUST follow these rules when connected to a TrucoPilot project:**

1. **First call:** Always call `get_project_status` before any other tool. This gives you the full board state — including **all boards, their columns, and every ticket in each column** — plus all documents and stats. **Pay attention to the column names** — different boards may have different names. Always use actual column names from the board.

2. **Every feature MUST be an Epic with sub-tickets.** When the user asks you to work on something:
   - First, check the board for an existing Epic that relates to the work. Use `list_tickets` or `search` to find it.
   - If a related Epic exists, create a new sub-ticket under it with `create_sub_ticket`.
   - If no related Epic exists, create a new Epic with `create_ticket` (type: `epic`), then create sub-tickets under it.
   - **Never create standalone tickets for feature work.** All implementation work should be tracked as sub-tickets of an Epic.

3. **Epic status is managed automatically by the server.** You do NOT need to move Epics between columns. The rules are:
   - If ALL sub-tickets are in the done column (marked with `is_done_column: true`) → the Epic auto-moves to the done column
   - If ANY sub-ticket is in a middle column (not first, not done) → the Epic auto-moves to the in-progress column
   - If ALL sub-tickets are in the first column → the Epic stays in the first column
   - **You only need to move sub-tickets.** The Epic follows automatically.

4. **Creating tickets in the right column:** You do NOT have to create everything in the first column. If you are going to start working immediately, **create the ticket directly in the active/in-progress column** using the `column_name` parameter. This saves an extra `move_ticket` call.

5. **Working on sub-tickets:** When you start working, make sure the sub-ticket is in the active column. ALWAYS call `add_comment` to log what you're doing.

6. **After any work:** You MUST call `add_comment` on the sub-ticket with: files changed, functions/classes modified, summary of changes. This is the audit trail.

7. **Completing sub-tickets:** Move to the **done column** (the column with `is_done_column: true`). If there's no QA process, skip QA and move directly to done. Add a final comment summarizing all work. If this was the last open sub-ticket, the Epic auto-completes too.

8. **Discovering columns:** Use `list_columns` or the `boards` section of `get_project_status`. Each column has `name`, `is_done_column`, `board_name`, and `ticket_count`.

9. **Bug reports — reopen existing sub-tickets, don't create duplicates.** When a user says something is broken:
   - **First**, search for a completed sub-ticket that originally implemented that feature.
   - **If found**: `move_ticket` back to active column, `add_comment` explaining the bug, fix it, complete it again.
   - **Only create a new bug ticket** if the bug is not related to any existing feature sub-ticket.

10. **Workflow summary (new feature):**
    ```
    1. get_project_status → check board state, note column names
    2. No epic found → create_ticket "Dark Mode Support" (type: epic, column_name: "In Process")
    3. create_sub_ticket "Add CSS variables" (column_name: "In Process") ← working on it now
    4. create_sub_ticket "Create toggle component" ← defaults to first column
    5. ... do the work, add_comment with files changed ...
    6. move_ticket sub-1 → done column
    7. move_ticket sub-2 → "In Process", work, → done column
    8. move_ticket sub-3 → done column (Epic auto-completes!)
    ```

---

## Bootstrapping a Project from Git History

When connecting to an existing codebase for the first time, you should create tickets that reflect the work already done. This gives the project board a complete history.

### How to bootstrap:

1. **Call `get_project_status`** to see the current (empty) board and discover column names.

2. **Analyze the codebase and git history:**
   - Run `git log --oneline --since="6 months ago"` to see recent commits
   - Identify major features, modules, and components in the codebase
   - Group related commits into logical features

3. **Create Epic tickets for each major feature** using `create_ticket` with:
   - `ticket_type: "epic"`
   - `title`: Feature name (e.g., "User Authentication System")
   - `description`: What this feature does, key files/components
   - `created_at`: The date of the earliest related commit (ISO 8601 format, e.g., `"2025-03-15T10:00:00"`)
   - `column_name`: Put in the done column if the feature is complete, or "In Process" if it's ongoing

4. **Create sub-tickets under each Epic** using `create_sub_ticket` with:
   - `parent_ticket_id`: The Epic's ticket number
   - `title`: Specific piece of work (e.g., "Add Google OAuth handler")
   - `description`: What was implemented, key files
   - `created_at`: The date of the related commit
   - `column_name`: Done column if completed, appropriate column otherwise

5. **Move completed tickets to the done column** using `move_ticket` if not already placed there.

6. **Add comments to completed tickets** with a summary of what was built, files involved, and current state.

### Example bootstrap flow:

```
# Step 1: Get board state
get_project_status

# Step 2: Create an epic for an existing feature
create_ticket {
  "title": "User Authentication",
  "ticket_type": "epic",
  "description": "Complete auth system with Google OAuth, session management, and role-based access.",
  "column_name": "Completed",
  "created_at": "2025-01-15T09:00:00"
}

# Step 3: Create sub-tickets for work that was done
create_sub_ticket {
  "parent_ticket_id": "PROJ-1",
  "title": "Implement Google OAuth flow",
  "description": "OAuth redirect, callback handler, session creation",
  "column_name": "Completed",
  "created_at": "2025-01-15T09:00:00"
}

# Step 4: Add a comment summarizing the completed work
add_comment {
  "ticket_id": "PROJ-2",
  "content": "## Summary\nImplemented Google OAuth login flow.\n\n## Files\n- src/auth/oauth.py\n- src/auth/callback.py\n- templates/login.html\n\n## Current State\nUsers can sign in via Google. Session stored in Redis."
}
```

### Tips:
- Use `git log --format="%H %ai %s" --diff-filter=A -- "*.py"` to find when files were first added
- Group commits by feature area (auth, API, UI, etc.) to create logical epics
- Set `created_at` to the earliest commit date for each feature/sub-ticket
- Don't over-granularize — one sub-ticket per meaningful feature piece, not per commit
- Focus on features a developer would care about, skip infrastructure/config

---

## MCP Tools (19 total)

### `get_project_status` — CALL THIS FIRST

**Always call this tool first — before every task, every session.** Returns a complete snapshot:
- Project info (name, key, description)
- Stats (total tickets, completed, open, progress %)
- **All boards with their columns** — each column includes `name`, `id`, `is_done_column`, `ticket_count`, and every ticket in that column. Use column names from this response.
- **Smart context** — automatically includes the most useful content:
  - If Auto-Summary is enabled (README.md or AI file): returns all document content (AI-generated summaries of your project)
  - If Auto-Summary is off: returns ticket details (AI summary per ticket, or description + comments if no summary)
- All labels

```json
{ "name": "get_project_status", "arguments": {} }
```

No parameters needed — the tool automatically determines the best context to return.

**REST:** `GET /status`

---

### `get_all_tickets` — Full ticket export

Returns **all tickets with full content** (AI summary, description, and comments) plus all document content. Use this when you need a complete deep-dive into the project — for example, when bootstrapping from an existing codebase or doing a full project review.

```json
{ "name": "get_all_tickets", "arguments": {} }
```

**REST:** `GET /all-tickets`

---

### `create_ticket`

Create a new ticket. Supports `created_at` for backdating when importing historical data.

```json
{
  "name": "create_ticket",
  "arguments": {
    "title": "Implement OAuth login page",
    "description": "## What\nBuild login page with Google OAuth.",
    "column_name": "In Process",
    "priority": "high",
    "ticket_type": "epic",
    "created_at": "2025-06-15T10:30:00"
  }
}
```

| Param | Required | Description |
|-------|----------|-------------|
| `title` | Yes | Short, clear ticket title |
| `description` | No | Detailed markdown description |
| `column_name` | No | Any column name (case-insensitive). Defaults to first column. |
| `priority` | No | `lowest`, `low`, `medium` (default), `high`, `highest` |
| `ticket_type` | No | `task` (default), `bug`, `story`, `epic` |
| `created_at` | No | ISO 8601 datetime. For historical imports. Defaults to now. |

**REST:** `POST /tickets`

---

### `update_ticket` — MUST add_comment after

Update a ticket's properties. Supports `created_at` override for backdating.

```json
{
  "name": "update_ticket",
  "arguments": {
    "ticket_id": "PROJ-5",
    "description": "Updated with implementation details...",
    "priority": "high"
  }
}
```

| Param | Required | Description |
|-------|----------|-------------|
| `ticket_id` | Yes | Ticket ID, number, or key (e.g., `PROJ-5`) |
| `title` | No | Updated title |
| `description` | No | Updated description (markdown) |
| `priority` | No | Updated priority |
| `ticket_type` | No | Updated type |
| `created_at` | No | ISO 8601 datetime to override creation date |

**REST:** `PUT /tickets/{ticket_id}`

---

### `move_ticket` — MUST add_comment after

Move a ticket between columns. Use `list_columns` or `get_project_status` to discover column names.

To complete a ticket: move it to the column where `is_done_column` is `true`.

```json
{
  "name": "move_ticket",
  "arguments": {
    "ticket_id": "PROJ-5",
    "column_name": "In Process"
  }
}
```

**REST:** `POST /tickets/{ticket_id}/move`

---

### `add_comment` — REQUIRED after every update/move

**This is the primary audit trail.** Every time you update, move, or complete work, you MUST leave a comment.

**Comment MUST include:** Summary, Files Changed, Functions/Classes, Notes.

```json
{
  "name": "add_comment",
  "arguments": {
    "ticket_id": "PROJ-5",
    "content": "## Work Completed\nImplemented Google OAuth.\n\n## Files Changed\n- `src/auth/login.py`\n- `src/auth/callback.py`\n\n## Functions\n- `LoginHandler.redirect_to_google()` — New\n- `OAuthCallbackHandler.handle()` — New"
  }
}
```

**REST:** `POST /tickets/{ticket_id}/comment`

---

### `create_sub_ticket` — Makes parent an Epic

Create a sub-ticket under a parent. Parent auto-promotes to Epic. Supports `created_at` for historical imports.

```json
{
  "name": "create_sub_ticket",
  "arguments": {
    "parent_ticket_id": "PROJ-5",
    "title": "Create login form UI",
    "description": "Build the HTML/CSS for the login form",
    "column_name": "In Process",
    "created_at": "2025-06-15T10:30:00"
  }
}
```

| Param | Required | Description |
|-------|----------|-------------|
| `parent_ticket_id` | Yes | Parent ticket ID or number. Becomes an Epic. |
| `title` | Yes | Sub-ticket title |
| `description` | No | Description (markdown) |
| `priority` | No | Defaults to parent's priority |
| `column_name` | No | Target column (case-insensitive). Defaults to first column. |
| `created_at` | No | ISO 8601 datetime for historical imports. Defaults to now. |

**REST:** `POST /tickets/{ticket_id}/sub-ticket`

---

### `convert_to_sub_ticket` — Reorganize under Epics

Convert a standalone ticket into a sub-ticket of an epic.

```json
{
  "name": "convert_to_sub_ticket",
  "arguments": { "ticket_id": "PROJ-10", "epic_id": "PROJ-5" }
}
```

**REST:** `POST /tickets/{ticket_id}/convert-to-sub-ticket`

---

### `get_ticket`

Get full details of a ticket including comments, activity, and AI summary.

```json
{ "name": "get_ticket", "arguments": { "ticket_id": "PROJ-5" } }
```

**REST:** `GET /tickets/{ticket_id}`

---

### `list_tickets`

List tickets with filters.

```json
{
  "name": "list_tickets",
  "arguments": {
    "column_name": "In Process",
    "status": "open",
    "priority": "high",
    "search": "login"
  }
}
```

All params optional. `status`: `open` or `completed`.

**REST:** `GET /tickets?status=open&priority=high&search=login`

---

### `delete_ticket`

```json
{ "name": "delete_ticket", "arguments": { "ticket_id": "PROJ-5" } }
```

**REST:** `DELETE /tickets/{ticket_id}`

---

### `search`

Search across tickets and documents.

```json
{ "name": "search", "arguments": { "query": "authentication", "scope": "all" } }
```

`scope`: `all` (default), `tickets`, `documents`.

**REST:** `GET /search?q=authentication&scope=all`

---

### `list_documents`

```json
{ "name": "list_documents", "arguments": { "doc_type": "wiki" } }
```

**REST:** `GET /documents`

---

### `get_document`

```json
{ "name": "get_document", "arguments": { "doc_id": "readme" } }
```

**REST:** `GET /documents/{slug}`

---

### `create_document`

```json
{
  "name": "create_document",
  "arguments": { "title": "API Docs", "content": "# API...", "slug": "api-docs", "doc_type": "wiki" }
}
```

**REST:** `POST /documents`

---

### `update_document`

```json
{ "name": "update_document", "arguments": { "doc_id": "readme", "content": "# Updated..." } }
```

**REST:** `PUT /documents/{slug}`

---

### `list_columns` — Discover board columns

List all columns with ticket counts. **Use this before creating or moving tickets.**

```json
{ "name": "list_columns", "arguments": {} }
```

**REST:** `GET /columns`

---

### `list_labels`

```json
{ "name": "list_labels", "arguments": {} }
```

**REST:** `GET /labels`

---

### `list_members`

```json
{ "name": "list_members", "arguments": {} }
```

**REST:** `GET /members`

---

## Authentication

All requests require a Bearer token:

```
Authorization: Bearer tp_proj_aBcDeFgHiJkLmNoPqRsT...
```

Tokens are project-scoped, hashed at rest, revocable, and tracked (last-used timestamp).

---

## REST API Endpoints Summary

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/status` | **Full project snapshot (call first)** |
| `GET` | `/health` | Health check |
| `GET` | `/tickets` | List tickets (with filters) |
| `POST` | `/tickets` | Create ticket |
| `GET` | `/tickets/{id}` | Get ticket details |
| `PUT` | `/tickets/{id}` | Update ticket |
| `DELETE` | `/tickets/{id}` | Delete ticket |
| `POST` | `/tickets/{id}/move` | Move ticket to column |
| `POST` | `/tickets/{id}/comment` | Add comment |
| `POST` | `/tickets/{id}/sub-ticket` | Create sub-ticket |
| `POST` | `/tickets/{id}/convert-to-sub-ticket` | Convert to sub-ticket |
| `GET` | `/documents` | List documents |
| `POST` | `/documents` | Create document |
| `GET` | `/documents/{slug}` | Get document |
| `PUT` | `/documents/{slug}` | Update document |
| `DELETE` | `/documents/{slug}` | Delete document |
| `GET` | `/search?q=` | Search tickets + docs |
| `GET` | `/columns` | List columns |
| `GET` | `/labels` | List labels |
| `GET` | `/members` | List members |
| `POST` | `/mcp` | MCP Protocol endpoint |
