Autonnel

オープンソースのファネルビルダーAutonnelに組み込まれたMCPサーバー。エージェントは、スコープが限定されたAPIキーを使ってHTTP経由でファネル、ページ、注文を読み書きできます。

ドキュメント

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

Desktop and IDE agents

For Claude Code, add an entry to .mcp.json at the project root (or run claude mcp add --transport http autonnel https://your-shop.com/api/mcp --header "Authorization: Bearer YOUR_KEY"):

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

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

Other clients:

  • Claude Desktop / claude.ai: it does not read remote servers from claude_desktop_config.json. Go to Customize → Connectors → + Add → Add custom connector, enter the URL, choose No sign in, and add Authorization: Bearer YOUR_KEY under Request headers. Claude connects from Anthropic’s cloud, so the deploy must be publicly reachable.
  • ChatGPT desktop app / Codex (~/.codex/config.toml, shared by the app, CLI and IDE extension):
    [mcp_servers.autonnel]
    url = "https://your-shop.com/api/mcp"
    bearer_token_env_var = "AUTONNEL_API_KEY"
    
  • Cursor (~/.cursor/mcp.json): the same JSON as above without "type", with the header value "Bearer ${env:AUTONNEL_API_KEY}".
  • Windsurf (mcp_config.json, opened from Cascade’s MCP settings): the same JSON with "serverUrl" instead of "url".

For a one-off task you can skip the config and paste the key into the chat instead; see Tutorial: edit a page with an AI agent.

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.

Related