Docs

Embed MCP

Give an AI agent — your own, or your customers' — control of Coassemble. The agent operates the whole course lifecycle through one tool surface, exposed both as an MCP server (for MCP-speaking clients) and as plain REST endpoints (for everything else).

What the agent can do

The agent exposes the course lifecycle as tools:

  • Create — courses, screens, and blocks.
  • Enrich — themes, brand voice, translations, and narration.
  • Publish & share — publishing and share links.
  • Organise — collections and folders.
  • Measure — course analytics.

Which tools a token can run is filtered by the workspace plan, an optional per-token allowlist, and a read-only flag (see Tenancy & scoping).

MCP vs. agent-tooling endpoints

Two ways to reach the same tools — pick whichever fits your integration:

  • MCP (POST /api/v1/agent/mcp, JSON-RPC 2.0) — for clients and agent frameworks that speak the Model Context Protocol. The client connects once, discovers the tools, and calls them. This is the right choice when an LLM is driving the integration.
  • Agent tooling (GET /api/v1/agent/tools, POST /api/v1/agent/tools/{name}, plain REST) — for HTTP integrations that do not speak MCP. List the available tools, then call one by name. See the Agent API reference.
info
There is also a consumer MCP at POST /mcp for connecting your own AI client (Claude, Cursor, and others) to your workspace. It uses an OAuth sign-in flow instead of an agent token, and you can connect it straight from the MCP tab in your workspace settings — no code required.

Authentication Build and above

Embed MCP and the agent tooling endpoints are authenticated with an agent token — a bearer token you mint with your workspace API key. It requires the api_advanced entitlement.

Mint an agent token
curl -X POST https://api.coassemble.com/api/v1/agent/auth \
  -H "Authorization: COASSEMBLE:<workspaceId>:<apiKey>" \
  -H "Content-Type: application/json" \
  -d '{
    "identifier": "user@example.com",
    "clientIdentifier": "tenant-123",
    "readonly": false
  }'

The response contains the token and its expiresAt. Tokens expire after 4 hours by default and are read-only unless you pass readonly: false. Full request/response schema is in the Agent API reference.

Tenancy & scoping

The token you mint carries the scope the agent runs within:

  • identifier — the stable end-user the agent acts as (required).
  • clientIdentifier — a customer key for multi-tenant embeds. Named tokens are limited to that customer. When absent or blank, an unpinned agent/MCP token can list, open, change and publish any live course and edit any collection in the workspace. Course and collection pins still apply. Analytics and coach insights for these tokens only cover courses not assigned to a customer.
  • tools — a per-token allowlist, still subject to the course scope and read-only setting. Omit to expose all tools permitted by those settings.
  • courseId — pin the token to a single course. Course tools and supporting reads (brand voice, themes, assets, narration voices and usage) remain available; workspace-wide tools such as list_courses are hidden unless explicitly allowlisted.
  • readonly — omitted or true means only read tools run. Pass false for write access.

A denied tool response names the pinned course and explains the next action. For an agent token, mint a replacement with the required tool in tools; keep courseId to retain the course boundary. Embedded builders cannot grant workspace-wide tools through an allowlist — use workspace-authorized access outside the builder. In the builder, saved context is limited to the course or session.

Connecting over MCP

Point your MCP client at POST /api/v1/agent/mcp with Authorization: Bearer <agent-token>. The transport is JSON-RPC 2.0 over HTTP. A typical session initializes, lists tools, then calls them:

initialize
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-06-18",
    "capabilities": {},
    "clientInfo": { "name": "your-app", "version": "1.0.0" }
  }
}
tools/list
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list"
}
tools/call
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "create_course",
    "arguments": { "title": "Onboarding 101" }
  }
}