# AI connector (MCP)

The connector speaks the Model Context Protocol and signs you in with OAuth. You choose one workspace or all of them, and read-only or read-and-manage access. It then does what your role allows — nothing more — through the same API, with the same limits, audit rows and money checks. Its tools cover projects and deploys, repos, environment variables, databases, storage, functions, vector collections, memory, agents, domains and DNS, Shield and CDN settings, security checks, payments, sign-in, mail, usage and these docs, and your team: new workspaces, invitations, roles, and links to upgrade the plan or add funds.

It is tested with Claude. ChatGPT and other MCP clients speak the same protocol and the steps below connect them, but they are not verified yet.

## In plain words

Lets an AI assistant such as Claude work in your Harakumo account when you ask in everyday words, with only the rights your role has.

For example: You ask your assistant why your site did not update, and it reads the error and puts the fixed version live.

## Connect

| Client | How |
| --- | --- |
| Claude (web and desktop) | Settings → Connectors → Add custom connector → paste `https://harakumo.com/mcp` → sign in and choose the workspace and access. |
| Claude Code | `claude mcp add --transport http harakumo https://harakumo.com/mcp` |
| ChatGPT | Turn on developer mode, add an app with the URL `https://harakumo.com/mcp` and OAuth sign-in. Step by step in Connect ChatGPT below. |
| Other clients (Cursor …) | `{ "mcpServers": { "harakumo": { "url": "https://harakumo.com/mcp" } } }` |
| With an API key instead | Any client that can send a header, e.g. Claude Code: `claude mcp add --transport http harakumo https://harakumo.com/mcp --header "Authorization: Bearer hk_live_…"`. See Connect with an API key below. |

## Connect with an API key

A headless agent, or an AI tool you would rather not sign in to, can send an API key as a header instead of signing in. In Claude Code: `claude mcp add --transport http harakumo https://harakumo.com/mcp --header "Authorization: Bearer hk_live_…"`. In a client set up with JSON that takes headers (Cursor and others): `{ "mcpServers": { "harakumo": { "url": "https://harakumo.com/mcp", "headers": { "Authorization": "Bearer hk_live_…" } } } }`.

- One key covers one workspace. A full key gets the developer tools, a read key only the read tools, and a key limited to one project works on that project only. Make keys in Settings → API access.
- A key belongs to the workspace, not to you, so it never manages members, keys or billing and cannot create workspaces. For those, connect by signing in instead.
- Never paste a key into a chat message. It would stay in the chat history, and the connector does not read keys from messages anyway: it only uses the one in its settings.

## Connect ChatGPT

ChatGPT's search and deep research use two read-only tools, `search` and `fetch`. `search` looks through these docs and your workspace — projects, deployments, databases, functions, storage buckets and domains — and returns results with ids like `project:12`, `deployment:340`, `domain:example.com` or `doc:deployments`. `fetch` reads one in full: a deployment comes with its build log, a docs topic as markdown. Both see only what your role and the connection allow, like every other read tool.

1. In ChatGPT on the web, open Settings and turn on Developer mode. It is available on Plus, Pro, Business, Enterprise and Education plans; ChatGPT moves the switch between releases (it has lived under Apps & Connectors and under Security).
2. Add an app (a connector): name it Harakumo, set the server URL to `https://harakumo.com/mcp` and choose OAuth for authentication.
3. Sign in to Harakumo when ChatGPT asks, then choose the workspace and Read only or Read and manage.
4. In a chat, pick Developer mode from the + menu and switch Harakumo on. Name it in your request, e.g. "Use Harakumo to show my failed deploys".

> Tools that change something ask ChatGPT to confirm first. For a ChatGPT that can only look, pick Read only on the Harakumo sign-in screen.

## Access

- Read only: the assistant can look but not change anything. Read and manage: changes are allowed; tools that change or delete things are marked so the assistant asks you first.
- A connector acts with your own role, so an admin's connector also gets admin tools such as API keys, members and the audit log; an API key gets developer tools only. Money never leaves through a connector: withdrawals, refunds and payout setup are refused by design.
- A connection stays signed in and renews itself (the access token lasts 90 days and refreshes; unused for 180 days, it expires). Dashboard → Connectors lists every connection and cuts any of them off immediately.
- One workspace or all: the sign-in screen offers both, even if you belong to just one workspace today. All of them covers every workspace you belong to on each request, including ones you create or join later, and only that choice, with Read and manage, lets the assistant create workspaces.
- Sign-in secrets stay out of the chat. When the assistant adds sign-in to a project (`enable_auth` or `setup_app_backend`), the pool's client secret and JWT secret are stored as the project's environment variables `HARAKUMO_AUTH_CLIENT_SECRET` and `HARAKUMO_AUTH_JWT_SECRET`, and the assistant gets only their names. `list_env_vars` lists names and lengths, never values.
- An agent's app-events signing secret stays out of the chat too: when the assistant turns an agent's app events on or gives them a new secret (`update_agent` with `events`), the secret is stored as the project's environment variable `HARAKUMO_AGENT_<id>_EVENTS_SECRET`, for the app's server to sign events with, and the assistant gets only its name.

## Workspaces, team and plan from a chat

- `create_workspace` — a new workspace you own, on Hobby, with the same limits as the dashboard (how many you may own, a few a day). It needs a connection granted all of your workspaces; then `switch_organization` moves the connection into it. On a one-workspace connection, reconnect and choose all of them on the sign-in screen (it is offered even when you belong to only one).
- `invite_member` — invites someone by email as admin, developer or viewer, never owner. It sends an email, so the assistant confirms the address and role with you first. `list_invitations` and `revoke_invitation` manage the pending ones. Owners and admins only.
- `update_member_role` and `remove_member` — change a member's role to admin, developer or viewer, or remove them. Never your own role or membership, never an owner, and never to owner (transferring ownership stays in the dashboard). Removing someone lists the API keys they made, which keep working until revoked.
- `create_upgrade_link` and `create_add_funds_link` — the workspace owner gets a checkout page to open and pay; nothing is charged and no plan changes until you pay there. A plan that is already paid for is changed on the Billing page, because that charges the card on file at once.

## What stays in the dashboard

The connector has no tools for these, and `get_dashboard_link` gives the assistant the exact page to send you to: changing your password or email, two-factor sign-in, signed-in sessions, deleting your account or a workspace, downloading a copy of your personal data, transferring ownership, leaving a workspace, payment cards, auto-reload and requiring two-factor sign-in of every member (the assistant can read that rule with `get_workspace_security`). A connector is a long-lived token held by another app, and each of these could lock you out, carry off your sign-in history or decide what your card is charged.

Asked to make a billing change that charges the card on file or decides what it is charged, the API answers an owner's connector 403 `dashboard_only` (anyone else's is told their role does not allow it); asked to pay for a domain with the card, any connector gets `card_requires_owner`. Both carry `dashboard_url`, the page to send you to, and nothing is changed. Every such call and its answer is listed in Billing → What needs the dashboard.

## Sending email from your own domain

Six tools let an assistant set up a sending domain end to end: it adds the domain, gives you the two nameservers and the steps for your provider (its existing records are copied first), checks until the switch is seen, and sets the project's From address once the domain is verified. See Mail → Send from your own domain.

- `add_mail_domain` — start (or start again); returns the nameservers, numbered steps, provider hints and the copied records.
- `check_mail_domain` — check now: whether the nameservers switched, then each record found, missing or wrong.
- `list_mail_domains` and `get_mail_domain` — status, steps and every project's current From address.
- `set_mail_from` — a project's From address and Reply-To.
- `remove_mail_domain` — stop sending from a domain.
- Also: `host_domain_dns` hosts a bought domain's DNS here so every record is added for you, and `send_email` takes `from` and `replyTo`.

## New tools not showing?

Assistants remember a connector's tool list from when it was attached. After Harakumo adds tools, disconnect and reconnect the connector, then start a new conversation. The docs themselves are always live through get_docs.

## Try asking

- "What needs my attention?" — one call to needs_attention, most urgent first.
- "Build a landing page for my bakery and put it online."
- "Why did the last deploy fail?"
- "How much of my plan and AI credit is left?"
- "Buy fruitshop.com and connect it to the store project."
- "Set up fruitshop.com as a sending domain on Harakumo and walk me through it."
- "Create a workspace called Fruitly Labs and invite ana@example.com as a developer."

## Reference

**SDK**

```js
// Nothing to install — the connector is the interface.
```

**CLI**

```bash
claude mcp add --transport http harakumo https://harakumo.com/mcp
```

**REST**

```http
POST   /mcp                                        Authorization: Bearer hk_mcp_… or hk_live_…
GET    /.well-known/oauth-protected-resource/mcp   # discovery
GET    /api/mcp/connections                        # what is connected
DELETE /api/mcp/connections                        { "id": 1 }   # disconnect
```
