MCP Server
The Featureflip MCP server (@featureflip/mcp) lets AI coding assistants and autonomous agents
manage feature flags through the Management API: create and toggle
flags, adjust targeting and rollouts, and find stale flags ready for cleanup — without leaving the editor.
It runs as a local process over stdio via npx, so there’s nothing to deploy: your agent starts it,
talks to it over the Model Context Protocol, and it calls the Management API on your behalf using
whatever token you give it.
It works on every plan, including Free. The Management API it calls is available on all plans, so you can create an account, generate a token, and let an agent manage real flags without a paid subscription.
Installation
Section titled “Installation”You’ll need an API token first — see Authentication below. Once you have one, add the server to your MCP client.
Claude Code
Section titled “Claude Code”claude mcp add featureflip -e FEATUREFLIP_TOKEN=ffp_your_token -- npx -y @featureflip/mcp@latestClaude Desktop
Section titled “Claude Desktop”Each release since 0.1.12 carries an MCP Bundle, featureflip-mcp-<version>.mcpb, on the
featureflip-mcp releases page.
Download it and open it with Claude Desktop to install the server in one step. Claude Desktop then
asks for your API token in its own settings, so there is no JSON config to write. The bundle needs
Node.js 20.19 or later.
Cursor / Cline / generic JSON config
Section titled “Cursor / Cline / generic JSON config”Most other MCP clients (Cursor, Cline, and anything that reads a standard MCP config file) use a JSON block like this:
{ "mcpServers": { "featureflip": { "command": "npx", "args": ["-y", "@featureflip/mcp@latest"], "env": { "FEATUREFLIP_TOKEN": "ffp_your_token" } } }}The Claude Code and JSON forms launch the same package: npx -y @featureflip/mcp@latest. The -y flag skips npm’s install
confirmation prompt, which matters because most MCP clients invoke the command non-interactively.
Keep the @latest. Without a version, npx reuses the copy it downloaded the first time and never
checks npm again, so tools added in later releases would never show up in your client.
Authentication
Section titled “Authentication”The MCP server authenticates the same way the Management API does — with a bearer token passed via the
FEATUREFLIP_TOKEN environment variable. There are two token types:
- Personal token (
ffp_...) — create one under Settings → API Tokens in the dashboard. It acts as you, carrying your role in every organization you belong to. This is the right choice for interactive editor use (Claude Code, Cursor) where you want the agent’s changes attributed to you. - Service token (
ffs_...) — create one under Organization Settings → Service Tokens. It’s a machine identity scoped to a single organization, and the right choice for CI or unattended agents.
See Authentication for the full walkthrough of token types,
roles, and error handling — the MCP server inherits all of it. A token below the required role for a
write returns the same 403 forbidden you’d see from a raw API call.
Configuration
Section titled “Configuration”| Env var | Required | Default | Purpose |
|---|---|---|---|
FEATUREFLIP_TOKEN | yes | — | ffp_/ffs_ API token |
FEATUREFLIP_API_URL | no | https://api.featureflip.io | API base URL |
FEATUREFLIP_ORG | no | auto | Org slug (needed only for multi-org personal tokens) |
Most setups only need FEATUREFLIP_TOKEN. Set FEATUREFLIP_API_URL if you’re pointing at a
self-hosted or non-default deployment. Set FEATUREFLIP_ORG if your personal token belongs to more
than one organization — without it, the server exits at startup with an error listing the org slugs it
can see (it can’t prompt you interactively) and you re-run with FEATUREFLIP_ORG set to one of them.
Tool reference
Section titled “Tool reference”The server exposes 39 tools. Read-only tools are always safe to call; destructive tools change or remove existing state and should be used deliberately (most agent clients will ask for confirmation before running them). Non-destructive writes create new state without touching anything existing.
Read-only
Section titled “Read-only”| Tool | What it does |
|---|---|
list_projects | List projects in an organization |
list_environments | List environments in a project |
list_sdk_keys | List an environment’s SDK keys (last four characters only; the full key is shown once, at creation) |
list_segments | List reusable user segments in a project |
get_segment | Get a single segment’s rules |
list_flags | List feature flags in a project |
get_flag | Get a single flag’s configuration |
flag_status | Cross-environment view of a flag’s enabled state, strategy, default variation, and prerequisites per environment |
compare_environments | Compare flag configuration between two environments: which flags differ and in which sections (state, default variation, strategy, rules, prerequisites). Returns only differing flags unless different_only is false |
flag_evaluations | What a flag served in one environment over the last 7, 30 or 90 days: total evaluations, the split by variation, and which rule served what, with a sample-ratio check on percentage rollouts. Counts are evaluations, so one user evaluated ten times counts ten times |
get_targeting | Get a flag’s current targeting rules in one environment — read before you update_targeting |
find_stale_flags | Find flags that look like cleanup candidates, with the flags that depend on each one. Skips permanent flags |
list_removal_candidates | List the flags Featureflip is confident you can remove, the same list the flag cleanup Action uses. Skips permanent flags |
list_webhooks | List webhook subscriptions and the event types they can filter on |
list_webhook_deliveries | List one subscription’s delivery attempts and their outcomes |
list_flag_triggers | List a flag’s triggers in one environment, or get one by id, with when each last fired (the URL is never listed) |
Non-destructive writes
Section titled “Non-destructive writes”| Tool | What it does |
|---|---|
create_flag | Create a new feature flag (starts disabled in every environment). Pass isPermanent: true for a kill switch or ops toggle that’s meant to stay |
restore_flag | Restore an archived flag |
set_flag_expiry | Set or clear the date a flag should be removed by (evaluation doesn’t change) |
set_flag_owner | Set or clear the person responsible for a flag (evaluation doesn’t change) |
set_default_flag_lifetime | Set or remove how long a temporary flag lives before it counts as expired. preview: true shows how many flags it would affect first |
set_flag_permanent | Mark a flag permanent so cleanup tools skip it, or make it temporary again (evaluation doesn’t change) |
wrap_feature | Create a flag and return an SDK snippet to wrap your code with it |
deliver_webhook | Send a test event to a webhook, or redeliver a past delivery |
Destructive
Section titled “Destructive”| Tool | What it does |
|---|---|
delete_flag | Permanently delete a flag |
update_flag | Update a flag’s name, description, tags, or client-side visibility (hiding a flag from client SDKs changes what they evaluate) |
archive_flag | Archive a flag |
toggle_flag | Enable or disable a flag in an environment |
copy_flag_config | Copy one flag’s targeting from one environment into another. Previews by default and changes nothing; on/off is copied only with include_state. Applying (dry_run: false) needs both ETags from a preview, with the same source and include_state (a 412 means preview again). Team plan and above. Copying into a critical environment needs a reason |
update_flag_environment_config | Change a flag’s per-environment configuration |
update_targeting | Replace a flag’s targeting rules, conditions, and rollout percentage wholesale — read the current rules first with get_targeting |
manage_variation | Add, update, or remove a flag’s variations |
manage_webhook | Create, update, or delete a webhook subscription, or rotate its signing secret |
manage_project | Create a project or change its name and description |
manage_environment | Create an environment or change its name, color, order and critical environment settings |
manage_sdk_key | Create, rename, or revoke an SDK key. Creating returns the full key once |
manage_segment | Create, update, or delete a user segment |
manage_targeting_rule | Add, update, remove, or reorder a single targeting rule |
manage_flag_trigger | Create, update, rotate, or delete a flag trigger, the URL a monitoring tool calls to turn a flag on or off. Creating or rotating returns the URL once |
The four webhook tools need an Admin token, reads included. When you create a subscription or rotate its secret, the response shows the signing secret. It is never shown again.
manage_webhook creates a generic HTTP endpoint unless you pass provider: "Slack", which a Slack incoming
webhook URL needs. See Sending to Slack. For "Datadog" or "Grafana",
also pass credential, a write-only API key or token that is never returned. See
Sending to Datadog and
Sending to Grafana.
The write tools take an optional reason, sent as the X-Intent-Reason header and shown in the audit log.
A critical environment refuses changes that arrive without one, and the
error tells the agent to retry with a reason, so it will usually ask you why before it tries again.
manage_sdk_key shows a new key in full exactly once, when it creates it. Have the agent write it to an
untracked .env file or a secret store. To rotate a key, create the new one, deploy it, then revoke the old one.
manage_flag_trigger returns a trigger’s URL and secret only when it creates or rotates one. Anyone holding either can flip the flag, so paste it into your monitoring tool as a secret and keep it out of the repo. If it leaks, ask the agent to rotate the trigger. The old URL stops working at once.
get_flag, get_targeting and get_segment return an etag. Pass it back as ifMatch to update_flag,
update_targeting or a manage_segment update and the write fails if someone changed the resource after the agent
read it, instead of silently overwriting their change. Those writes return the new etag too, so a second
conditional write can use it without reading the resource again. Creating or deleting a segment can’t be made conditional, so
manage_segment refuses ifMatch on those actions rather than ignoring it.
Example agent workflows
Section titled “Example agent workflows”Wrap new code in a flag
Section titled “Wrap new code in a flag”Ask the agent to gate a new feature behind a flag. It calls wrap_feature, which creates the flag
(disabled everywhere, as all new flags are) and returns a code snippet using the SDK for your project’s
language — the agent applies that snippet directly to your working tree. Once you’re ready to test it,
ask the agent to enable it in dev: it calls toggle_flag for the dev environment. The flag stays off
in every other environment until you say otherwise.
Ramp a rollout
Section titled “Ramp a rollout”To gradually roll out a flag that’s already live, ask the agent to ramp it: it calls update_targeting
with rolloutPercentage set to 10, then later 50, then 100 as you gain confidence — each call
replaces the previous percentage rather than stacking. Once the flag has been at 100% for a while, it’s
a candidate for cleanup — find_stale_flags will start surfacing it.
Clean up shipped flags
Section titled “Clean up shipped flags”Periodically ask the agent to find cleanup candidates. It calls find_stale_flags, which returns flags
that have been fully rolled out or unchanged for a long stretch. find_stale_flags checks whether every
environment is enabled, not whether a per-rule percentage ramp has actually reached 100% — confirm the
rollout is complete before removing. Flags marked permanent never
show up, so a kill switch that has served one value for a year isn’t offered for removal. For each one you confirm, the agent calls delete_flag and removes
the corresponding conditional from your code — leaving a single code path where the flag used to be.
When one flag is a prerequisite of another, remove the dependent first. Each result’s blockedBy lists
the live flags that still depend on it. Archive a prerequisite while a dependent still names it and the
dependent fails its check and serves its off variation, so archive_flag refuses with
FLAG_HAS_DEPENDENTS. A blockedBy of null means Featureflip had no answer for that flag. The archive
still refuses it if a live flag depends on it, so the removal can wait until the dependents are gone.
- Flag evaluation is not exposed over MCP — use the SDKs in application code. The MCP server manages flag configuration, not runtime evaluation.
wrap_featurereturns a snippet for you or your agent to apply; it never edits files on its own.- Every mutation is audit-logged and attributed to the token that made it, same as a direct API call.
- Requests are rate-limited per token. Errors carry machine-readable hints (
did_you_mean,next_actions) so an agent can recover without human intervention — for example, a typo’d flag key suggests the closest match, and a403on a locked action points at what to try next.
Frequently asked questions
Section titled “Frequently asked questions”Do I need a paid plan to use the Featureflip MCP server?
Section titled “Do I need a paid plan to use the Featureflip MCP server?”No. The MCP server works on every Featureflip plan, including Free. It calls the Management API, which is available on all plans, so you can create an account, generate a token, and let Claude Code or Cursor manage real flags without a subscription or a sales call.
Which AI tools can manage Featureflip feature flags?
Section titled “Which AI tools can manage Featureflip feature flags?”Any client that speaks the Model Context Protocol. That covers Claude Code, Cursor, VS Code with
Copilot, and Cline, plus autonomous and CI agents. Interactive editor use is best served by a Personal
Access Token (ffp_) so changes are attributed to you. Unattended agents should use a Service Token
(ffs_) scoped to one organization.
Can an AI agent turn on a feature flag in production?
Section titled “Can an AI agent turn on a feature flag in production?”Yes, if the token you hand it carries the permission. toggle_flag takes an environment, so an agent
enables a flag one environment at a time, and every new flag is created disabled everywhere. The tool
is marked destructive, which is the signal most MCP clients use to ask you before running it, and each
toggle is audit-logged against the token that made it.
Does the MCP server evaluate flags?
Section titled “Does the MCP server evaluate flags?”No. It manages configuration: creating flags, setting variations, toggling environments, and writing targeting rules. Reading a flag’s value for a given user at runtime belongs to the language SDKs, which evaluate locally in memory on your application’s request path.
What happens when an agent uses a flag key that doesn’t exist?
Section titled “What happens when an agent uses a flag key that doesn’t exist?”The Management API returns its standard error envelope with a did_you_mean field naming the closest
matching key, and the server passes that through unchanged. A well-behaved agent reads the suggestion
and corrects itself on the next call instead of stopping to ask.