> ## Documentation Index
> Fetch the complete documentation index at: https://docs.janet.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Server

> Connect AI agents to your organization

<div className="img-showcase">
  <div className="term-mock">
    <div className="term-header">
      <div className="term-dots">
        <span className="term-dot term-dot-red" />

        <span className="term-dot term-dot-yellow" />

        <span className="term-dot term-dot-green" />
      </div>

      <span className="term-title">claude — \~/projects/frontend</span>

      <div style={{width: '50px'}} />
    </div>

    <div className="term-body">
      <div className="term-user-row">
        <span className="term-user-chevron">›</span>
        <span className="term-user-text">look at my tickets in "To Do" and make a plan for how I should prioritize and finish them</span>
      </div>

      <div className="term-tool-slot">
        <div className="term-tool-row term-phase-tool-loading-1">
          <span className="term-tool-dot term-tool-dot-loading" />

          <span className="term-tool-label"><strong>janet-ai - list\_tickets (MCP)</strong><span className="term-tool-args">(project\_key: "SW", status: "To Do", assignees: \["me"])</span></span>
        </div>

        <div className="term-tool-row term-phase-tool-done-1">
          <span className="term-tool-dot" />

          <span className="term-tool-label"><strong>janet-ai - list\_tickets (MCP)</strong><span className="term-tool-args">(project\_key: "SW", status: "To Do", assignees: \["me"])</span></span>
        </div>
      </div>

      <div className="term-response-row term-stream-1">
        <span className="term-response-dot" />

        <span className="term-response-text">You have 4 tickets in To Do. Here's how I'd tackle them:</span>
      </div>

      <div className="term-response-row term-stream-2">
        <span style={{width: '8px', flexShrink: 0}} />

        <span className="term-response-text">1. <strong>SW-84</strong> SSO token refresh — blocking other auth work, fix first</span>
      </div>

      <div className="term-response-row term-stream-3">
        <span style={{width: '8px', flexShrink: 0}} />

        <span className="term-response-text">2. <strong>SW-71</strong> OAuth callback timeout — related to SSO, do right after</span>
      </div>

      <div className="term-response-row term-stream-4">
        <span style={{width: '8px', flexShrink: 0}} />

        <span className="term-response-text">3. <strong>SW-63</strong> Session cookie fix — standalone, quick win</span>
      </div>

      <div className="term-response-row term-stream-5">
        <span style={{width: '8px', flexShrink: 0}} />

        <span className="term-response-text">4. <strong>SW-58</strong> Safari redirect — lowest impact, last</span>
      </div>

      <div className="term-response-row term-stream-6" style={{height: '4px'}} />

      <div className="term-response-row term-stream-7">
        <span style={{width: '8px', flexShrink: 0}} />

        <span className="term-response-text">Want me to spawn agents to start working through these?</span>
      </div>

      <div className="term-input-area">
        <span className="term-input-chevron">›</span>

        <span className="term-input-cursor" />
      </div>
    </div>
  </div>
</div>

Give AI agents like Claude Code, Cursor, and Codex full access to your Janet AI workspace. Create & resolve tickets, manage sprints, and [more](#available-tools).

## Setup

<Tabs>
  <Tab title="Claude Code">
    Run this command in your terminal:

    ```bash theme={null}
    claude mcp add janet-ai --transport http https://mcp.janet.ai/mcp
    ```

    Then run `/mcp` in Claude Code and complete the OAuth flow to connect your Janet AI Organization.
  </Tab>

  <Tab title="Claude Desktop">
    Open **Settings → Connectors → Add custom connector** and enter the URL:

    ```
    https://mcp.janet.ai/mcp
    ```

    Complete the OAuth flow to connect your Janet AI organization.

    <Callout icon="circle-info" color="#8B5CF6">Remote MCP servers in Claude Desktop are configured through Settings → Connectors, not the `claude_desktop_config.json` file.</Callout>
  </Tab>

  <Tab title="Cursor">
    Go to **Cursor Settings → Tools & MCP** and click **New MCP Server**. This opens `mcp.json` — add the following:

    ```json theme={null}
    {
      "mcpServers": {
        "janet-ai": {
          "url": "https://mcp.janet.ai/mcp"
        }
      }
    }
    ```

    Save, then back in Cursor Settings click **Connect** next to janet-ai to authenticate and choose your organization.
  </Tab>

  <Tab title="VS Code">
    Create or edit `.vscode/mcp.json` in your workspace:

    ```json theme={null}
    {
      "servers": {
        "janet-ai": {
          "type": "http",
          "url": "https://mcp.janet.ai/mcp"
        }
      }
    }
    ```

    Open the Command Palette and run **MCP: List Servers**, then start the Janet AI server and complete the OAuth flow.
  </Tab>

  <Tab title="Windsurf">
    Open Windsurf Settings and search for **MCP**. Click **View raw config** to open `mcp_config.json`, then add:

    ```json theme={null}
    {
      "mcpServers": {
        "janet-ai": {
          "serverUrl": "https://mcp.janet.ai/mcp"
        }
      }
    }
    ```

    Save, restart Windsurf, and complete the OAuth flow on first use.
  </Tab>

  <Tab title="Codex">
    Run this command in your terminal:

    ```bash theme={null}
    codex mcp add janet-ai --url https://mcp.janet.ai/mcp
    ```

    Then run `codex mcp login janet-ai` and complete the OAuth flow to connect your workspace.
  </Tab>
</Tabs>

## What You Can Do

Once connected, just talk to your AI agent naturally:

| Use case              | Example prompt                                                    |
| --------------------- | ----------------------------------------------------------------- |
| **Find tickets**      | "Show me my assigned tickets in MAIN"                             |
| **Search**            | "Search for tickets about authentication"                         |
| **Create tickets**    | "Create a high-priority bug for the login redirect issue"         |
| **Schedule tickets**  | "Schedule a ticket for tomorrow at 9am to review the deployment"  |
| **Update tickets**    | "Move MAIN-452 to In Progress"                                    |
| **Manage sprints**    | "Add MAIN-100 and MAIN-101 to Sprint 3"                           |
| **Create objectives** | "Create an objective called Q2 Launch with high priority"         |
| **Manage objectives** | "Add MAIN-100 and MAIN-101 to the Q2 Launch objective"            |
| **Add comments**      | "Add a comment to MAIN-100 saying the fix is deployed"            |
| **Attach context**    | "Add this Slack thread / PR / email / doc to MAIN-123 as context" |
| **Break down work**   | "Create child tasks on MAIN-200 for each component"               |
| **Sort & organize**   | "Sort the To Do column by priority"                               |
| **Web search**        | "What are the best libraries for rate limiting in Node.js?"       |
| **Write docs**        | "Create a document called API Design with the proposed structure" |

### Available Tools

The MCP server exposes 40 tools that your AI agent discovers and uses automatically.

<Accordion title="Workspace">
  <ResponseField name="get_workspace_context">Get user info, organization, projects, statuses, and members.</ResponseField>
  <ResponseField name="get_platform_guidance">Get platform documentation and usage guidance.</ResponseField>
</Accordion>

<Accordion title="Tickets">
  <ResponseField name="list_tickets">List tickets with optional filters (status, priority, assignee, keyword, dates).</ResponseField>
  <ResponseField name="get_tickets">Get full ticket details including description, comments, and child tasks for one or more tickets.</ResponseField>
  <ResponseField name="create_tickets">Create one or more tickets in a single call (title, description, status, priority, assignees, labels, sprint, due date, scheduled activation).</ResponseField>
  <ResponseField name="update_tickets">Batch update ticket fields (status, priority, assignees, labels, due date).</ResponseField>
  <ResponseField name="delete_tickets">Soft-delete one or more tickets in a single call. Restorable.</ResponseField>
  <ResponseField name="restore_tickets">Restore one or more previously deleted tickets together with their child tasks.</ResponseField>
  <ResponseField name="move_ticket">Reposition a ticket: top, bottom, at:N, before/after, within kanban, sprint, or objective. Also supports column-wide `sort` and `reorder`.</ResponseField>
  <ResponseField name="search_tickets_semantic">Semantic search across tickets by meaning.</ResponseField>
</Accordion>

<Accordion title="Ticket Context">
  <ResponseField name="add_context_to_tickets">Attach context to one or more tickets in a single call. The `type` arg picks the source: `slack` (permalink or manual reporter+message), `discord` (permalink or manual username+message), `email` (sender, subject, body), `pull_request` (URL), `web_link` (URL), or `document` (Janet AI doc by UUID or exact title — idempotent).</ResponseField>
  <ResponseField name="list_ticket_context">List every context item on a ticket (Slack/Discord/email messages, PRs, web links, linked Janet docs, meetings, Google Docs) with its id + short description. Call this before `remove_context_from_ticket`.</ResponseField>
  <ResponseField name="remove_context_from_ticket">Remove a context item from a ticket by id (id comes from `list_ticket_context`). Works on any context type.</ResponseField>
</Accordion>

<Accordion title="Child Tasks">
  <ResponseField name="list_child_tasks">List child tasks for a ticket.</ResponseField>
  <ResponseField name="create_child_tasks">Create one or more child tasks on a ticket in a single call.</ResponseField>
  <ResponseField name="update_child_tasks">Batch update child task title, status, priority, or assignee.</ResponseField>
  <ResponseField name="delete_child_tasks">Delete one or more child tasks in a single call.</ResponseField>
</Accordion>

<Accordion title="Comments">
  <ResponseField name="list_comments">List comments on a ticket.</ResponseField>
  <ResponseField name="add_comments">Add one or more comments to one or more tickets in a single call.</ResponseField>
  <ResponseField name="edit_comments">Batch edit existing comments. Edit history is preserved (the original row is deactivated, a new row inserted with the original `created_at`).</ResponseField>
  <ResponseField name="delete_comments">Delete one or more comments in a single call.</ResponseField>
</Accordion>

<Accordion title="Sprints">
  <ResponseField name="list_sprints">List sprints with status, dates, and ticket counts.</ResponseField>
  <ResponseField name="create_sprint">Create a new sprint.</ResponseField>
  <ResponseField name="update_sprint">Update a sprint's name, dates, status, or description.</ResponseField>
  <ResponseField name="add_sprint_tickets">Add tickets to a sprint.</ResponseField>
  <ResponseField name="remove_sprint_tickets">Remove tickets from a sprint.</ResponseField>
  <ResponseField name="list_sprint_tickets">List tickets in a sprint grouped by status.</ResponseField>
</Accordion>

<Accordion title="Objectives">
  <ResponseField name="list_objectives">List objectives with status, priority, and ticket counts.</ResponseField>
  <ResponseField name="create_objective">Create a new objective.</ResponseField>
  <ResponseField name="update_objective">Update an objective's name, status, priority, or assignees.</ResponseField>
  <ResponseField name="delete_objective">Delete an objective.</ResponseField>
  <ResponseField name="add_objective_tickets">Add tickets to an objective.</ResponseField>
  <ResponseField name="remove_objective_tickets">Remove tickets from an objective.</ResponseField>
  <ResponseField name="list_objective_tickets">List tickets in an objective grouped by status.</ResponseField>
</Accordion>

<Accordion title="Documents">
  <ResponseField name="list_documents">List documents in the workspace.</ResponseField>
  <ResponseField name="get_document">Get a document's full content.</ResponseField>
  <ResponseField name="create_document">Create a document with title and markdown content.</ResponseField>
  <ResponseField name="update_document">Update a document's title or content.</ResponseField>
</Accordion>

<Accordion title="Web">
  <ResponseField name="web_search">Search the web for current information.</ResponseField>
</Accordion>

<Accordion title="JanetClaw">
  <ResponseField name="post_janetclaw_activity">Post an activity message to the user's JanetClaw feed for distinct JanetClaw actions (creating a ticket from email, adding context, moving tickets when a PR merges, etc.). Pass `ticket_key` — click-through URLs resolve automatically.</ResponseField>
</Accordion>

## Activity Log

Every MCP tool call is logged and visible in the **MCP page** → **Usage tab** in your dashboard. Organization admins see all members' calls; members see only their own.

## Troubleshooting

### Cannot connect / authentication errors

If your client fails to connect, try:

1. **Clear existing auth** — In your client, remove and re-add the MCP server to trigger a fresh OAuth flow.
2. **Check your organization** — During sign-in, make sure you select the correct organization.
3. **Restart your client** — Some clients need a full restart after the OAuth flow completes.

## FAQ

<AccordionGroup>
  <Accordion title="What are the rate limits?">
    The MCP server enforces per-user rate limits. If you hit a `429 Too Many Requests` error, wait a minute before retrying. Typical limits are 200 requests/minute and 5,000 requests/hour per user.

    If you consistently hit rate limits, contact [support@janet.ai](mailto:support@janet.ai).
  </Accordion>

  <Accordion title="Is there a Janet CLI tool?">
    [`mcporter`](https://github.com/steipete/mcporter) lets you call MCP tools directly as CLI commands — no agent required.

    First, install it globally:

    ```bash theme={null}
    npm install mcporter
    ```

    Authenticate once locally:

    ```bash theme={null}
    mcporter auth https://mcp.janet.ai/mcp
    ```

    Then call any tool directly from the command line:

    ```bash theme={null}
    mcporter call janet-ai.list_tickets --project_key MAIN --status "To Do"
    ```
  </Accordion>

  <Accordion title="How do I use CLI commands in my cloud-hosted scripts?">
    First, install it globally and authenticate on your local machine:

    ```bash theme={null}
    npm install mcporter
    mcporter auth https://mcp.janet.ai/mcp
    ```

    Credentials are stored in `~/.mcporter/credentials.json` — copy that file's contents as a secret or environment variable in your cloud environment so scripts can run without an interactive OAuth flow.

    For example, a Python script that creates a ticket:

    ```python theme={null}
    import json
    import subprocess

    subprocess.run([
        "mcporter", "call", "janet-ai.create_tickets",
        "--tickets", json.dumps([{
            "title": "Nightly health check failed",
            "project_key": "MAIN",
            "priority": "High",
        }]),
    ])
    ```
  </Accordion>

  <Accordion title="My agent doesn't support the OAuth PKCE flow — how do I connect?">
    Some agent runtimes support HTTP-based MCP servers but don't implement the OAuth PKCE flow required by Janet AI (e.g. [OpenClaw](https://openclaw.ai)). You can proxy through [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) to handle auth transparently.

    First, install it:

    ```bash theme={null}
    npm install -g mcp-remote
    ```

    Then trigger the OAuth flow in your terminal:

    ```bash theme={null}
    mcp-remote https://mcp.janet.ai/mcp
    ```

    Then configure your agent to use it:

    ```json theme={null}
    {
      "mcpServers": {
        "janet-ai": {
          "command": "mcp-remote",
          "args": ["https://mcp.janet.ai/mcp"]
        }
      }
    }
    ```

    `mcp-remote` runs locally, performs the PKCE handshake with `https://mcp.janet.ai/mcp` on your behalf, and exposes the server over stdio to your agent. This works with any client that supports stdio-based MCP servers.
  </Accordion>
</AccordionGroup>
