frappe-cloud-mcp

frappe-cloud-mcp

An MCP server for the Frappe Cloud control plane that lets agents manage sites, bench groups, servers, backups, deploys, logs, analytics, and billing. It provides read, write, and optional destructive tools for operating Frappe Cloud hosting infrastructure.

Category
访问服务器

README

frappe-cloud-mcp

An MCP server for the Frappe Cloud control plane — the press API behind frappecloud.com. It gives an agent an operator's view of your hosting account: sites, bench groups, servers, backups, deploys, logs, analytics and billing.

This is not another ERPNext data connector. Existing Frappe MCP servers talk to the DocTypes inside a site; this one talks to the layer that runs the site. Ask it why a deploy failed, what is hammering your database, or what next month's invoice looks like.

Install

Requires Python 3.11+.

git clone <this repo> && cd frappe-cloud-mcp
uv sync

Credentials

In the Frappe Cloud dashboard, go to Settings > Developer and press Create New API Key.

Despite the button's name it gives you two values — an API key and an API secret — and the secret is shown only once, so copy both before closing the dialog.

export FRAPPE_CLOUD_API_KEY=...
export FRAPPE_CLOUD_API_SECRET=...

Both halves are required. Frappe reads the header as token <api-key>:<api-secret> and splits it on the colon; given only one value it discards the credential silently and serves the request as an anonymous Guest, so a missing secret surfaces as Not Permitted rather than as a login error. This server refuses to start on a half credential instead of letting you hit that.

If you have the pair as a single key:secret string, FRAPPE_CLOUD_TOKEN takes it whole.

Register with Claude Code

From this repo (project scope)

A .mcp.json ships in the repo root, so opening this project in Claude Code offers the server automatically. It reads credentials from your environment rather than storing them, so the file is safe to commit:

{
  "mcpServers": {
    "frappe-cloud": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--directory", "${CLAUDE_PROJECT_DIR:-.}", "frappe-cloud-mcp"],
      "env": {
        "FRAPPE_CLOUD_API_KEY": "${FRAPPE_CLOUD_API_KEY}",
        "FRAPPE_CLOUD_API_SECRET": "${FRAPPE_CLOUD_API_SECRET}",
        "FRAPPE_CLOUD_URL": "${FRAPPE_CLOUD_URL:-https://frappecloud.com}",
        "FRAPPE_CLOUD_TEAM": "${FRAPPE_CLOUD_TEAM:-}",
        "FRAPPE_CLOUD_READ_ONLY": "${FRAPPE_CLOUD_READ_ONLY:-0}",
        "FRAPPE_CLOUD_ALLOW_DESTRUCTIVE": "${FRAPPE_CLOUD_ALLOW_DESTRUCTIVE:-0}"
      }
    }
  }
}

Claude Code asks for approval the first time it sees a project-scoped server. Everything except the key and secret has a :-default, so exporting those two is enough to start.

From anywhere (user scope)

To use it across all your projects, paste this into ~/.claude.json under mcpServers — with a real absolute path, since ${CLAUDE_PROJECT_DIR} means nothing outside this repo:

{
  "mcpServers": {
    "frappe-cloud": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--directory", "/home/you/projects/frappe-cloud-mcp", "frappe-cloud-mcp"],
      "env": {
        "FRAPPE_CLOUD_API_KEY": "fc_key_...",
        "FRAPPE_CLOUD_API_SECRET": "fc_secret_..."
      }
    }
  }
}

The same block works in Claude Desktop's claude_desktop_config.json and in any other MCP client that takes an mcpServers object. If uv is not on your PATH, use its absolute path (which uv) as command.

Or add it from the CLI, without editing files:

claude mcp add frappe-cloud \
  -e FRAPPE_CLOUD_API_KEY=... \
  -e FRAPPE_CLOUD_API_SECRET=... \
  -- uv run --directory /path/to/frappe-cloud-mcp frappe-cloud-mcp

Verify with /mcp in Claude Code: the server should show connected. Bad credentials show failed with the HTTP status from Frappe Cloud.

Read-only or destructive

Both flags are ordinary env vars, so set them in the env block of whichever config you used:

"env": {
  "FRAPPE_CLOUD_API_KEY": "...",
  "FRAPPE_CLOUD_API_SECRET": "...",
  "FRAPPE_CLOUD_READ_ONLY": "1"
}

A practical pattern is two entries — frappe-cloud read-only for everyday questions and frappe-cloud-admin with FRAPPE_CLOUD_ALLOW_DESTRUCTIVE=1 for sessions where you intend to change infrastructure.

Configuration

Variable Default Purpose
FRAPPE_CLOUD_API_KEY — required
FRAPPE_CLOUD_API_SECRET — required
FRAPPE_CLOUD_TOKEN — alternative to the pair above, as key:secret
FRAPPE_CLOUD_TEAM your default team sent as X-Press-Team; needed to target a child team
FRAPPE_CLOUD_URL https://frappecloud.com point at a self-hosted press instance
FRAPPE_CLOUD_READ_ONLY 0 expose read tools only
FRAPPE_CLOUD_ALLOW_DESTRUCTIVE 0 unlock the destructive tier
FRAPPE_CLOUD_TIMEOUT 60 request timeout in seconds

Safety model

Tools fall into three tiers, and a tool that is not enabled is never registered — a read-only server truthfully advertises no mutating tools rather than offering them and refusing.

Tier Default Examples
read on list_sites, site_log, bench_candidate, mariadb_processlist, upcoming_invoice
write on (off under READ_ONLY) create_site_backup, clear_site_cache, install_app, add_site_domain
destructive off unless ALLOW_DESTRUCTIVE archive_site, deploy_bench, change_site_plan, reboot_server, press_call

FRAPPE_CLOUD_READ_ONLY=1 wins over FRAPPE_CLOUD_ALLOW_DESTRUCTIVE=1.

Run it read-only or default for day-to-day work; turn on the destructive tier only for a session where you actually intend to change infrastructure.

Tools

86 tools by default; 115 with the destructive tier on.

Sites — list/get, installed and available apps, config, domains, backups and download links, logs, agent jobs, activity, update checks, plans. Writes: backup, clear cache, install app, add domain, update config, activate, auto-update toggles. Gated: create, update, migrate, deactivate, archive, reinstall, restore, uninstall app, remove domain, change plan, version upgrade, move server, admin login link.

Bench groups — list/get, apps, config, dependencies, deployed versions, deploy information and status, recent deploys, deploy candidates (with build output), jobs, logs, processes, branches, regions. Writes: fetch latest app update, restart. Gated: deploy, update, rebuild, add/remove app, change branch, update config, archive.

Servers — list/get, overview, usage, bench groups, plans, jobs, Ansible plays, reclaimable disk. Gated: reboot, change plan, archive.

Observability — site analytics, daily usage, request count and duration by path, background job duration, request logs, server CPU/memory, MariaDB process list and slow queries, deadlock report, structured log browsing, notifications.

Billing (read-only throughout) — summary, upcoming invoice, current amount, unpaid and past invoices, balances, forecast, invoice line items, subscriptions.

Generic — press_methods searches a bundled catalogue of 278 whitelisted press endpoints; press_list, press_get and press_search_link read arbitrary press documents. Gated: press_call, press_run_doc_method and press_set_value reach anything without a named tool.

Refreshing the method catalogue

press_methods is backed by src/frappe_cloud_mcp/catalog.json, generated from the frappe/press source. Regenerate it when press adds endpoints:

uv run python scripts/refresh_catalog.py --ref master

Development

uv run pytest          # 44 tests, no network
uv run ruff check src tests scripts
uv run mcp dev src/frappe_cloud_mcp/__main__.py

Notes on the press API

Built against the frappe/press source rather than the published docs, which are stale and currently returning 500s. Behaviour worth knowing:

  • Responses wrap the return value in {"message": ...}; errors arrive as 4xx/5xx with _server_messages, a JSON string holding a list of JSON strings.
  • Reads go out as GET with non-scalar arguments JSON-encoded per parameter; writes go as POST with a JSON body so argument types survive.
  • press.api.site.get answers a custom domain with a redirect to the real site name; the client follows it.
  • The generic press.api.client.* layer is limited server-side to an allowlist of ~55 doctypes and to documents owned by the active team.

Out of scope

OAuth/browser login, marketplace app publishing, partner and SaaS onboarding flows, data-plane access to the sites themselves, and remote HTTP transport (stdio only).

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选