MCP Server

Let MCP-compatible AI assistants operate your Koolbase backend directly — and write code against it. Read projects, flip feature flags, update remote config, inspect code-push history, and let a coding agent read your collections, access rules, and SDK idioms so the code it generates is wired to your real backend.

What is it?

The Model Context Protocol (MCP) is an open standard that lets AI assistants connect to external tools and services. The Koolbase MCP server exposes your backend as a set of tools an assistant can call — so instead of clicking through the dashboard or writing CLI commands, you can ask your assistant to do it.

It ships inside the Koolbase CLI. If you have the CLI, you already have the MCP server — no separate install. It runs locally over stdio and talks to the same Koolbase API the dashboard and CLI use, so every operation is subject to the same authorization and limits.

Because MCP is an open standard, the server is not tied to any one assistant. Any MCP-capable client can drive it — Claude Desktop, Cursor, other editors and agents, or your own client that speaks the protocol over stdio. The guide below uses Claude Desktop as the worked example; the same server entry works anywhere, only the config location differs.

Requires Koolbase CLI v0.4.0 or later. Check with koolbase version; install or update via curl -fsSL https://get.koolbase.com/install.sh | sh.

Authentication & scopes

The MCP server authenticates with an organization API key (kb_live_…), provided via the KOOLBASE_API_KEY environment variable. The key is required: koolbase mcp serve deliberately refuses to fall back to your CLI login session, so a misconfigured client fails visibly at startup instead of silently acting as your logged-in user account.

Every key has a scope, and the scope is the hard ceiling on what any tool can do — enforced by the Koolbase API, not just the MCP layer:

readList and inspect resources. Cannot change anything.
writeEverything read can do, plus change flags and remote config.
adminEverything write can do, plus production-affecting operations.

For an assistant that only needs to look around, give it a read key. Grant write only when you want it changing flags or config. If a tool needs more scope than the key has, it tells you exactly which scope is required rather than failing opaquely.

Isolation. A key can only ever see and act on resources in its own organization. Requests for resources in another organization return “not found” — Koolbase never confirms a resource exists to a key that can’t access it.

Setup

First mint a key for the assistant — koolbase login then koolbase keys create --name claude --scope write (or --scope read for a look-but-don’t-touch assistant). The command prints the key once, along with a ready-to-paste MCP config.

Claude Desktop, one command: run koolbase mcp install --key kb_live_… — it writes the config entry for you (preserving any existing servers and backing up the old file), then fully quit and reopen Claude Desktop. Add --codepush-mutations to also enable the code-push publish/recall tools (admin key required). Skip to the confirmation step below.

Manual, or other MCP clients: point any client at the koolbase mcp serve command. Use the absolute path to the binary (which koolbase to find it) — MCP clients spawn the server with their own environment and don’t inherit your shell’s PATH. For Claude Desktop, add this to your MCP config:

{
"mcpServers": {
  "koolbase": {
    "command": "/usr/local/bin/koolbase",
    "args": ["mcp", "serve"],
    "env": {
      "KOOLBASE_API_KEY": "kb_live_your_key_here"
    }
  }
}
            }

Then restart your client fully — on macOS that means quitting with ⌘Q, not just closing the window; MCP configuration is only read at startup. The Koolbase tools become available, and you can ask your assistant something like “what projects do I have on Koolbase?” to confirm the connection.

Whatever the client, the server is the same three things: a command (absolute path to the koolbase binary), the args ["mcp", "serve"], and a KOOLBASE_API_KEY environment variable.

Available tools

The minimum key scope each tool requires is shown alongside it.

koolbase_whoamireadIdentity and scope the server is acting as.
koolbase_list_projectsreadProjects in your organization.
koolbase_get_projectreadA single project's details.
koolbase_list_environmentsreadA project's environments (production, staging, …).
koolbase_list_flagsreadFeature flags for an environment, with rollout and kill-switch state.
koolbase_set_flagwriteChange a flag's enabled state, rollout percentage, or kill switch.
koolbase_list_configsreadRemote-config entries for an environment, with their values and types.
koolbase_set_configwriteChange a remote-config value or description. Values are type-checked against the config\u2019s declared type (string, number, boolean, or json).
koolbase_list_patchesreadCode-push patch history: status, rollout, app version, and target build.
koolbase_describe_projectwriteA project's full shape for code generation: collections with access rules and unique constraints, buckets, function signatures, and environments.
koolbase_get_collectionwriteOne collection's rules and constraints by name — the drill-down for single-screen work.
koolbase_sdk_conventionsreadThe client SDK's idioms for one platform (flutter or react_native): initialization, auth, the query pattern, and the offline write contract.
koolbase_publish_patchadminPublish a draft code-push patch to real devices. Gated: only registered when the server runs with --enable-codepush-mutations.
koolbase_recall_patchadminRecall a live patch — the emergency brake. Gated behind the same flag.

koolbase_describe_project and koolbase_get_collection require a write key because they read the same project-export route the snapshot tooling uses. They never return secrets or function source.

Building with your agent

The schema tools exist so a coding agent can generate code that is correctly wired to your backend instead of guessing at it. koolbase_describe_project tells the agent what exists — every collection, its access rules as structured data, its unique constraints, your buckets and deployed functions. koolbase_sdk_conventions tells it how to call it — the real SDK surface for Flutter, React Native or the browser, so a generated query uses the methods that actually exist.

Access rules come back as data, one per verb. Each rule has a kind:

publicAnyone, signed in or not.
authenticatedAny signed-in user.
ownerOnly the record’s creator — the server stamps created_by on insert; clients can’t set or override it.
scopedRestricted by an explicit binding: the rule carries the record field (owner_field) and the caller property it must equal (caller_key). Reads filter on it; writes populate it.
conditionalAllowed when the rule’s declared conditions hold.
server_onlyFunctions and server-side code only — client SDK calls are refused.

Collections are schemaless. A collection is a governed container; records carry whatever fields your app writes. The description deliberately returns no invented field list — the only declared field names are the ones inside unique constraints, plus the system fields every record carries ($id, $createdAt, $updatedAt, $revision).

The intended flow: the agent calls koolbase_describe_project once to learn the project (or koolbase_get_collection for one screen’s worth), calls koolbase_sdk_conventions for the platform it’s generating, then writes code — real collection names, rule-respecting queries, the SDK’s actual call shapes.

This works for Flutter, React Native and the web alike: the two SDKs share the same semantics (the same access rules, offline write contract, and cache-then-refresh queries) but have different call shapes — koolbase_sdk_conventions returns the right dialect for whichever one you ask for (flutter or react_native), so a Flutter query builder never leaks into TypeScript and an options object never leaks into Dart.

Example

A conversation with an assistant connected to Koolbase might go:

You

Is the new checkout flag live in production?

Assistant

It’s enabled but only at a 10% rollout. Want me to take it to 100%?

You

Yes, roll it out fully.

Assistant

Done — new_checkout is now enabled at 100% in production.

Behind the scenes the assistant called koolbase_list_flags to read the state, then koolbase_set_flag to change it — each authorized against your key’s scope.

Or, with a coding agent:

You

Write a Flutter screen listing the signed-in user’s conversation_members records.

Assistant

This collection’s read rule is scoped — user_id must equal the caller’s id — so the query filters on the signed-in user, skips the query entirely when signed out, and handles the cache-then-refresh arrival the SDK’s queries use. Here’s the screen…

The agent called koolbase_get_collection to learn the collection’s access rule, then koolbase_sdk_conventions for the Flutter call shapes — and generated code against your real backend, not a guessed one.

Security notes

  • •Scopes are enforced server-side. The MCP server cannot exceed its key’s scope, regardless of what a tool or assistant attempts.
  • •Keys cannot mint other keys. A leaked key is bounded by its own scope and cannot escalate.
  • •Give assistants the least scope they need. Use a read key for exploration; reserve write for when changes are intended.
  • •Your MCP client stores the key in its config file in plaintext. Treat that file as a secret, and prefer a dedicated key per machine so revocation is surgical.
  • •Revoke a key at any time from the dashboard. Revocation takes effect immediately.