Cacoo Remote MCP Server

Cacoo Remote MCP Server

Enables managing Cacoo diagrams, folders, organizations, and account information through MCP tools over HTTP, with OAuth-based authentication, email allowlisting, and support for multiple Cacoo accounts.

Category
访问服务器

README

Cacoo Remote MCP Server

A remote MCP server for the Cacoo API, deployable to Cloudflare Workers, AWS Lambda, Google Cloud Run or Azure Container Apps.

Unlike a local stdio MCP server, this runs as a hosted HTTP endpoint: you authenticate once in the browser with OAuth, and your Cacoo API key never leaves the server.

日本語版はこちら

Features

  • 14 MCP tools covering diagrams, folders, organizations and account information
  • OAuth 2.1 with PKCE — clients authenticate in the browser; no API key on the client
  • Email allowlist — application-level authorization on top of the upstream IdP
  • Multiple Cacoo accounts — route per call, with a per-account read-only guard
  • Four deployment targets sharing the same tool implementations

Choosing a deployment

Cloudflare AWS Google Cloud Azure
Runtime Workers (edge) Lambda + API Gateway Cloud Run Container Apps
MCP session Durable Objects Stateless Stateless Stateless
OAuth authorization server @cloudflare/workers-oauth-provider src/oauth src/oauth src/oauth
Upstream IdP Cloudflare Access Amazon Cognito Google account Microsoft Entra ID
State storage Workers KV DynamoDB (TTL) Firestore (TTL) Cosmos DB (TTL)
Secrets Workers Secrets Secrets Manager Secret Manager Key Vault
IaC wrangler AWS SAM Terraform Bicep
Config file .dev.vars infra/aws/params.yaml infra/gcp/terraform.tfvars infra/azure/params.json

The tools and their behavior are identical on all of them. Every platform can use either Google or Microsoft Entra ID as its upstream IdP; the table shows the default.

Architecture

The same MCP server runs on four platforms. Each platform subgraph holds its own wiring — gateway, storage and upstream IdP — and the Node-based ones funnel into the shared src/oauth, which in turn uses src/core.

flowchart TB
    subgraph clients["MCP clients"]
        direction LR
        CC["Claude Code<br/><i>native HTTP transport</i>"]
        CD["Claude Desktop / Kiro / Cursor<br/><i>mcp-remote proxy</i>"]
    end

    subgraph cf["Cloudflare &nbsp;&nbsp; src/platforms/cloudflare"]
        direction TB
        CFW["Workers &nbsp;&nbsp; <i>OAuthProvider</i>"]
        CFA["Cloudflare Access<br/><i>or Google / Entra ID</i>"]
        CFKV["KV &nbsp;&nbsp; <i>OAUTH_KV</i>"]
        CFDO["Durable Object<br/><i>CacooMCP session</i>"]
        CFW -. "OIDC" .-> CFA
        CFW --- CFKV
        CFW --> CFDO
    end

    subgraph aws["AWS &nbsp;&nbsp; src/platforms/aws"]
        direction TB
        APIGW["API Gateway<br/><i>HTTP API + ACM + Route 53</i>"]
        LAMBDA["Lambda &nbsp;&nbsp; <i>nodejs22 / arm64</i>"]
        COG["Amazon Cognito"]
        DDB["DynamoDB &nbsp;&nbsp; <i>OAuth state</i>"]
        SM["Secrets Manager<br/><i>Cacoo API keys</i>"]
        APIGW --> LAMBDA
        LAMBDA -. "OIDC" .-> COG
        LAMBDA --- DDB
        LAMBDA --- SM
    end

    subgraph gcp["Google Cloud &nbsp;&nbsp; src/platforms/gcp"]
        direction TB
        RUN["Cloud Run &nbsp;&nbsp; <i>container</i>"]
        GID["Google account"]
        FS["Firestore &nbsp;&nbsp; <i>OAuth state</i>"]
        GSM["Secret Manager"]
        RUN -. "OIDC" .-> GID
        RUN --- FS
        RUN --- GSM
    end

    subgraph azure["Azure &nbsp;&nbsp; src/platforms/azure"]
        direction TB
        ACA["Container Apps &nbsp;&nbsp; <i>container</i>"]
        ENT["Entra ID"]
        COS["Cosmos DB &nbsp;&nbsp; <i>OAuth state</i>"]
        AKV["Key Vault"]
        ACA -. "OIDC" .-> ENT
        ACA --- COS
        ACA --- AKV
    end

    subgraph oauth["src/oauth &nbsp;&nbsp; shared by Node runtimes"]
        OP["provider.ts &nbsp;&nbsp; <i>OAuth authorization server</i>"]
        OS["store.ts &nbsp;&nbsp; <i>AuthStore interface</i>"]
        OP --- OS
    end

    subgraph shared["src/core &nbsp;&nbsp; every runtime"]
        CS["create-server.ts<br/><i>tool registration + email allowlist</i>"]
        TOOLS["tools/ &nbsp;&nbsp; <i>14 MCP tools</i>"]
        BC["cacoo-client.ts<br/><i>account routing + readOnly guard</i>"]
        CS --> TOOLS --> BC
    end

    CACOO["Cacoo API &nbsp;&nbsp; <i>/api/v1</i>"]

    clients == "Streamable HTTP + OAuth" ==> CFW
    clients == "Streamable HTTP + OAuth" ==> APIGW
    clients == "Streamable HTTP + OAuth" ==> RUN
    clients == "Streamable HTTP + OAuth" ==> ACA

    CFDO --> CS
    LAMBDA --> OP
    RUN --> OP
    ACA --> OP
    OP --> CS

    DDB -. "implements AuthStore" .-> OS
    FS -. "implements AuthStore" .-> OS
    COS -. "implements AuthStore" .-> OS

    BC == "per-account API key" ==> CACOO

Request flow

sequenceDiagram
    autonumber
    participant C as MCP client
    participant S as Worker / Lambda / Container
    participant I as Upstream IdP
    participant K as Cacoo

    C->>S: POST /mcp
    S-->>C: 401 + OAuth metadata
    C->>S: authorize
    S->>I: redirect to upstream OIDC
    I-->>S: callback with identity
    Note over S: email allowlist check<br/>reject -> access_denied tool only
    S-->>C: access token
    C->>S: tools/list, tools/call
    Note over S: resolve account -> pick API key<br/>readOnly guard blocks writes
    S->>K: Cacoo REST API v1
    K-->>S: JSON / PNG / XML
    S-->>C: MCP result

Authorization happens in two layers. The upstream IdP decides who may sign in, and the email allowlist decides who gets tools: a user outside the allowlist receives a server exposing only access_denied. The readOnly flag on an account rejects every non-GET request in the API client layer, so it cannot be bypassed by an individual tool.

Directory layout

Three layers, by how widely each one can be reused:

src/
  core/                    Every runtime. Depends only on the MCP SDK and zod
    cacoo-client.ts        Cacoo API client (account routing + readOnly guard)
    tools/                 14 MCP tools
    create-server.ts       MCP server assembly and authorization
  oauth/                   Node runtimes. OAuth authorization server (Express)
    provider.ts            OAuthServerProvider implementation
    store.ts               AuthStore interface — the persistence port
    upstream.ts            Upstream OIDC client
    consent.ts             Consent screen
    app.ts                 Express app exposing /authorize, /token, /mcp, ...
  platforms/
    cloudflare/            Workers wiring (uses its own Workers OAuth provider)
    aws/                   Lambda wiring + DynamoDB / Secrets Manager adapters
    gcp/                   Cloud Run wiring + Firestore / Secret Manager adapters
    azure/                 Container Apps wiring + Cosmos DB / Key Vault adapters
infra/
  aws/                     SAM template and parameters
  gcp/                     Terraform configuration
  azure/                   Bicep template and parameters

src/platforms/<name> is the only place a cloud SDK appears. Adding another Node-hosted platform means implementing AuthStore, a secret lookup, and an entry point that hands the Express app to the runtime.

Configuration

Accounts are configured as a single JSON string, CACOO_ACCOUNTS_CONFIG. See Cacoo API keys and account configuration for how to issue a key and find your organizationKey.

{
  "accounts": [
    { "name": "main", "apiKey": "xxx", "organizationKey": "your-org-key" },
    { "name": "shared", "apiKey": "yyy", "readOnly": true }
  ],
  "defaultAccount": "main"
}
Field Meaning
name Name used by the account argument on every tool
apiKey Cacoo API key. Generate one at https://cacoo.com/profile/api
organizationKey Default organization for diagram and folder tools. Required on non-legacy plans; tools can override it per call
readOnly When true, every non-GET call is rejected
baseUrl Defaults to https://cacoo.com

Connecting from MCP Clients

Claude Code

claude mcp add --transport http cacoo https://<your-domain>/mcp -s user

Claude Desktop / Kiro / Cursor

{
  "mcpServers": {
    "cacoo": {
      "command": "npx",
      "args": ["mcp-remote", "https://<your-domain>/mcp"]
    }
  }
}

A browser opens on first connection and asks you to authenticate.

Claude Desktop (.mcpb bundle)

Instead of hand-editing the JSON above, you can double-click a .mcpb (MCP Bundle) to install it. It is generated during deploy and written to dist/.

npm run mcpb:pack   # generate on its own
npm run aws:deploy  # generated as part of the deploy

The endpoint URL is a user_config field, and the domain you deployed to is baked in as its default, resolved from --host, MCP_HOSTNAME, ApiDomainName in infra/aws/params.yaml, or MCP_HOSTNAME in .dev.vars, in that order.

The bundle does not contain the server itself. MCPB is a local-execution format, so it ships mcp-remote as a stdio proxy that connects to your deployed server. Claude Code does not use this bundle — it stays on claude mcp add --transport http.

Available Tools

Diagrams

Tool Description
list_diagrams List diagrams with filtering, sorting and pagination
get_diagram Details of one diagram, including sheets and comments
create_diagram Create a new empty diagram
copy_diagram Copy an existing diagram
move_diagram Move a diagram to another folder
delete_diagram Delete a diagram
get_diagram_image PNG rendering of a diagram or one sheet
get_diagram_contents Structured contents (shapes, text, lines) as XML

Workspace

Tool Description
list_accounts Configured accounts, the default, and which allow writes
list_folders Folders in the account
list_organizations Organizations, including the key used as organizationKey
get_account Profile of the authenticated account
get_license License/plan details
get_user Public profile of a user by name

Security

  • Authentication: OAuth 2.1 with PKCE (S256) against an upstream IdP
  • Authorization: ALLOWED_EMAILS provides an application-level email allowlist. Leaving it empty disables the allowlist, so anyone who can sign in through the upstream IdP gets every tool
  • API key protection: Cacoo API keys stay on the server and are never sent to clients
  • Client consent: Dynamic Client Registration is open to anyone, so authorization is gated behind a consent screen naming the client and its redirect target, with CSRF protection. Approvals are keyed on client_id + redirect_uri
  • Write guard: accounts marked readOnly: true reject every non-GET call. The check lives in src/core/cacoo-client.ts, so it does not depend on individual tools
  • Dependency cooldown: .npmrc sets min-release-age=3, so dependency resolution only considers package versions that have been public for at least three days

Local Development

npm install
npm run type-check   # all four platforms
npm test             # 108 assertions
Test Covers
npm run test:cacoo-client URL building, organizationKey resolution, readOnly guard, error formatting, 4MB image cap
npm run test:tools All 14 tools register; allowlist gating
npm run test:oauth DCR, PKCE, single-use tokens, scopes, revocation
npm run test:oauth-consent HTML escaping, signed cookies, CSRF, approval gate
npm run test:oauth-upstream Endpoint resolution for Cognito / Google / Entra ID

IaC can be validated without cloud credentials:

npm run aws:validate     # sam validate --lint
npm run gcp:validate     # terraform validate
npm run azure:validate   # az bicep build

Credits

The tool definitions are ported from cacoo-mcp-server (local stdio). The remote server architecture is shared with backlog-remote-mcp-server.

License

MIT

推荐服务器

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 模型以安全和受控的方式获取实时的网络信息。

官方
精选