{
  "schemaVersion": "1.0",
  "product": "TopCal",
  "humanPage": "https://topcal.ai/developers",
  "agentMarkdown": "https://topcal.ai/developers.md",
  "install": "https://topcal.ai/INSTALL.md",
  "skill": "https://topcal.ai/skill/SKILL.md",
  "exploreEndpoints": {
    "label": "Explore endpoints",
    "docs": "https://app.topcal.ai/docs",
    "openapi": "https://app.topcal.ai/api/v1/openapi",
    "discovery": "https://app.topcal.ai/.well-known/agent-discovery.json"
  },
  "origins": {
    "public": "https://topcal.ai",
    "app": "https://app.topcal.ai",
    "mcpConnector": "https://mcp.topcal.ai/mcp"
  },
  "jobs": [
    {
      "id": "guest_book",
      "title": "Book a public link",
      "requiresApiKey": false,
      "antiAbuse": "email-otp",
      "bookingUrl": "https://topcal.ai/{workspace}/{username}/{eventSlug}",
      "restBase": "https://topcal.ai/api/v1/public",
      "get": [
        {
          "method": "GET",
          "path": "/api/v1/public/{workspace}/{username}",
          "purpose": "List their event types and any form fields you must collect."
        },
        {
          "method": "GET",
          "path": "/api/v1/public/{workspace}/{username}/{eventSlug}/slots?timezone={IANA}",
          "purpose": "Read open times. Each slot has UTC and a local display string."
        },
        {
          "method": "GET",
          "path": "/api/v1/public/{workspace}/{username}/{eventSlug}/otp?email=&startAt=&timezone=&name=",
          "purpose": "Email the code. Response has confirmUrl — use that, not a token field."
        },
        {
          "method": "GET",
          "path": "{confirmUrl}&code={6 digits}",
          "purpose": "Confirm with the digits the guest read from email. Never guess."
        }
      ],
      "post": [
        {
          "method": "POST",
          "path": "/api/v1/public/{workspace}/{username}/{eventSlug}/otp",
          "purpose": "Same code email. Body: { email, name? }."
        },
        {
          "method": "POST",
          "path": "/api/v1/public/{workspace}/{username}/{eventSlug}/book",
          "purpose": "Finish the booking. Body: { startAt, code, invitee, customFields? }."
        }
      ],
      "manage": {
        "note": "Token comes from the manage link in the confirmation email. Never guess it.",
        "endpoints": [
          {
            "method": "POST",
            "path": "/api/v1/public/{workspace}/{username}/{eventSlug}/cancel",
            "purpose": "Cancel with the manage token. Body: { token, reason? }."
          },
          {
            "method": "POST",
            "path": "/api/v1/public/{workspace}/{username}/{eventSlug}/reschedule",
            "purpose": "Move to a new slot. Body: { token, startAt }. Pick startAt from a fresh slots call."
          },
          {
            "method": "POST",
            "path": "/api/v1/public/manage/cancel",
            "purpose": "Same cancel when you only have the token. Body: { token, reason? }."
          },
          {
            "method": "POST",
            "path": "/api/v1/public/manage/reschedule",
            "purpose": "Same reschedule by token alone. Body: { token, startAt }."
          }
        ]
      },
      "mcp": {
        "url": "https://topcal.ai/api/mcp/public/mcp",
        "transport": "streamable-http",
        "requiresAuth": false,
        "tools": [
          {
            "name": "find_bookable_calendar",
            "purpose": "Start here. Workspace + username → events and form fields."
          },
          {
            "name": "get_availability",
            "purpose": "Open slots for one event. Pass the guest's IANA timezone."
          },
          {
            "name": "request_booking_code",
            "purpose": "Email a 6-digit code to the guest."
          },
          {
            "name": "confirm_booking",
            "purpose": "Book with startAt, the code, invitee, and optional customFields."
          }
        ]
      },
      "customFields": "Pass requiredFieldKeys from GET …/{username} as customFields on book."
    },
    {
      "id": "host_setup",
      "title": "Share your own link",
      "requiresApiKey": false,
      "auth": "device-auth — topcal auth register opens a browser approve page",
      "steps": [
        "Paste: Set up https://topcal.ai/INSTALL.md",
        "Agent runs: npx --yes -p @topcal/cli topcal setup --json",
        "Human only: sign up (14-day Growth trial, no card), Allow CLI, connect Google/Microsoft."
      ],
      "cli": {
        "package": "@topcal/cli",
        "setup": "npx --yes -p @topcal/cli topcal setup --json --url https://app.topcal.ai --client-name agent\n# Human: sign up / confirm email if asked → Allow CLI → connect calendar\nnpx --yes -p @topcal/cli topcal tools list --json"
      },
      "openapi": "https://app.topcal.ai/api/v1/openapi",
      "docs": "https://app.topcal.ai/docs",
      "mcp": "https://app.topcal.ai/api/mcp/mcp",
      "mcpConnector": "https://mcp.topcal.ai/mcp",
      "discovery": "https://app.topcal.ai/.well-known/agent-discovery.json",
      "agentGuide": "https://app.topcal.ai/signup/agents",
      "install": "https://topcal.ai/INSTALL.md",
      "skill": "https://topcal.ai/skill/SKILL.md"
    },
    {
      "id": "operate_workspace",
      "title": "Operate the workspace",
      "note": "Same tool catalog as Cal Agent through the CLI, the in-app MCP shim, the remote MCP connector, or REST.",
      "cli": {
        "package": "@topcal/cli",
        "tools": "npx --yes -p @topcal/cli topcal tools list --json\nnpx --yes -p @topcal/cli topcal tools call get_workspace --json\nnpx --yes -p @topcal/cli topcal tools call list_meetings --args '{\"filter\":\"upcoming\"}' --json"
      },
      "mcpConnector": {
        "url": "https://mcp.topcal.ai/mcp",
        "transport": "streamable-http",
        "auth": "oauth2.1-pkce",
        "authorizationServer": "https://app.topcal.ai",
        "note": "Remote MCP for ChatGPT, Claude, and custom connectors. OAuth 2.1 + PKCE, no API key, no terminal.",
        "steps": [
          "Add the MCP URL https://mcp.topcal.ai/mcp as a connector.",
          "The human signs in and clicks Allow — same Google, Microsoft, or magic-link login.",
          "Call get_workspace, then the same tools as the CLI. Do not ask for an API key; connectors reject keys."
        ]
      },
      "mcpShim": {
        "url": "https://app.topcal.ai/api/mcp/mcp",
        "transport": "streamable-http",
        "auth": "http-bearer",
        "note": "In-app MCP on app.topcal.ai. Bearer API key after CLI device auth."
      },
      "rest": {
        "base": "https://app.topcal.ai/api/v1",
        "endpoints": [
          {
            "method": "GET",
            "path": "/api/v1/workspace/tools",
            "purpose": "List the workspace tools your API key owner can run — same catalog as Cal Agent."
          },
          {
            "method": "POST",
            "path": "/api/v1/workspace/tools/execute",
            "purpose": "Run one tool. Body: { name, arguments? }."
          }
        ],
        "auth": "Bearer API key (tofu_live_…) from CLI device auth"
      }
    }
  ],
  "rules": [
    "Guest bookings use the guest's email. They confirm the code. You book on their behalf.",
    "Never invent API keys or codes. Hosts run topcal setup.",
    "Public booking lives on topcal.ai. Sign-in and host API live on app.topcal.ai.",
    "Read slots JSON. Do not scrape the HTML booking page.",
    "A website button is an HTML link (app.topcal.ai/docs/embed), not a REST integration.",
    "Guests cancel or reschedule from the manage link in their confirmation email. Agents use that token on the public cancel and reschedule endpoints. Never guess a token."
  ],
  "workspaces": {
    "multiWorkspace": true,
    "summary": "One account spans multiple workspaces: personal, department, agency client books.",
    "membership": "A user can own one workspace, admin another, and be a member of a third. Each membership has its own username slug.",
    "addressing": "Every book is addressed by path: topcal.ai/{workspace}/{username}/{eventSlug}. Team round-robin: topcal.ai/{workspace}/team/{teamSlug}/{eventSlug}. Short revocable link: topcal.ai/b/{token}.",
    "agentScoping": "API keys, MCP sessions, and CLI device approvals bind to exactly one workspace. An agent operates only where its key is bound; cross-workspace access requires a separate assignment.",
    "publicPlane": "Guest booking needs no key and is workspace-addressed: GET /api/v1/public/{workspace}/{username} …",
    "manifest": "https://app.topcal.ai/.well-known/agent-discovery.json"
  },
  "related": {
    "llms": "https://topcal.ai/llms.txt",
    "agentInstructions": "https://topcal.ai/.well-known/agent-instructions.md",
    "pricingMarkdown": "https://topcal.ai/pricing.md",
    "pricingJson": "https://topcal.ai/pricing.json",
    "embedGuide": "https://app.topcal.ai/docs/embed",
    "openapi": "https://app.topcal.ai/api/v1/openapi",
    "mcpConnector": "https://mcp.topcal.ai/mcp",
    "mcpHost": "https://app.topcal.ai/api/mcp/mcp",
    "mcpPublic": "https://topcal.ai/api/mcp/public/mcp"
  }
}