Autonnel v0.1.0

MCP server

Connect AI agents to your autonnel deploy through the Model Context Protocol over HTTP.


Autonnel exposes its admin API as a Model Context Protocol (MCP) server. Agents that speak MCP — Claude Code, Claude Desktop, Cursor, Windsurf, or anything built on the official MCP SDKs — can connect to your autonnel deploy and call its tools directly, without writing a custom REST integration.

Prerequisites

  • A running autonnel deploy accessible over HTTP.
  • An API key. See API keys. Use a key with writeAccess if the agent will create or update funnels, pages, media, or orders.
  • An MCP-capable client.

Endpoint

Autonnel serves MCP over HTTP at:

https://<your-autonnel-deploy>/api/mcp

The endpoint speaks the MCP streamable HTTP transport. There is no separate process to run and no stdio binary to install — it lives in the same Worker or Node process that serves the rest of the site.

It is POST only and stateless. A fresh server and transport are created per request, because the tenant and principal live in request-scoped storage and a shared instance would leak one caller’s tenant into the next. GET and DELETE return 405 with an explanatory JSON-RPC error; there is no session to resume and no session id to send.

Authentication

Every MCP request must include your API key as a Bearer token:

Authorization: Bearer <your-api-key>

Every call is scoped to that key’s tenant — there is no cross-tenant access and no tenant parameter to pass. The key’s effective permissions are the union of the user’s roles. A read-only key can call the read tools; the write tools additionally require writeAccess on the key.

Connecting from a client

Claude Code / Claude Desktop / Cursor / Windsurf

Add an entry to the client’s MCP configuration — .mcp.json at the project root for Claude Code, claude_desktop_config.json for Claude Desktop:

{
  "mcpServers": {
    "autonnel": {
      "transport": "http",
      "url": "https://your-shop.com/api/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_KEY"
      }
    }
  }
}

Reload the client. The autonnel tools appear in its tool list.

Custom agent using the MCP SDK

If you’re building your own agent, install the official SDK and connect with the streamable HTTP transport:

import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';

const transport = new StreamableHTTPClientTransport(
  new URL('https://your-shop.com/api/mcp'),
  {
    requestInit: {
      headers: { Authorization: `Bearer ${process.env.AUTONNEL_API_KEY}` },
    },
  },
);

const client = new Client({ name: 'my-agent', version: '1.0.0' });
await client.connect(transport);

const tools = await client.listTools();

Tools exposed

Twenty tools, one per action. Tools marked write require a key with writeAccess.

DomainTools
Funnelslist_funnels, get_funnel, create_funnel (write), update_funnel (write), delete_funnel (write)
Funnel stepsadd_funnel_page (write), replace_funnel_page (write), remove_funnel_page (write), set_funnel_step_slug (write)
Pageslist_pages, get_page, create_page (write), update_page (write)
Page templateslist_templates, get_template
Cataloglist_products
Mediaupload_media (write)
Orderslist_orders, deliver_order (write)
Statsget_stats

Each tool’s input schema is exposed through standard MCP introspection — the client’s listTools call returns the full definitions. You do not need to read separate documentation for tool signatures; the agent reads them on connect.

Two things the tool list deliberately does not include:

  • Refunds and order mutation beyond delivery. deliver_order marks an order delivered and sends the delivery email. There is no refund tool.
  • Ad platform data. Core ads support is token-mode conversion postback only: you configure a pixel id and an access token and orders are posted back server-side. There is no OAuth flow, no campaign or spend query, and no ad-entity writing. If you need spend for a ROAS calculation, read it from the ad platform directly.

Error handling

A failed tool call still returns HTTP 200. Check isError, not the status code.

ConditionWhat you get
Auth failureHTTP 401. The MCP session is never established, so there is no JSON-RPC frame at all.
Unknown tool nameHTTP 200 with a real JSON-RPC error object carrying a numeric code. This is the only in-band failure shaped that way, because it happens before dispatch.
Everything else — missing write access, validation failure, not found, conflict, server errorHTTP 200 with result.isError === true and the message in result.content[0].text, and no JSON-RPC error object.

So the check is: if error is present, it is an unknown tool. Otherwise read result.isError before trusting result.content. A client that only inspects the HTTP status, or only looks for a JSON-RPC error key, will treat every rejected write as if it succeeded.

The message text is worth reading rather than retrying blindly: a validation failure names the exact field path, and a conflict names the rule that was hit — a duplicate page slug, or a duplicate stepSlug within a funnel.

MCP vs the external REST API

Both surfaces back the same underlying operations, but they are not interchangeable tool for tool.

  • MCP is the right choice when an AI agent needs to call autonnel as part of its tool-use loop. The agent discovers tools at connect time, reads their schemas, and calls them with structured arguments.
  • External REST API is the right choice for a deterministic integration — a cron, a webhook handler, a one-off script.

Thirteen of the twenty tools are also reachable over REST through a shared bridge that runs the identical schema and handler, so those two surfaces cannot drift. The other seven are MCP-only: list_funnels, get_funnel, list_pages, get_page, list_products, deliver_order, get_stats. Some of those have no REST equivalent; others have an older, independently implemented endpoint at the same path prefix with a different response shape or query-parameter name — for example GET /api/v1.1/products takes q, not search. Do not assume a REST endpoint matches the MCP tool of the same name.

One path trap worth knowing: /api/v1.1/templates is an older endpoint that lists email templates for Settings → Email Templates. Puck page templates, which is what list_templates and get_template return, are at /api/v1.1/page-templates.

Both surfaces share the same authentication, the same writeAccess gate, and the same permission feature IDs.

Caveats

  • The MCP endpoint serves the same deployment your API key belongs to. There is no tool to switch deployments mid-session.
  • draftData on a page is not structurally validated. Nothing checks the root / content / zones shape, required props, or component type names before saving — a malformed document is accepted and only breaks at render time. Take the shape from get_template({ key }) rather than inventing it, and confirm with get_page after writing.
  • update_page replaces draftData wholesale. Read the page first and edit only the props you mean to change; a regenerated document silently drops props you did not author.
  • get_stats counts unique users, not page views. Five visits by one visitor is 1. Do not compare it against raw pageview counts from another system.
  • Tool definitions are stable within an autonnel release. If your agent caches the tool list, refresh it after upgrading autonnel.