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

# MCP Server

> Connect AI agents like Claude and Cursor to your Crevio account using the Model Context Protocol (MCP) to manage your business with natural language.

**The Crevio MCP server gives an AI agent the full run of your business — anything you can do in the dashboard, an agent can do through MCP.** It exposes two tools that accept Ruby code: one to discover available API endpoints, and one to execute them. Two tools, full API coverage, minimal context usage. This is Crevio's flagship agent surface: because every operation routes through the [same controllers](#security) as the [REST API](/developer/guides/api-overview), connecting an agent gives it parity with a human operator — products, checkouts, customers, email, socials, sites, domains, calls, and web research, all driven in natural language.

<Info>
  New to Crevio's agentic model? Start with the [AI & Agents overview](/developer/guides/agents-overview) to see how MCP, [Tasks](/developer/guides/tasks), and [Events](/developer/guides/events) fit together. This page is the MCP surface in depth.
</Info>

## What is MCP?

[Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard that gives AI assistants a way to connect to external tools and data sources. Instead of manually writing API calls, an AI agent discovers and invokes your Crevio API through MCP — using natural language.

## How it works

Traditional MCP servers expose one tool per API endpoint. This works for small APIs, but quickly becomes impractical — each tool definition consumes tokens in the AI model's context window. At 155 operations across 102 API paths and \~427 tokens per tool, that's over 66,000 tokens burned before the agent does anything useful.

Crevio uses **Code Mode** — inspired by [Cloudflare's approach](https://blog.cloudflare.com/code-mode-mcp/) — with just two tools:

1. **`code_search`** — The agent writes Ruby code to filter and explore the API catalog
2. **`code_execute`** — The agent writes Ruby code to call endpoints, chain requests, and transform results

The key insight: LLMs write code better than they navigate large JSON schemas. Give them a programming environment and they figure it out.

The agent never sees the full API spec. It discovers only what it needs, keeps context lean, and gets the same responses as the [REST API](/developer/guides/api-overview). Multi-step workflows that would require 10+ tool calls collapse into a single code execution.

## Connect

The server is available at `https://mcp.crevio.co/mcp` over **Streamable HTTP** transport, authenticated with a Bearer token — the [same API token](/developer/guides/api-overview#creating-api-tokens) you'd use for REST. Any MCP-compatible client connects: Claude Desktop, Cursor and other AI IDEs, or your own agent built on an MCP SDK. Once connected, the client lists two tools (`code_search`, `code_execute`) and the agent uses them to discover and call your API in code.

<Card title="Connecting" icon="plug" href="/developer/mcp/connection">
  Set up Claude Desktop, Cursor, or any MCP-compatible client.
</Card>

## The two tools

### `code_search` — Discover API endpoints

A **read-only, idempotent** tool for exploring the Crevio API. Write Ruby code to filter and search the API catalog. A `tools` method is available that returns all 155 operations (across 102 API paths) as an array of hashes.

Each entry has keys: `:method`, `:path`, `:summary`, `:description`, `:tags`, `:parameters`, and `:request_body`.

```json theme={null}
{
  "name": "code_search",
  "arguments": {
    "code": "tools.select { |t| t[:path].include?(\"products\") }.map { |t| \"#{t[:method]} #{t[:path]} — #{t[:summary]}\" }"
  }
}
```

Returns:

```json theme={null}
{
  "result": [
    "GET /products — List products",
    "POST /products — Create product",
    "GET /products/{id} — Get product details",
    "PATCH /products/{id} — Update product",
    "DELETE /products/{id} — Delete product"
  ]
}
```

More search examples:

```ruby theme={null}
# List all available resource groups (tags)
tools.map { |t| t[:tags] }.flatten.compact.uniq.sort

# Find endpoints that accept a specific parameter
tools.select { |t| t[:parameters]&.any? { |p| p["name"] == "status" } }

# Count endpoints per tag
tools.group_by { |t| t[:tags]&.first }.transform_values(&:size)

# Get full details for a specific endpoint
tools.find { |t| t[:method] == "POST" && t[:path] == "/products" }
```

### `code_execute` — Run API operations

Executes Ruby code against the live Crevio API in a sandboxed environment. Available methods:

* `get(path, **params)` — GET request
* `post(path, **params)` — POST request
* `patch(path, **params)` — PATCH request
* `delete(path, **params)` — DELETE request

Paths are automatically prefixed with `/v1`. Parameters are sent as query params for `GET`/`DELETE` and as a JSON body for `POST`/`PATCH`.

```json theme={null}
{
  "name": "code_execute",
  "arguments": {
    "code": "get(\"/products\")"
  }
}
```

The power of code mode is **chaining multiple calls in a single execution**:

```ruby theme={null}
# List products and get their names
products = get("/products")
products["data"].map { |p| p["name"] }
```

```ruby theme={null}
# Create a product, then a price variant (note creation order:
# a product needs a price variant before it can be set "active")
product = post("/products", name: "My Course", slug: "my-course", status: "draft")
post("/price_variants",
  product: product["id"],     # bare association name + prefix-id string, not product_id
  name: "Standard",
  amount_type: "fixed",
  amount: 4900,               # cents — $49.00
  currency: "usd",
  billing_type: "one_time"
)
```

```ruby theme={null}
# Cross-resource aggregation — 3 API calls, one round-trip
account = get("/account")
customers = get("/customers")
products = get("/products")
{
  account_name: account["name"],
  total_customers: customers["data"].size,
  total_products: products["data"].size,
  product_names: products["data"].map { |p| p["name"] }
}
```

```ruby theme={null}
# Batch update — update all active products in one shot
products = get("/products")["data"]
updated = products.select { |p| p["status"] == "active" }.map do |p|
  patch("/products/#{p['id']}", status: "archived")
  p["name"]
end
{ updated_count: updated.size, names: updated }
```

The `code_execute` tool dispatches requests through the **same API controllers** as `api.crevio.co` — all authorization, validation, and rate limiting apply. Responses match the [REST API format](/developer/guides/api-overview#conventions) exactly.

## Same API, same conventions

Because MCP runs through the same controllers as REST, the agent must follow the same [conventions and gotchas](/developer/guides/api-overview#conventions) — there are no MCP-specific shortcuts:

* **Params are unwrapped.** Fields go at the top level. A `{ product: { ... } }` wrapper is silently dropped — pass `post("/products", name: "...", status: "draft")`.
* **Associations are bare names + prefix-id strings.** Use `product: "prod_abc123"`, not `product_id`. (A few schema fields keep an `_id` suffix, e.g. `site_id`, `tag_ids` — match the field name exactly.)
* **Creation order matters.** A product needs at least one price variant before it can go `active`; creating it `active` in one call fails with `422`. Create draft → add price variant(s) → `patch` status to `active`.
* **List vs single.** List endpoints return `{ "object": "list", "data": [...], "has_more": ... }`; single resources return the object directly.
* **Money is in cents**, `currency` is lowercase ISO (`"usd"`), and `?expand=` inlines related resources.

When the agent hits a `404 resource_missing` on a POST/PATCH, it's almost always a bad or nil association id — not a routing problem.

## Example: How an agent handles a request

When you ask *"Create a buy-one-get-one discount for my course"*, here's what happens under the hood:

<Steps>
  <Step title="Discover relevant endpoints">
    The agent calls `code_search` with Ruby code to find discount and product endpoints:

    ```ruby theme={null}
    tools.select { |t| t[:tags]&.include?("Discounts") || t[:tags]&.include?("Products") }
         .map { |t| { method: t[:method], path: t[:path], summary: t[:summary] } }
    ```
  </Step>

  <Step title="Find the product and create the discount">
    The agent calls `code_execute` to chain everything together in one shot:

    ```ruby theme={null}
    # Find the course's price variant, then scope the discount to it
    products = get("/products")
    course = products["data"].find { |p| p["name"].downcase.include?("course") }
    variant = get("/price_variants", product: course["id"])["data"].first

    discount = post("/discounts",
      code: "BOGO",
      discount_type: "percentage",
      percent_off: 100,
      duration: "once",
      price_variants: [variant["id"]]   # scope to specific price ids
    )

    { product: course["name"], discount_code: discount["code"] }
    ```
  </Step>

  <Step title="Confirm the result">
    The agent formats the response and tells you the discount was created with code `BOGO`.
  </Step>
</Steps>

The whole interaction uses just **2 tool calls** — one search, one execution — regardless of how many API endpoints Crevio has.

## What's available

Everything accessible through the [REST API](/developer/guides/api-overview#what-you-can-do-with-the-api) is available via MCP:

| Category                | Operations                                                |
| ----------------------- | --------------------------------------------------------- |
| **Account**             | Retrieve, update                                          |
| **Profile**             | Retrieve your user profile                                |
| **Products**            | Create, update, delete, list, retrieve                    |
| **Price variants**      | Create, update, delete, list, retrieve                    |
| **Experiences**         | List, retrieve (courses, downloads, links)                |
| **Reviews**             | Create, update, delete, list, retrieve                    |
| **Blog posts**          | List, retrieve                                            |
| **Blog categories**     | List, retrieve                                            |
| **Legal pages**         | List, retrieve, update                                    |
| **Checkouts**           | Create, retrieve, update                                  |
| **Checkout links**      | Create, update, delete, list, retrieve                    |
| **Orders**              | List, retrieve                                            |
| **Order items**         | List, retrieve                                            |
| **Refunds**             | Create, list, retrieve                                    |
| **Invoices**            | Create, list, retrieve, void                              |
| **Subscriptions**       | List, retrieve, cancel, pause, resume                     |
| **Customers**           | Create, update, delete, list, retrieve, tag               |
| **Tags**                | Create, update, delete, list, retrieve                    |
| **Discounts**           | Create, update, delete, list, retrieve                    |
| **Socials**             | Manage connected accounts, posts, comments, and analytics |
| **Forms**               | Create, update, delete, list, retrieve, archive, restore  |
| **Form submissions**    | List, create, retrieve                                    |
| **Tasks**               | Create, update, delete, list, retrieve                    |
| **Task runs**           | List, retrieve, update                                    |
| **Event sources**       | List, create, delete, retrieve, discover available        |
| **Events**              | List subscribable events                                  |
| **Formations**          | Create, list, retrieve, submit, retry payment             |
| **Formation documents** | List, retrieve                                            |
| **AI sites**            | Create, update, delete, list, retrieve                    |
| **Files**               | Create, list, retrieve, delete, confirm upload            |
| **Emails**              | Send                                                      |
| **Webhook endpoints**   | Create, update, delete, list, retrieve, test              |
| **Webhook events**      | List, retrieve                                            |

## Security

The code execution environment runs in a **sandboxed BasicObject clean room** — the agent cannot access the filesystem, network, environment variables, or Ruby's standard library. Only safe operations (arrays, hashes, strings, iteration) and the API dispatch methods are available. A 5-second timeout prevents runaway executions.

All operations run within your account's tenant boundary — the same multi-tenant isolation as the REST API. The MCP server dispatches requests through the same API controllers as `api.crevio.co`. No special code paths — the agent gets the same behavior, validation, and error messages as direct API calls.

## Next steps

<CardGroup cols={2}>
  <Card title="Connecting" icon="plug" href="/developer/mcp/connection">
    Set up Claude Desktop, Cursor, or any MCP-compatible client.
  </Card>

  <Card title="AI & Agents overview" icon="robot" href="/developer/guides/agents-overview">
    How MCP, Tasks, and Events form Crevio's agentic model.
  </Card>

  <Card title="Tasks (your AI workforce)" icon="list-check" href="/developer/guides/tasks">
    Turn the agent into a scheduled, autonomous workforce.
  </Card>

  <Card title="API conventions" icon="book" href="/developer/guides/api-overview#conventions">
    The shapes, prefixes, and gotchas every call shares.
  </Card>
</CardGroup>
