Erza Studioerza AI

Erza MCP Server

Connect Claude, Cursor, VS Code and any other Model Context Protocol client to your Erza workspace. Write, rewrite, schedule and publish articles from the assistant you already use.

npx -y @erza-ai/erza-mcp

01

Overview

Erza MCP is a Model Context Protocol server that exposes your Erza workspace as tools. Any MCP client can list, write, rewrite, export, schedule and publish articles with the same account, plan and credits you use in the app.

MCP clientClaude · Cursor · VS Code
erza-mcplocal or hosted
Erza APIapi.erza.ai
The server is a thin adapter: every tool call maps onto an existing Erza API endpoint, and billing, roles, rate limits and generation stay in the Erza API. Run it locally over stdio, or connect to the hosted endpoint over Streamable HTTP.
  • Native binary for each platform, launched through npx. Nothing else to install.
  • One required setting: ERZA_API_KEY.
  • 18 tools with MCP annotations (readOnlyHint, destructiveHint), so clients can ask before risky calls.
  • Structured errors with a stable code and a retryable flag.

02

Requirements

Check these before you install.

  • An Erza account

    Any plan works. Tools that generate with AI spend credits from your wallet.

  • An API key

    A personal key that starts with ez_live_, created in Settings → API Keys.

  • Node.js with npx

    Only for the local (stdio) setup. The hosted endpoint needs nothing installed.

Supported platforms
Operating systemArchitectureBundled binary
macOSarm64 (Apple Silicon), x64 (Intel)erza-mcp-darwin-<arch>
Linuxx64, arm64erza-mcp-linux-<arch>
Windowsx64, arm64erza-mcp-win32-<arch>.exe

03

Create an API key

The key identifies you to the Erza API. Every tool call runs as your account.

  1. Sign in to Erza and open Settings → API Keys.
  2. Click Create API key and give it a name you will recognise later, such as mcp-laptop.
  3. Copy the ez_live_… token right away. It is shown only once; after that only its prefix is visible.
Lost the key? Revoke it and create a new one. Revoking takes effect immediately for every client that uses it.

04

Install

Pick your client and a transport. Paste your key into the field below to fill it into every snippet.

Only used to fill the snippets on this page. It stays in your browser and is never sent or stored.

Runs the native binary on your machine through npx and talks to the client over stdio.

Claude Code

stdio
  1. Run the command in your terminal. --scope user makes Erza available in every project; leave it out to add Erza to the current project only.
  2. Start a new Claude Code session and run /mcp to see the server and its tools.
bash
claude mcp add erza --scope user \
  --env ERZA_API_KEY=ez_live_your_api_key_here \
  -- npx -y @erza-ai/erza-mcp

05

Verify the connection

Confirm the server starts and lists its tools before you rely on it in a chat.

MCP Inspector

Runs the official inspector against the local server and opens a web UI. Connect, then List Tools should return 18 tools. Put your key in first.

bash
npx @modelcontextprotocol/inspector \
  -e ERZA_API_KEY=ez_live_your_api_key_here \
  npx -y @erza-ai/erza-mcp

Claude Code

claude mcp list starts every configured server and prints its connection status.

bash
claude mcp list
# erza: npx -y @erza-ai/erza-mcp - ✓ Connected

Hosted endpoint

The hosted server answers ok on /healthz. A request to /mcp without a key returns 401.

bash
curl https://mcp.erza.ai/healthz
# ok
First prompt to try: “List my 5 latest Erza articles.” The assistant should call erza_article_list and show titles and statuses.

06

Configuration

The local server is configured with environment variables. Only the API key is required.

Environment variables

Environment variables
VariableDefaultDescription
ERZA_API_KEYRequired—Your personal key, ez_live_…. Sent as X-API-Key on every Erza API request.
ERZA_API_BASE_URLOptionalhttps://api.erza.aiErza API endpoint. Change it only for local development or a private instance.
ERZA_WS_BASE_URLOptionalwss://api.erza.aiWebSocket endpoint used to start generations. Derived from ERZA_API_BASE_URL (https → wss) when unset.

Hosted endpoint

POST https://mcp.erza.ai/mcp
Streamable HTTP endpoint. Stateless: no session is kept between requests.
X-API-Key: ez_live_…
Auth header, sent on every request. Authorization: Bearer ez_live_… works too.
GET https://mcp.erza.ai/healthz
Health check. Returns ok.
401 Unauthorized
Returned when a request has no key: missing credentials: send X-API-Key or Authorization: Bearer.

07

Tools reference

18 tools in four groups. Expand a tool to see its parameters and the Erza API endpoint it calls.

  • Read-onlyNo side effects, safe to repeat.
  • WritesCreates or changes data.
  • DestructiveCannot be undone.
  • CreditsSpends wallet credits.

18 tools shown

  • erza_article_listRead-onlyList your articles, newest first, with status, type and pagination.
    Upstream
    GET /api/articles
    Annotations
    readOnlyHint: truedestructiveHint: false
    Parameters of erza_article_list
    ParameterTypeDescription
    pageinteger1-based page number. Defaults to 1.
    limitintegerItems per page, 1-50. Defaults to 10.
    statusstringFilter by article status, e.g. 'draft', 'published', 'complete'.
    article_typestringFilter by article type name, e.g. 'template-auto'.
    titlestringSubstring filter on the article title.
  • erza_article_getRead-onlyRead one article in full, including its content blocks.
    Upstream
    GET /api/articles/{id}
    Annotations
    readOnlyHint: truedestructiveHint: false
    Parameters of erza_article_get
    ParameterTypeDescription
    article_idRequiredstringArticle id returned by erza_article_list.
    include_blocksbooleanInclude the article content blocks. Defaults to true.
  • erza_article_list_typesRead-onlyList the article types your account can create.
    Upstream
    GET /api/article-types
    Annotations
    readOnlyHint: truedestructiveHint: false
    Parameters of erza_article_list_types
    ParameterTypeDescription
    pageinteger1-based page number. Defaults to 1.
    limitintegerItems per page, 1-50. Defaults to 20.
  • erza_article_exportRead-onlyExport an article as PDF or DOCX and return the download URL.
    Upstream
    POST /api/articles/{id}/download/{pdf,docx}
    Annotations
    readOnlyHint: truedestructiveHint: false
    Parameters of erza_article_export
    ParameterTypeDescription
    article_idRequiredstringArticle id to export.
    format'pdf' | 'docx'Export format. Defaults to 'pdf'.
  • erza_article_generateWritesCreditsStart an AI generation of 1–5 articles. Returns a generation id right away.
    Upstream
    POST /api/internal/ws-ticket → WS /ws/articles (auto | quick)
    Annotations
    readOnlyHint: falsedestructiveHint: false
    Parameters of erza_article_generate
    ParameterTypeDescription
    itemsRequiredobject[1..5]1 to 5 generation items. Every item consumes credits.
    items[].topicRequiredstringThe topic (or title/topic mix) to write about, 3-200 characters.
    items[].templatestringTemplate id to render. Omit to let Erza pick the user's default template.
    items[].keywordsstringTarget keywords, at most 5, comma-separated.
    items[].titlestringUse this value as the final title verbatim instead of letting the model write one.
    mode'auto' | 'quick''auto' (default) generates outline, assets and the full article; 'quick' is fast template generation.
    languagestringContent language tag forwarded as Accept-Language, e.g. 'id-ID' or 'en-US'. Defaults to the account setting.
  • erza_article_rewriteWritesCreditsRewrite from a topic, keyword, source text or reference URLs.
    Upstream
    POST /api/internal/ws-ticket → WS /ws/articles (rewrite_article)
    Annotations
    readOnlyHint: falsedestructiveHint: false
    Parameters of erza_article_rewrite
    ParameterTypeDescription
    itemsRequiredobject[1..5]1 to 5 rewrite items. Every item consumes credits.
    items[].topicRequiredstringTopic or title of the article to rewrite, 3-200 characters.
    items[].keywordstringOptional focus keyword.
    items[].sourcesstring[]Optional list of reference/source URLs.
    items[].source_textstringOptional raw text content to rewrite from.
    languagestringContent language tag forwarded as Accept-Language, e.g. 'id-ID' or 'en-US'. Defaults to the account setting.
  • erza_article_regenerateWritesCreditsRegenerate an existing article from scratch.
    Upstream
    POST /api/internal/ws-ticket → WS /ws/articles (regenerate)
    Annotations
    readOnlyHint: falsedestructiveHint: false
    Parameters of erza_article_regenerate
    ParameterTypeDescription
    article_idRequiredstringArticle id to regenerate.
    languagestringContent language tag forwarded as Accept-Language, e.g. 'id-ID' or 'en-US'. Defaults to the account setting.
  • erza_article_regenerate_sectionWritesCreditsRegenerate one content block, with an optional guiding prompt.
    Upstream
    POST /api/internal/ws-ticket → WS /ws/articles (regenerate_section)
    Annotations
    readOnlyHint: falsedestructiveHint: false
    Parameters of erza_article_regenerate_section
    ParameterTypeDescription
    article_idRequiredstringArticle id containing the section.
    content_block_idRequiredstringContent block id of the section to regenerate.
    section_promptstringOptional prompt or guidance for regenerating this section.
    languagestringContent language tag forwarded as Accept-Language, e.g. 'id-ID' or 'en-US'. Defaults to the account setting.
  • erza_generation_listRead-onlyList generation runs with their status and counts.
    Upstream
    GET /api/article-generations
    Annotations
    readOnlyHint: truedestructiveHint: false
    Parameters of erza_generation_list
    ParameterTypeDescription
    pageinteger1-based page number. Defaults to 1.
    limitintegerItems per page, 1-50. Defaults to 10.
    topicstringFilter by the topic submitted for generation.
    modestringFilter by generation mode, e.g. 'auto_generate', 'quick_create', 'rewrite_article'.
  • erza_generation_getRead-onlyGet the status of every article in one generation run.
    Upstream
    GET /api/article-generations/{id}
    Annotations
    readOnlyHint: truedestructiveHint: false
    Parameters of erza_generation_get
    ParameterTypeDescription
    generation_idRequiredstringGeneration id returned by erza_article_generate or erza_article_rewrite.
  • erza_generation_waitRead-onlyPoll a generation until it finishes or the wait budget runs out.
    Upstream
    GET /api/article-generations/{id} (polling)
    Annotations
    readOnlyHint: truedestructiveHint: false
    Parameters of erza_generation_wait
    ParameterTypeDescription
    generation_idRequiredstringGeneration id returned by erza_article_generate or erza_article_rewrite.
    max_wait_secondsintegerHow long to keep polling before answering with the current state, 1-300. Defaults to 60.
    poll_interval_secondsintegerSeconds between polls, 2-30. Defaults to 5.
  • erza_article_create_draftWritesSave your own content as a draft. No AI, no credits.
    Upstream
    POST /api/articles/draft
    Annotations
    readOnlyHint: falsedestructiveHint: false
    Parameters of erza_article_create_draft
    ParameterTypeDescription
    contentRequiredstringMarkdown or HTML body content, at least 1 character.
    article_typeRequiredstringExisting article type name, e.g. 'template-auto'. See erza_article_list_types.
    titlestringOptional title, 5-255 characters when present.
  • erza_article_updateWritesUpdate title, content, excerpt, slug or tags. Only sent fields change.
    Upstream
    PATCH /api/articles/{id}
    Annotations
    readOnlyHint: falsedestructiveHint: false
    Parameters of erza_article_update
    ParameterTypeDescription
    article_idRequiredstringArticle id to update.
    titlestringNew title, 5-255 characters.
    contentstringNew body content, at least 20 characters.
    excerptstringNew excerpt.
    slugstringNew URL slug.
    tagsstring[]Replacement tag list, at most 10 entries.
  • erza_article_deleteDestructiveDelete an article permanently.
    Upstream
    DELETE /api/articles/{id}
    Annotations
    readOnlyHint: falsedestructiveHint: true
    Parameters of erza_article_delete
    ParameterTypeDescription
    article_idRequiredstringArticle id to delete. This cannot be undone.
  • erza_article_sync_wordpressWritesPush an article to its connected WordPress site.
    Upstream
    POST /api/articles/{id}/sync
    Annotations
    readOnlyHint: falsedestructiveHint: false
    Parameters of erza_article_sync_wordpress
    ParameterTypeDescription
    article_idRequiredstringArticle id to sync to WordPress.
    connection_idstringWordPress connection id. If omitted, Erza resolves the article's existing connection.
  • erza_scheduler_createWritesSchedule 1–10 articles for WordPress or Blogger at a set date and time.
    Upstream
    POST /api/scheduler/schedules
    Annotations
    readOnlyHint: falsedestructiveHint: false
    Parameters of erza_scheduler_create
    ParameterTypeDescription
    article_idsRequiredstring[1..10]1 to 10 article ids to schedule for publication.
    scheduled_dateRequiredstringTarget publication date, YYYY-MM-DD.
    connection_idRequiredstringCMS connection id.
    cms_type'wordpress' | 'blogger'Target CMS. Defaults to 'wordpress'.
    timezonestringIANA timezone, e.g. 'Asia/Jakarta' or 'UTC'. Defaults to 'Asia/Jakarta'.
    start_fromstringFirst publishing time on scheduled_date, HH:MM. Defaults to '09:00'.
    interval_minutesintegerMinutes between scheduled articles. Defaults to 30.
    post_status'draft' | 'publish'Post status in the CMS. Defaults to 'draft'.
    wp_author_idintegerOptional WordPress author id.
    confirm_reschedulebooleanConfirm rescheduling when some articles are already scheduled. Defaults to false.
  • erza_scheduler_get_calendarRead-onlyRead scheduled and published articles for a date range.
    Upstream
    GET /api/scheduler/calendar
    Annotations
    readOnlyHint: truedestructiveHint: false
    Parameters of erza_scheduler_get_calendar
    ParameterTypeDescription
    start_dateRequiredstringStart date, YYYY-MM-DD.
    end_dateRequiredstringEnd date, YYYY-MM-DD.
  • erza_scheduler_cancelDestructiveCancel a scheduled publication job.
    Upstream
    DELETE /api/scheduler/schedules/{id}
    Annotations
    readOnlyHint: falsedestructiveHint: true
    Parameters of erza_scheduler_cancel
    ParameterTypeDescription
    job_idRequiredstringSchedule job id to cancel.

08

Generation flow

AI generation is asynchronous. The tool starts the job and returns at once, and progress is read over REST, so it survives reconnects. erza_article_rewrite, erza_article_regenerate and erza_article_regenerate_section follow the same flow.

  1. Start with erza_article_generate

    Send 1–5 items. Returns a generation_id and the new article ids immediately. Credits are charged per item.

  2. Wait with erza_generation_wait

    Polls every poll_interval_seconds (2–30, default 5) for up to max_wait_seconds (1–300, default 60), then returns the status of every article.

  3. Repeat if needed

    If articles are still running, call the wait tool again with the same id. Use erza_generation_get for a single snapshot.

  4. Read with erza_article_get

    Fetch each finished article with its content blocks, then edit, export or schedule it.

erza_article_generate · argumentsjson
{
  "items": [
    {
      "topic": "Brewing manual coffee at home",
      "keywords": "manual brew, v60, pour over"
    }
  ],
  "mode": "auto",
  "language": "id-ID"
}

09

Errors

A failed tool call returns an error result (isError: true) with a structured payload. Agents can branch on code instead of parsing the message.

Errors
codeMeaningretryable
unauthorizedThe API key is missing, invalid or revoked. auth_problem is true.false
insufficient_creditThe wallet does not have enough credits for this generation.false
not_foundThe article, generation or schedule id does not exist for this account.false
invalid_requestA parameter failed validation, for example a topic shorter than 3 characters.false
rate_limitedToo many requests. Wait and retry.true
upstream_errorThe Erza API returned an unexpected HTTP error.true
upstream_unreachableThe Erza API could not be reached (network, DNS or timeout).true
invalid_upstream_responseThe Erza API answered with a body the server could not decode.false
generation_stream_failedThe WebSocket used to start a generation failed before the job was accepted.false
structuredContentjson
{
  "code": "insufficient_credit",
  "message": "insufficient credits: …",
  "retryable": false,
  "auth_problem": false
}

retryable: true means the same call can succeed later. auth_problem: true means the key has to be fixed first.

10

Troubleshooting

The server does not start on Windows

Some clients cannot launch npx directly on Windows because it is a .cmd script. Wrap the command in cmd /c:

claude_desktop_config.jsonjson
{
  "mcpServers": {
    "erza": {
      "command": "cmd",
      "args": [
        "/c",
        "npx",
        "-y",
        "@erza-ai/erza-mcp"
      ],
      "env": {
        "ERZA_API_KEY": "ez_live_your_api_key_here"
      }
    }
  }
}
Every tool returns unauthorized

The key is wrong or has been revoked. Create a new key in Settings → API Keys, update ERZA_API_KEY (or the X-API-Key header) and restart the client.

The Erza tools do not show up

Check that the config file is valid JSON (no trailing commas) and that you fully restarted the client. Running npx -y @erza-ai/erza-mcp in a terminal shows any startup error; when it works, it waits silently for input.

Reading Claude Desktop logs

Claude Desktop writes one log file per server. The Erza server logs to stderr, so its errors end up there:

bash
# macOS
tail -f ~/Library/Logs/Claude/mcp-server-erza.log

# Windows (PowerShell)
Get-Content "$env:APPDATA\Claude\logs\mcp-server-erza.log" -Wait
Unsupported platform or architecture

The package ships binaries for macOS, Linux and Windows on x64 and arm64 only. On anything else, use the hosted endpoint.

A generation looks stuck

Generation keeps running on Erza after the tool returns. erza_generation_wait answers with the current state after max_wait_seconds; call it again with the same generation_id. It is safe to repeat, also after a reconnect.

Behind a proxy or firewall

The local server needs outbound HTTPS to api.erza.ai, plus a WebSocket (WSS) connection to the same host to start generations. The hosted setup only needs HTTPS to mcp.erza.ai.

11

Security

The server acts with your account's permissions and nothing more. Billing, roles and rate limits are enforced by the Erza API.

  • Treat the key like a password

    Anyone with the key can read, write and spend credits as you. Keep it out of screenshots, issues and chat logs.

  • Keep keys out of git

    Project files such as .cursor/mcp.json are easy to commit. In shared repositories, use global config, VS Code inputs or environment variables.

  • One key per device

    Create a separate key for each machine or client, so you can revoke one without breaking the others.

  • Review destructive calls

    erza_article_delete and erza_scheduler_cancel carry destructiveHint: true. Keep per-call approval on for them in your client.

12

Update & uninstall

npx resolves the local package. The hosted endpoint always runs the current release.

Get the latest release

npx caches packages. Add @latest to the args to always pull the newest version.

bash
npx -y @erza-ai/erza-mcp@latest

Pin a version

Use an exact version in the args when a team needs the same setup everywhere.

bash
npx -y @erza-ai/[email protected]

Uninstall

Remove the erza entry from your client config (or run this in Claude Code), then revoke the key.

bash
claude mcp remove erza

Ready to connect Erza?

Create an API key, paste one config block, and start writing from the assistant you already use.