Skip to main content
Glama
README.md
# Balzac MCP Server

[![npm version](https://img.shields.io/npm/v/balzac-mcp.svg)](https://www.npmjs.com/package/balzac-mcp)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)

**MCP server for the Balzac AI content platform** -- give AI agents native access to keyword research, article writing, and CMS publishing.

The Balzac MCP server implements the [Model Context Protocol](https://modelcontextprotocol.io) so that AI agents like Claude Desktop, OpenClaw, Claude Code, and any MCP-compatible client can manage your entire content pipeline through structured tool calls.

Not sure whether your site lets AI crawlers in? The free [AI crawler checker](https://hirebalzac.ai/free-seo-tools/ai-crawler-checker/) and the other [free SEO tools](https://hirebalzac.ai/free-seo-tools/) need no signup.

---

## Remote server (Claude, ChatGPT, and other connectors)

Balzac is also available as a hosted MCP server, with nothing to install:

```
https://mcp.hirebalzac.ai
```

- **Claude** (claude.ai, Desktop, mobile): **Settings > Connectors > Add custom connector**, paste the URL, then sign in to Balzac and allow access.
- **ChatGPT**: turn on developer mode under **Settings > Apps & Connectors > Advanced settings**, create a connector with the URL and OAuth authentication, then sign in to Balzac.
- **Claude Code**: `claude mcp add --transport http balzac https://mcp.hirebalzac.ai`, then run `/mcp` to sign in.

Clients that can't do OAuth can send an API key instead, as an `Authorization: Bearer bz_...` header. You can disconnect apps at any time from your Balzac profile page.

A connected app acts with the role of the person who approved it. Members don't get the admin-only tools (see [Roles](#roles)).

Content created through the remote connector never gets AI-generated images. Workspaces it creates start with `ai_images: false`, so the setup that follows `create_workspace` picks stock photos or title covers on a gradient of the brand color. The articles it writes (`create_briefing`, `accept_suggestion`), rewrites or gives a new cover keep AI out of all their covers, even in a workspace that allows AI images. Without AI images, a title cover is the article title on a gradient of the brand color, any other cover is a stock photo, and a first cover with no matching stock photo gets the title gradient instead.

The tools follow the same rule: they offer no AI picture style and no `ai` mode, and `title_based_featured_image` and `ai_images` can only be turned off. `update_settings` with `ai_images: false` keeps every cover of a workspace free of AI images, including articles written in the Balzac app or by autopilot; turning `ai_images` back on is done in the Balzac app (**Settings > Images**), and the API answers `403 forbidden` to a connector that tries. Turning `auto_accept_suggestions` on in a workspace whose `ai_images` is `true` also returns `403`, unless the same call sends `ai_images: false`. `regenerate_article_picture` has two modes: `title` or `stock` (a stock photo, which never falls back to AI: when no photo matches, the tool returns `422 no_stock_photo` and nothing is counted, so try again with search words in `additional_instructions`, or use `title`).

The guarantee covers OAuth sign-ins, which is how Claude and ChatGPT connect. With a `bz_` API key, the remote server's tools still never ask for AI images, but the covers of new articles follow the workspace's `ai_images` setting.

The local server below offers the same tools, plus AI picture styles and the `ai` cover mode, using an API key.

---

## Registry listing

This repository includes a `server.json` (and `mcpName` in `package.json`: `io.github.hirebalzac/mcp`) prepared for the [official MCP Registry](https://github.com/modelcontextprotocol/registry). Registry listing is not live until it has been published; check the registry for current status.

Balzac is an AI SEO agent that researches keywords, then writes and publishes blog articles. The free tier includes 3 articles; paid plans start at $79/month.

The local (npm, stdio) server reads `BALZAC_API_KEY` (required) and `BALZAC_API_URL` (optional). Never commit your key.

---

## Quick Start

### 1. Get your API key

Log in to [Balzac](https://app.hirebalzac.ai), go to **Settings > API Keys**, and generate a key.

### 2. Configure your MCP client

Add to your MCP configuration (Claude Desktop, OpenClaw, or any MCP-compatible host):

```json
{
  "mcpServers": {
    "balzac": {
      "command": "npx",
      "args": ["-y", "balzac-mcp"],
      "env": {
        "BALZAC_API_KEY": "bz_your_api_key_here"
      }
    }
  }
}
```

For **Claude Desktop**, this file lives at `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows).

### 3. Start using it

Once configured, your AI agent can directly call Balzac tools:

> "Research keywords for my site and write an SEO article about the best opportunity"
>
> "Write 3 articles about our top keywords and publish them as drafts to WordPress"
>
> "Rewrite my latest article with a more professional tone"

---

## Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `BALZAC_API_KEY` | Yes | Your Balzac API key (starts with `bz_`) |
| `BALZAC_API_URL` | No | API base URL (default: `https://api.hirebalzac.ai/v1`) |

The remote server (`npm run start:http`, deployed from the `Dockerfile`) takes its credentials from each request instead of `BALZAC_API_KEY`, and reads:

| Variable | Description |
|----------|-------------|
| `MCP_PUBLIC_URL` | Public URL of the server (`https://mcp.hirebalzac.ai` in production) |
| `BALZAC_AUTH_URL` | OAuth authorization server (default: `https://app.hirebalzac.ai`) |
| `BALZAC_API_URL` | API base URL (default: `https://api.hirebalzac.ai/v1`) |
| `PORT` | Port to listen on (default: `3001`) |

---

## Available Tools

### Account

| Tool | Description |
|------|-------------|
| `get_account` | Account, available credits, and whether the credentials act as an admin |

### Workspaces

| Tool | Description |
|------|-------------|
| `list_workspaces` | List all workspaces (filter by status: new, running, ready, imported, not_imported) |
| `get_workspace` | Get workspace details |
| `create_workspace` | Create a workspace from a domain |
| `update_workspace` | Update workspace settings |
| `delete_workspace` | Delete a workspace (admins only) |

### Keywords

| Tool | Description |
|------|-------------|
| `list_keywords` | List keywords (filter by status) |
| `get_keyword` | Get keyword details (volume, competition, intent, difficulty, GSC metrics) |
| `create_keyword` | Add a keyword |
| `enable_keyword` | Enable a keyword |
| `disable_keyword` | Disable a keyword |
| `delete_keyword` | Delete a keyword |
| `generate_keywords` | Generate new keywords with AI (async) |

### Suggestions

| Tool | Description |
|------|-------------|
| `list_suggestions` | List content suggestions |
| `get_suggestion` | Get suggestion details |
| `generate_suggestions` | Generate 10 new suggestions (1 credit) |
| `accept_suggestion` | Accept and start writing (5 credits) |
| `reject_suggestion` | Reject a suggestion |

### Briefings

| Tool | Description |
|------|-------------|
| `list_briefings` | List briefings |
| `get_briefing` | Get briefing details |
| `create_briefing` | Create a briefing and start writing (5 credits) |

### Articles

| Tool | Description |
|------|-------------|
| `list_articles` | List articles (filter by status, published), with each one's `live_url`, `rewrites_left` and `new_covers_left` |
| `get_article` | Get article details and content, `live_url`, publications, and the free `rewrites_left` and `new_covers_left` |
| `update_article` | Update article metadata |
| `delete_article` | Delete an article |
| `rewrite_article` | Rewrite article content (free, 2 per article) |
| `regenerate_article_picture` | Generate a new cover (free, 2 per article): title, stock photo or, on the local server, an AI style |
| `publish_article` | Publish to an integration (the live URL shows up later in `get_article`) |
| `schedule_article` | Schedule future publication |
| `export_article` | Export as HTML, Markdown, or XML |

`rewrite_article`, `publish_article` and `schedule_article` return the article without `html_content`, `published_html` and `schema_json_ld`: `get_article` has them. When the article is already on that integration, `publish_article` creates no new publication and passes on the API's message, which says when nothing was sent because the integration can't take updates (GoHighLevel, or a webhook with `webhook_updates` off).

### Competitors

| Tool | Description |
|------|-------------|
| `list_competitors` | List competitor domains |
| `create_competitor` | Add a competitor |
| `delete_competitor` | Remove a competitor |

### Links

| Tool | Description |
|------|-------------|
| `list_links` | List reference links |
| `create_link` | Add a reference link |
| `delete_link` | Remove a link |

### Settings

| Tool | Description |
|------|-------------|
| `get_settings` | Get workspace settings, including `ai_images` and `cover_mode` |
| `update_settings` | Update workspace settings, including `ai_images` (on the remote server, only `false`) |

### Tones of Voice

| Tool | Description |
|------|-------------|
| `list_tones` | List available tones |
| `get_tone` | Get tone details |

### Integrations

| Tool | Description |
|------|-------------|
| `list_integrations` | List publishing integrations |
| `get_integration` | Get integration details (credentials are never returned) |
| `create_integration` | Create an integration (WordPress, Webflow, Wix, GoHighLevel, Webhook), admins only |
| `update_integration` | Update integration settings, admins only |
| `delete_integration` | Delete an integration, admins only |
| `reconnect_integration` | Re-test integration connection, admins only |

When `update_integration` moves `wordpress_url` to another site, send `wordpress_application_password` in the same call; when it changes `webhook_url` on an integration with a bearer token, send `webhook_bearer_token`. Otherwise the update fails with `422 validation_failed`.

For webhooks, `webhook_updates` (on `create_integration` and `update_integration`) says whether the endpoint gets an `article.updated` call when an article already published there changes. New webhooks have it on; send `false` for an endpoint that creates a post on every call. Webhooks connected before updates existed have it off: turn it on once the endpoint updates the post it created. While it is off, `publish_article` on an article already there sends nothing and says so.

---

## Credit Costs

| Action | Credits |
|--------|---------|
| Writing an article (accept suggestion or create briefing) | 5 |
| Generating 10 new suggestions | 1 |

If your account doesn't have enough credits, the tool returns an error with the required and available credit counts. `get_account` shows the credits left.

Rewriting an article and generating a new cover are free. Each article includes 2 rewrites and 2 new covers; one counts when it finishes, and `get_article` shows what is left (`rewrites_left`, `new_covers_left`). Starting another while one runs returns `409 conflict`, and once an article has used its 2 the tool returns `422 free_limit_reached`.

---

## Roles

Only admins can manage integrations (`create_integration`, `update_integration`, `delete_integration`, `reconnect_integration`) and delete workspaces (`delete_workspace`). Members get `403 forbidden` there, and can still list integrations and publish to them.

API keys count as admin, so the local server keeps every tool. On the remote server, an app connected by a member doesn't list the admin-only tools at all. Apps cache the tool list, so after a role change (or for a connection made before this update), reconnect the app to refresh it: until then a member calling an admin-only tool gets a "Tool ... not found" error instead of the 403 message, and a newly promoted admin doesn't see those tools yet.

---

## Errors

Tool errors start with the HTTP status and the API's error type, then the message, for example:

```
[422 free_limit_reached] You've used the 2 free rewrites for this article.
[422 plan_limit_reached] Your Columnist plan includes 1 website. Upgrade your plan to add another one.
[403 forbidden] Only company admins can do this. Ask an admin of your Balzac account.
[422 no_stock_photo] No stock photo matches this article. Send a few search words in additional_instructions (for example "laptop on a desk"), or use picture_mode: title.
```

See the [API documentation](https://developer.hirebalzac.ai) for every error type.

---

## See Also

- [Balzac CLI](https://github.com/hirebalzac/cli) -- Command-line interface
- [API Documentation](https://developer.hirebalzac.ai) -- Full REST API reference

---

## License

MIT

TDQS

B3.3/5.0

Scored across 45 tools

Disambiguation4/5

Most tools have distinct purposes with clear boundaries, such as separate CRUD operations for different resources like keywords, articles, and integrations. However, some overlap exists between 'create_briefing' and 'accept_suggestion' as both initiate article writing, which could cause mild confusion for an agent.

Naming Consistency5/5

Tool names follow a highly consistent verb_noun pattern throughout, such as 'create_workspace', 'list_articles', 'update_settings', and 'delete_keyword'. This predictability makes it easy for agents to understand and navigate the toolset.

Tool Count2/5

With 45 tools, the count is excessive for the server's purpose of content creation and management. This large number can overwhelm agents, making it difficult to efficiently select the right tool, and suggests the surface could be streamlined without losing functionality.

Completeness5/5

The toolset provides comprehensive coverage for the content creation domain, including full CRUD operations for workspaces, articles, keywords, integrations, and more. It supports lifecycle management from suggestion generation to publishing, with no obvious gaps that would hinder agent workflows.

Maintenance

ActivityMaintained
ResponsivenessNo issues