Connect AI coding assistants and autonomous agents to Flaggr using the official @flaggr/mcp-server package
Last updated October 25, 2026
Model Context Protocol (MCP) Server
The Flaggr MCP Server (@flaggr/mcp-server) connects AI coding assistants—such as Claude Desktop, Cursor, VS Code Copilot, and Antigravity—directly to your Flaggr instance.
With the MCP server, AI assistants can:
- Walk new users through setup in an interactive in-chat app (Claude, Codex, ChatGPT)
- List, create, update, evaluate, and toggle feature flags
- Run rollout plans gated on browser vitals (LCP, INP, CLS), JS errors and conversion — canary vs baseline
- Work alert incidents: assign, investigate, add notes, resolve
- Read project overview KPIs, evaluation trends, flag exposure and real-user browser analytics
- Administer organizations, members, invitations, teams, flag ownership and API tokens
- Profile traces, measure real-time propagation, and inspect the audit log
New here? Follow Connect Claude, Codex & AI Assistants or the interactive guide at flaggr.dev/connect.
Remote Connector (Recommended)
Flaggr hosts a remote MCP endpoint at https://flaggr.dev/mcp — the fastest path for clients that support remote MCP servers (Claude connectors, ChatGPT connectors, Codex, Cursor). No local install, no token management — OAuth handles everything. flaggr.dev/connect has step-by-step screens for each client.
Claude Code
claude mcp add --transport http --scope user flaggr https://flaggr.dev/mcpThen run /mcp, select flaggr and choose Authenticate.
Claude / Claude.ai
Settings → Connectors → Add custom connector → URL: https://flaggr.dev/mcp. Claude walks you through sign-in, project selection, and scoping in the browser.
Codex
codex mcp add flaggr --url https://flaggr.dev/mcp
codex mcp login flaggrChatGPT / generic MCP clients
Any client implementing the MCP authorization spec works: point it at https://flaggr.dev/mcp and it discovers the OAuth endpoints via /.well-known/oauth-protected-resource, self-registers via Dynamic Client Registration, and runs the authorization-code + PKCE flow.
How the flow works
Scoping
The hosted endpoint accepts both initialize-era MCP clients (through 2025-11-25)
and the 2026-07-28 stateless envelope used by Cuttlefish. Modern requests carry
params._meta["io.modelcontextprotocol/protocolVersion"] and matching
MCP-Protocol-Version / Mcp-Method headers; tool calls and named resource/prompt
reads also carry a matching Mcp-Name header. server/discover advertises the modern
revision without requiring initialize. Modern results include resultType, server
metadata and discovery/read caching hints; HTTP responses remain uncached. Modern
batch requests are rejected, notifications receive 202, and request bodies are
bounded at 1 MiB. Both paths retain the same OAuth, project and tier checks.
OAuth grants are bound to the registered client and the MCP resource https://flaggr.dev/mcp.
The authorization-server metadata advertises offline_access for clients that request
persistent access. Flaggr issues a refresh token with every successful grant; this
auxiliary scope adds no project permissions and does not change token lifetimes.
Protected-resource metadata and authentication challenges require only read.
Both legacy and modern HTTP requests return finite JSON. Clients may accept
application/json, application/* or */*, or omit Accept; advertising SSE
is unnecessary. JSON media types are case-insensitive. Explicitly excluding JSON
with q=0 still returns 406, and non-JSON request media types return 415.
MCP authentication failures return X-Flaggr-MCP-Request-ID; token exchanges return
X-Flaggr-OAuth-Request-ID. Server diagnostics record refusal categories and whether
a refresh token was issued, without recording tokens, OAuth parameters or project scopes.
Code exchange requires the registered redirect_uri; refresh requires the issuing client_id.
When a client supplies resource, it must identify this endpoint and match the consented resource.
For older clients that omit it, Flaggr binds the grant to its own MCP endpoint. A mismatched refresh
request is rejected without consuming the legitimate connection's token. Token responses are never cached.
Deployments upgrading from earlier versions must apply 054_mcp_oauth_resource.sql before starting
the new server. The additive migration binds existing production grants to this endpoint without
changing their projects, permissions, expiry or secrets. Independent runtime and scanner grants with
identical consent remain supported.
For hosted transport failures, server logs record a protocol_rejected phase with the
X-Flaggr-MCP-Request-ID returned to the client. It includes elapsed time, HTTP status,
a fixed rejection category (for example invalid_jsonrpc or unsupported_protocol_version),
and header presence/compatibility indicators. Unsupported version values, session IDs,
credentials, request bodies and raw SDK errors are not included. A fast HTTP rejection
and a client-side timeout are separate observations; correlate them before attributing
a scanner failure to a particular request.
During consent you pick which projects the connector can access and one of three access levels for the connection. That level is the most any project can get. Each selected project can then be given a lower level on the same screen:
| Access | Scope | Tools the client sees |
|---|---|---|
| Read your flags | read | Evaluate, list flags, analytics, browser vitals, release analytics, incidents, traces, audit log |
| Manage flags & rollouts | read write | Plus flag changes, targeting, rollout plans, experiments, incident workflow, sites, alert rules |
| Administer projects & members | read write admin | Plus organizations, members, invitations, teams, API tokens, environments and settings |
Rollout status reads (get_canary_status, list_rollout_plans, get_rollout_plan) let the engine progress due stages, including rollback and configured notifications, so they require write access. check_site_guardrails also requires write access because it can execute mitigation. Use get_connection for a passive connection check.
Tools above the connection's level are not advertised to the client at all. The API enforces each project's access on every request to that project: a project at read gets 403 on any change there, and a project below admin gets 403 on its member, team, token and settings routes. Creating an API token, a flag trigger or a share link, listing a project's API tokens and inviting a project member need admin on that project. Organization-level changes need admin on every selected project of that organization. Creating an organization needs admin at the connection's level, and creating a project needs that and, in an organization that owns selected projects, admin on each of them (403 "connector token lacks the admin scope for every project of this organization"). Deleting a project or organization is never available to a connector. Administration is opt-in on the consent screen even when a client requests it.
Project scope is enforced server-side on every tool call — a token for project-a gets 403 on project-b, list_projects only returns consented projects, and scope survives token refresh. When an admin connector creates a project with create_project, that project joins the token's scope automatically, at the connection's level.
Organization-level tools work only in organizations that own at least one of the connector's consented projects. A connector can create a project only in such an organization, or in a brand-new organization you created that has no projects yet: after create_organization, create a project in the new organization with create_project before managing the organization. Anywhere else it gets 403 "connector token is not scoped to this organization". Connectors can never change project or organization ownership (granting or removing owner); use the dashboard.
Latest access wins. A changed approval from the same OAuth client (the same client_id) replaces its grants with different stored scopes or project selections, so a narrower approval cannot leave broader access in use. Exact stored consent matches can coexist, such as a runtime connection and a publication scanner: each gets independent access and refresh tokens, and authorizing one does not invalidate the other. Creating a project through the connector also changes its allowlist and invalidates that client's other grants with a different project selection. Explicitly disconnect the client on flaggr.dev/connect to revoke all its grants rather than relying on an identical reauthorization. An assistant that registers a new client when it reconnects appears as a separate connection; disconnect the old client there too if it is no longer needed.
Access errors
A connector gets a 403 that names the access it lacks. Reconnect and raise that access on the approval page:
| Message | Access that is missing | Fix |
|---|---|---|
connector token is read-only | The connection's level | Allow Manage flags & rollouts |
connector token lacks the admin scope | The connection's level | Allow Administer projects & members |
connector token is read-only in this project | That project's access (Read) | Allow Manage flags & rollouts if the connection is read only, then give the project Read & write |
connector token lacks the admin scope in this project | That project's access | Allow Administer projects & members, then give the project Admin |
connector token lacks the admin scope for every project of this organization | Admin on each selected project of that organization | Allow Administer projects & members, then give each of those projects Admin |
connector token is not scoped to this project | The project wasn't selected | Reconnect and select it |
connector token is not scoped to this organization | No selected project belongs to the organization | Reconnect and select one of its projects |
Project API tokens and personal access tokens get a 403 that names what they lack: more access (for example read-only or lacks admin access), or, for a project API token whose scopes don't name the service, environment or flag of the request, API token scopes don't cover this resource. Create a token with the access or scopes the request needs. Reconnecting applies only to connectors.
Revocation
Disconnect any assistant from flaggr.dev/connect, which lists each connected client with its access level, each project's access, its projects and its last use. Disconnect revokes all the client's grants and also voids approvals it hasn't exchanged for a token yet. POST /api/oauth/revoke revokes the individual grant identified by its supplied access or refresh token. Tokens are hashed at rest and checked on every request, so revocation is immediate.
Local Stdio Setup
Use the local server with a personal access token (fgp_… — every project you can access, capped by its tier; create one under Profile → Personal access tokens), a project API token (fgr_… — one project), or the credentials flaggr login saved.
1. Claude Desktop
Add @flaggr/mcp-server to your claude_desktop_config.json:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"flaggr": {
"command": "npx",
"args": ["-y", "@flaggr/mcp-server@latest"],
"env": {
"FLAGGR_API_URL": "https://flaggr.dev",
"FLAGGR_API_TOKEN": "fgp_your_token_here"
}
}
}
}Tip: If you have already authenticated using the Flaggr CLI (
flaggr login), the MCP server will automatically discover your credentials from~/.flaggr/config.json. You can omitFLAGGR_API_TOKEN.
Use @flaggr/mcp-server 0.3.0 or later: earlier versions can run shell commands taken from a crafted url passed to the login tool. @latest makes npx fetch the newest release from npm (npm view @flaggr/mcp-server version shows which that is); with no version, npx can keep running an older copy from its cache. Until npm view @flaggr/mcp-server version prints 0.3.0 or later, @latest installs an earlier version: use the remote connector instead.
2. Cursor IDE
Add to your project's .cursor/mcp.json or Global Cursor Settings:
{
"mcpServers": {
"flaggr": {
"command": "npx",
"args": ["-y", "@flaggr/mcp-server@latest"],
"env": {
"FLAGGR_API_URL": "https://flaggr.dev",
"FLAGGR_API_TOKEN": "fgp_your_token_here"
}
}
}
}Authentication Methods
The Flaggr MCP server supports three authentication methods:
- Auto-Discovery via Flaggr CLI:
Reads
~/.flaggr/config.jsonminted byflaggr login. Zero configuration required. - Interactive OAuth via
loginTool: Prompt the agent: "Log in to Flaggr". The agent calls thelogintool, opening your browser to authorize. Choose All my projects on the authorization page for a personal access token (write tier, 90 days), or One project for a project API token. The tool sends a one-timestateto the sign-in page and accepts only the browser callback that returns it. Any other request to its localhost port is ignored, so a web page can't log the server into a different account. The sign-in page hands over the token in a form POST, never in a URL, so it stays out of your browser history. The tool refuses a token sent in the URL by an older Flaggr server and asks you to revoke it. The tool'surlmust be an http(s) server base URL without user name, password, query or fragment; the browser is opened without a shell.logoutforgets the token on this machine (memory and~/.flaggr/config.json) but doesn't revoke it — revoke it under Profile → Personal access tokens, or in the project's Settings → API tokens for a project API token. - Direct Environment Variable:
Set
FLAGGR_API_TOKEN— a personal access token (fgp_…) or a project API token (fgr_…) — in your MCP configuration.
get_connection shows which credential and tier the server is using. The stdio server reads the same answer from /api/users/me and hides the tools its token can't use.
Personal access tokens (fgp_…) work everywhere except flag evaluation and creating credentials. With one, the stdio server also hides evaluate_flag, trace_flag_evaluation, watch_flag_updates, measure_round_trip, record_bandit_reward, create_api_token, rotate_api_token, invite_project_member and invite_org_member. Read-tier tokens can't make changes: the API accepts only GET requests and the read-only POSTs (explain, simulate, advice, code references, cohort evaluation) from them. Read-tier tokens keep explain_flag_evaluation, simulate_flag_targeting and evaluate_cohort_membership. Evaluate with a project API token (SDK key), and create API tokens and invitations in the dashboard.
Project API tokens (fgr_…) act only inside their project, capped by their scopes: project, service, environment or flag rules, each read, write or admin. A legacy whole-project token is capped by its Read / Write / Delete permissions (Delete counts as the admin tier). With one, the stdio server also hides the tools project tokens can never use: create_api_token, rotate_api_token, invite_project_member, invite_org_member, create_project, create_organization, every organization tool except get_organization, list_org_projects and list_organizations, and the member, invitation and team tools (add_project_member, update_project_member, remove_project_member, list_project_invitations, revoke_project_invitation, create_team, update_team, delete_team). delete_flag needs admin access to the flag (an admin scope covering it, or the Delete permission on a legacy token), so read and write tokens — including the read+write tokens flaggr login mints — don't see it; the other delete tools only need Write. A 403 from a token names what it lacks: create a token with that access or with the scopes the request needs (reconnecting only applies to connectors). Manage members and teams with a personal access token or a connector, and create tokens and invitations in the dashboard (or with an admin connector).
The Flaggr app (MCP Apps)
open_flaggr opens an interactive view (ui://flaggr/console, text/html;profile=mcp-app) in hosts that support MCP Apps — Claude, Codex and ChatGPT. New connections get a setup checklist with a screen per stage (connect → project → service → first flag → SDK → browser analytics); finished projects get a home with KPIs, flags and suggested prompts. In Codex, the tool's global entrypoint lists Flaggr under Explore, where you can Pin to sidebar.
The view is a self-contained bundle (no remote assets or network access of its own). Every read and write goes through the host bridge to this server; before any change it re-reads get_connection and stops if the server, account or access level changed. Its access hints follow the credential: a connector is told to reconnect and allow more access, while a personal access token or project API token is told to create a token with the tier it needs (Profile → Personal access tokens, or the project's settings → API tokens). Prompts are only sent to the chat, and context only shared, when you click.
Clients without MCP Apps get the same checklist from get_onboarding_status. Both offer to create a project only to credentials that can: dashboard sessions, admin connectors and admin personal access tokens (never project API tokens).
Tool Catalog
164 tools, grouped by area; the local stdio server adds three sign-in tools (167 in all). Access is the minimum connector level that can see the tool. The local stdio server applies the same tiers to its own token — a connector's scope, or the tier of a project API token or personal access token, read from /api/users/me at startup and again after login/logout — and hides the tools that kind of token can never use (see Authentication Methods). A connector narrowed on some projects shows the stdio server the tools of the connection's tier, as the hosted connector does (/api/users/me reports the connection's tier), and the API refuses what a project's lower access doesn't allow (403 "… in this project"). With no token, or no answer within 3 seconds, it shows every tool. Project roles still apply.
Setup & connection
| Tool | Access | What it does |
|---|---|---|
open_flaggr | read | Open the interactive Flaggr app: guided setup (project, service, first flag, SDK, browser analytics) for new connections, then a project home. Accepts empty arguments from app navigation or a chat tab. |
get_onboarding_status | read | Check Flaggr setup progress for a project — which of project, service, first flag, SDK evaluation and browser analytics are done — with the next step and a ready-made prompt for it. Use when a user is getting started or asks what's left to set up. |
get_connection | read | Show which Flaggr server and account this connection uses: endpoint, signed-in user, the credential (connector, project API token or personal access token) and its access tier (read / write / admin), projects in scope, and server build. Use to verify the connection before acting, or when access looks wrong. |
Directory
| Tool | Access | What it does |
|---|---|---|
list_organizations | read | List all organizations the authenticated user belongs to. |
get_organization | read | Get organization details and metadata by ID. |
list_projects | read | List all projects the authenticated user has access to. |
list_services | read | List all services within a project. |
Organizations, projects & members
| Tool | Access | What it does |
|---|---|---|
create_organization | admin | Create a new organization; you become its owner. |
update_organization | admin | Rename an organization, change its description, or restrict which email domains can be invited. |
list_org_members | read | List an organization's members with their org role, user ID and membership ID. Use the membership ID with update_org_member_role or remove_org_member. |
add_org_member | admin | Add someone you already share an organization or project with to an organization, by user ID (from list_org_members or list_project_members). Anyone else — and anyone you only know by email — must be invited with invite_org_member: Flaggr never looks an address up and adds the account. An unknown user ID and one you share nothing with get the same 404. Only organization owners can add an owner. May fail with 402 when a project in the organization has no free seat on its plan. |
update_org_member_role | admin | Change a member's organization role. Only owners grant the owner role or change or remove an owner; everyone else assigns roles up to their own and can't raise their own role or add themselves. Ownership changes are refused for connectors and API tokens — use the Flaggr dashboard (or a personal access token created with owner actions). The last owner cannot be demoted. |
remove_org_member | admin | Remove a member from an organization. This also removes their direct memberships and team seats in the organization's projects. Someone who owns a project in the organization can only be removed by an organization owner, who becomes the direct owner of any project they were the last owner of; the org's last owner can't be removed. Members may remove themselves (leave) unless they are a project's last owner. Ownership changes are refused for connectors and API tokens. |
list_org_invitations | admin | List an organization's invitations with their status and expiry. |
invite_org_member | admin | Invite someone to an organization by email. Flaggr emails them an accept link that works once and expires in 7 days; they accept it signed in with that (verified) address. Owner can't be invited — invite them, then promote them once they join. This is how to add anyone by email (whether or not they have an account — the answer is the same); add_org_member only adds people you already share an organization or project with, by user ID. May fail with 409 (already a member, or an invitation is already pending), 402 (a project in the organization has no free seat under the organization's plan, its most generous project plan; pending invitations hold one) or 429 (more than 20 invitations an hour; attempts refused with 409 or 402 count too). |
revoke_org_invitation | admin | Delete a pending organization invitation. |
list_org_projects | read | List every project in an organization. |
get_project | read | Get a project's details: slug, organization, member count, tags and settings. |
create_project | admin | Create a project; you become its owner and default environments are seeded. |
update_project_settings | admin | Update a project's name, description, slug, tags or settings. Nested settings sections merge with current values; only owners can change the slug. |
list_project_members | read | List a project's direct members with role, access overrides, user ID and membership ID. Use the membership ID with update_project_member or remove_project_member. |
add_project_member | admin | Add someone you already share an organization or project with to a project, by user ID (e.g. from list_org_members). Anyone else — and anyone you only know by email — must be invited with invite_project_member. An unknown user ID and one you share nothing with get the same 404; 402 when the plan has no free seat. Only owners grant the owner role or change or remove an owner; everyone else assigns roles up to their own and can't raise their own role or add themselves. Ownership changes are refused for connectors and API tokens — use the Flaggr dashboard (or a personal access token created with owner actions). |
update_project_member | admin | Change a project member's role and/or per-environment and per-service access overrides. Only owners grant the owner role or change or remove an owner; everyone else assigns roles up to their own and can't raise their own role or add themselves. Ownership changes are refused for connectors and API tokens — use the Flaggr dashboard (or a personal access token created with owner actions). The same applies to overrides: only owners set "owner" in a scope or change an owner's access. The last owner cannot be demoted. |
remove_project_member | admin | Remove a member from a project and its teams. Org members keep any access they get through the organization. Only owners remove an owner, and the last owner stays; members may remove themselves (leave). |
get_member_access | read | Show a project member's effective role in every environment and service after access overrides. Use it to check what someone can do before or after update_project_member. |
get_my_project_access | read | Show your own effective role in a project's environments and services, to check what you can change before trying. |
list_project_invitations | admin | List a project's invitations with status and expiry. |
invite_project_member | admin | Invite someone to a project by email. Flaggr emails them an accept link that works once and is valid for 7 days. May fail with 409 (already a member, or an invitation is already pending — revoke it with revoke_project_invitation first), 402 (the plan's member limit; pending invitations hold a seat) or 429 (more than 20 invitations an hour; attempts refused with 409 or 402 count too). |
revoke_project_invitation | admin | Delete a pending project invitation so its emailed link stops working. Accepted invitations can't be revoked (409) — remove the member instead. |
Connectors manage only organizations that own one of their consented projects, and create projects only there or in a brand-new organization (see Scoping). Connectors and project API tokens can never change ownership (granting, changing or removing owner) — use the dashboard, or a personal access token created with owner actions.
Teams & flag ownership
| Tool | Access | What it does |
|---|---|---|
list_teams | read | List a project's teams with their members, plus every flag's owning team or person. |
create_team | admin | Create a project team. Members must already be direct project members; people removed from the project (or from its organization) leave its teams automatically. |
update_team | admin | Rename, recolor or describe a team, or replace its member list. Members must be direct project members; removed members leave teams automatically. |
delete_team | admin | Delete a team. Flags it owned keep their individual owner; flags with no owner left become unowned. |
get_flag_owners | read | Get the owning team and person for one flag (pass serviceId and flagKey), or list owners across the project. Team names are in list_teams. |
set_flag_owner | write | Assign the team and/or person who owns a flag (covers every environment). Omitted fields keep their current value; null clears one; both null clears ownership. |
API tokens
| Tool | Access | What it does |
|---|---|---|
list_api_tokens | admin | List a project's API tokens: type, access, last-4 hint, last use and expiry. Secrets are never returned. |
create_api_token | admin | Create a project API token: a long-lived fgr_ token whose access is a list of scopes (project, service, environment or flag rules, each read, write or admin; with no scopes it reads the whole project), or an SDK key with sdkKey (evaluation only, read rules only). Service slugs and names are resolved to IDs. It never expires unless expiresAt is set. format: "jwt" issues the legacy short-lived JWT instead, and permissions (read, write, delete) makes a legacy whole-project token. The token works only in this project and never above your own role. The secret is returned once and lands in this conversation's transcript, so store it in a secret manager right away. Creating or rotating a token is credential issuance: it works with an admin connector or the Flaggr dashboard, never when this server runs on a project API token or a personal access token (403). |
rotate_api_token | admin | Replace a project API token with a new secret that keeps its name, access, expiry and identity: it still acts as the person who created the original, and rotating it needs a project role at least as high as theirs. Pass scopes or expiresAt (null for no expiry) to change the access or expiry in the same step (opaque tokens only). Only the token's creator can do that: anyone else gets 403 NOT_TOKEN_CREATOR and rotates without a body. An expired token needs a new expiresAt, which only its creator can send; without one the rotation fails with 409 TOKEN_EXPIRED. The old token is deleted immediately, so its clients fail until updated. The new secret is returned once and lands in this conversation's transcript. Creating or rotating a token is credential issuance: it works with an admin connector or the Flaggr dashboard, never when this server runs on a project API token or a personal access token (403). |
revoke_api_token | admin | Permanently delete a project API token; anything using it fails from now on, including this MCP server if it is the token configured here. |
list_my_tokens | admin | List the API tokens you created, only in the projects this credential could list tokens for. Secrets and hashes are never returned. |
Services & code references
Code searches use the GitHub repository connection saved by a project administrator in Settings → GitHub. Neither code-reference tool accepts a GitHub credential. Missing configuration, expired credentials and inaccessible repositories produce actionable errors; reconnect in Flaggr rather than putting credentials in chat.
| Tool | Access | What it does |
|---|---|---|
get_service | read | Details and settings of one service: name, slug, project, description, tags, platform, stack, default environment, SDK config, ignored unknown keys and the cached code-reference scan. Look it up by ID, or by slug within a project. |
create_service | write | Create a service (an app or microservice that evaluates flags) in a project, optionally with tags, platform, stack label and default environment. Flags, sites and API tokens hang off services. |
update_service | write | Update a service's name, description, tags or settings (platform, stack label, default environment, ignored unknown keys, SDK config served by /api/sdk-config). Only the fields you pass change — SDK fields merge into the existing SDK config; tags and ignoredUnknownKeys replace the whole list. |
get_service_code_references | read | The cached GitHub code-reference scan for a service: where each of its flag keys appears in the repo (file, link, matching line) and which keys were not found — candidates for cleanup. Run scan_service_code_references to refresh. |
scan_service_code_references | write | Search a GitHub repo for every flag key of a service (all environments, up to 60 keys) and cache the result on the service. Use to find where flags are read and which are no longer referenced. |
search_flag_code_references | read | Search a GitHub repo for one flag key (exact match) and list the files that reference it. Use before removing or renaming a flag. Nothing is stored; scan_service_code_references covers every key of a service. A read-only GET; the optional GitHub token travels in the X-GitHub-Token header, never the URL. |
get_service_lifecycle | read | Lifecycle state of each flag × environment in a service (new, active, launched, inactive, stale) with days since last evaluation, 7-day volume and archive readiness. Use to plan flag cleanup for one service. |
get_service_history | read | Recent audit events for a service and its flags (created, updated, toggled, settings changes), newest first, with who made each change and a change summary. Use to answer 'what changed in this service lately?'; get_audit_log covers the whole project. |
Flags, evaluation & tracing
| Tool | Access | What it does |
|---|---|---|
list_flags | read | List all feature flags for a project, optionally filtered by service and environment. |
create_flag | write | Create a new feature flag. |
update_flag | write | Update an existing feature flag's properties. In targeting, a rule with no conditions matches everyone (see add_targeting_rule); rule percentages and variant weights are whole numbers from 0 to 100. |
toggle_flag | write | Toggle a feature flag on/off or explicitly set its enabled state. |
bulk_toggle_flags | write | Toggle many feature flags on/off in a single batched request (up to 100 keys). Much faster and lower-impact than calling toggle_flag repeatedly — one batched DB update plus one invalidation notification per environment. |
delete_flag | write | Delete a feature flag permanently. Project API tokens need an admin scope covering the flag (the Delete permission on a legacy token). |
evaluate_flag | read | Evaluate a feature flag for a given context. Returns the resolved value, variant, and reason. |
measure_round_trip | write | Measure true real-time round-trip propagation time: opens live SSE stream, toggles a flag, and measures the exact milliseconds until the update event is delivered on the stream. |
watch_flag_updates | read | Stream and capture real-time flag update events from Flaggr's SSE stream for a specified duration. |
get_trace | read | Inspect a detailed end-to-end OpenTelemetry distributed trace by trace ID, including per-hop latency, status, and hotspot analysis. |
get_flag_traces | read | Query recent short-term in-memory distributed traces for a flag or service, with bottleneck hotspots and duration summaries. Connectors and project API tokens list one service at a time: without serviceId the tool uses the project's service that has the flag. Without serviceId, sessions and personal access tokens get the traces of every service they can read; for connectors and project API tokens, projectId defaults to the configured project. |
trace_flag_evaluation | read | Evaluate a feature flag on-demand and immediately pull the full E2E OpenTelemetry distributed trace with an ASCII latency waterfall and automated hotspot optimization advice. |
check_and_rollback_flag | write | Evaluate post-toggle drift safety for a flag and trigger an automated circuit-breaker rollback if degraded (or preview with dryRun). With a live rollout plan on the flag in that environment the rollback cancels the plan (removing only its rule) instead of restoring the previous version; the result's rolloutPlan names it. Fails with 409 (code BUSY or ROLLOUT_IN_PROGRESS) when another rollout change is in progress — run it again. maxErrorRateDelta must be above 0 and at most 1, maxLatencyDeltaMs above 0, and windowMinutes above 0 and at most 1440 — the tool rejects other values before calling the API. |
get_stale_flags | read | List stale, inactive, and launch-ready feature flags for a project, including days inactive and automated cleanup advice. |
start_canary_rollout | write | Start a canary rollout of a flag value: creates and starts a persisted rollout plan (canary strategy, listed under Releases in the console) that ramps initialRolloutPercent → targetRolloutPercent in rampStepPercent steps, soaking each stage soakPeriodMinutes. Gates are the flag's pre-canary evaluation error rate / p99 latency plus errorRateGateDelta / latencyGateDeltaMs (never below 2% / 100 ms): an error-rate breach removes the canary rule (autoRollbackOnBreach) or pauses it, a latency breach pauses it. The gates only see evaluations served by flaggr.dev — not api.flaggr.dev or SDK-local evaluation — and a stage with fewer than minSampleSize of them holds until it is advanced with force. The rollout engine advances stages every 5 minutes. Fails with 409 when the flag is disabled, already serves the value, has a live rollout, or its environment needs approval. Use create_rollout_plan for approvals, ring cohorts or RUM guardrails. |
get_canary_status | write | The flag's live (or latest canary) rollout plan: stages, soak remaining, guardrail checks vs the pre-canary baseline, and whether it can advance (a hold says when the gates lack flaggr.dev-served evaluations). Reading it lets the engine progress due stages. |
advance_canary_stage | write | Advance the flag's live canary to its next stage now, once its soak and guardrails pass (force skips both). A breached rollback guardrail aborts it instead; a stage short of flaggr.dev-served evaluations holds unless forced. Stages also advance on their own every 5 minutes unless the canary was started with autoAdvance false. Approval-gated stages need advance_rollout_plan. |
abort_canary_rollout | write | Abort the flag's live canary: cancels its rollout plan and removes its rule, so the flag serves what it did before the canary (edits made since are kept), records the reason and alerts the plan's channels. A failed or rolled-back canary whose rule still serves has the rule removed. |
Targeting, overrides & cohorts
| Tool | Access | What it does |
|---|---|---|
add_targeting_rule | write | Add a targeting rule to a feature flag. A rule matches users on its conditions, and its rolloutPercentage (a whole number from 0 to 100) applies to those. conditions is optional: leave it out for a rule that matches everyone, such as a percentage rollout to all users. A rule with no conditions matches everyone, but data planes from before Flaggr 0.5.0 (https://api.flaggr.dev until it is updated) and @flaggr/sdk local evaluation before 0.5.0 match it to nobody: the match-all condition targetingKey not_equals __flaggr_rollout_match_all__ (see Targeting Rules) serves everyone on every plane, and start_canary_rollout writes it itself. A matching rule serves its value (the flag's default value when it has none). variant names one of the flag's variants, and the rule then serves that variant's value (value can be left out, and a different one is refused, as is a name the flag's variants don't have); on a flag without variants it only names value, which is then required. |
remove_targeting_rule | write | Remove a targeting rule from a feature flag by rule ID. A rollout-<planId> rule of a live rollout plan stays (cancel the plan or abort the canary); a finished plan's leftover rule is removed. |
add_override | write | Add a user-specific value override to a feature flag. Overrides bypass all targeting rules. |
list_cohorts | read | List reusable customer cohorts and dynamic audience segments in a project. |
get_cohort | read | Get cohort definition, audience rules, and static member count by ID. |
create_cohort | write | Create a new reusable customer cohort (static list or rule-based dynamic predicate). |
evaluate_cohort_membership | read | Test whether a user targeting key and evaluation context match an audience cohort. |
Rollout plans & releases
| Tool | Access | What it does |
|---|---|---|
list_rollout_plans | write | List a project's rollout plans (Releases): staged pipelines that ramp a flag value through guarded stages. Shows status, current stage, traffic served and what happens next. Use get_rollout_plan for stages and guardrail verdicts. |
get_rollout_plan | write | Get one rollout plan: stages with soak/approval gates, guardrails, rollback policy, current stage and the last guardrail check (canary vs baseline per check). Reading a plan also lets the engine progress due stages. |
create_rollout_plan | write | Create a draft rollout plan that ramps a flag value through stages, soaking each and checking guardrails (evaluation error rate / p99 latency, traffic ratio, browser RUM SLIs: LCP/INP/CLS p75, JS errors, friction, conversion) with pause or rollback on breach. The flag must already exist in that service and environment (404 FLAG_NOT_FOUND otherwise). Use plans for governed releases — approvals, ring cohorts, RUM guardrails, release KPIs; start_canary_rollout is a one-call shortcut that creates and starts a canary plan gated on the flag's pre-canary error rate / p99. Stages default to the strategy's preset; guardrails default to error rate > 2% → rollback and p99 latency > 100 ms → pause. Start it with start_rollout_plan. |
update_rollout_plan | write | Edit a draft rollout plan's name, stages, guardrails or rollback policy (started plans can't be edited, nor can a draft whose start is awaiting approval — withdraw that change request first). Each list you pass replaces the stored one. |
delete_rollout_plan | write | Delete a rollout plan that isn't running (draft, completed, cancelled, rolled back or failed). Cancel active or paused plans first with cancel_rollout_plan. Refused while the draft's start is awaiting approval (withdraw the change request first) and while a failed, rolled-back or cancelled plan's rule still serves traffic (clear it with abort_canary_rollout and the plan's id as pipelineId). |
start_rollout_plan | write | Start a draft rollout plan: activates stage 1 and serves its traffic share. Project governance may assess risk first — a risky production start (or any start in a protected environment) opens a change request for approval instead (the plan stays draft; starting again returns the same request, and once it is approved START_APPROVED names the request to apply, or withdraw to change the plan), and a policy block fails with a reason; retry with acknowledgePolicy when the policy allows an override. Only one plan per flag and environment can be live (ROLLOUT_IN_PROGRESS names the live one); BUSY, PLAN_CHANGED and 503 answers changed nothing and can be retried in a moment. |
pause_rollout_plan | write | Pause an active rollout plan: it stops advancing and keeps serving the current stage's traffic share. Resume with resume_rollout_plan. |
resume_rollout_plan | write | Resume a paused rollout plan (paused by hand or by a pause-action guardrail breach); the engine re-checks guardrails on its next tick. |
advance_rollout_plan | write | Approve the current stage of an active plan and move to the next one (or complete the plan). Needed for approval-gated or manual stages. Refuses while the stage is soaking, held for samples/traffic, or breached unless force is set. |
cancel_rollout_plan | write | Cancel an active or paused rollout plan. Remaining stages are skipped and the plan's rollout rule drops to 0% — users stop receiving the target value. |
get_rollout_analysis | read | Canary-vs-baseline analysis of a plan's current (or last) stage: the engine's guardrail verdicts (evaluation error rate / p99, traffic ratio, RUM SLIs) and every browser RUM SLI — LCP/INP/CLS p75, JS error rate, friction, conversion — measured canary vs baseline, guarded or not. Use it to decide whether to advance, pause or cancel. |
get_releases_summary | read | Release KPIs from the rollout audit trail for the last N days vs the N days before: auto vs manual stage advances, guardrail breaches by action, rollbacks, mean time to rollback (breach → rollback) and blocked advances. |
estimate_rollout_audience | read | Estimate how many sessions each stage of a rollout would reach, from browser analytics (sessions that carried the flag, else all sessions on the service's sites). Also tells you whether the service has browser RUM data — needed before adding RUM SLI guardrails. |
start_canary_rollout is a one-call shortcut over these plans: it creates and starts a canary-strategy plan whose guardrails are the flag's pre-canary error rate and p99 plus the allowed deltas (never below 2% / 100 ms), and the engine advances it every 5 minutes. get_canary_status, advance_canary_stage and abort_canary_rollout act on the flag's live plan. The gates count only evaluations served by flaggr.dev (api.flaggr.dev and SDK-local evaluation record none), so a stage with too few of them (minSampleSize, default 200) holds until it is advanced with force. Use create_rollout_plan when you need approval gates, ring cohorts or RUM guardrails.
get_rollout_analysis also reports what the RUM trust filters kept out of the stage's browser SLIs, for the canary and the baseline: sessions and events marked untrusted (sent from outside the Site's domain), and sessions and events over a cap. The caps are 5 sessions per client per arm, and 10 samples of each web vital (and of rage and dead clicks) per session. It also reports counted sessions that have no client key (rows written before the ingest identified clients, or by an ingest that couldn't), which the per-client cap can't apply to.
Plan tools turn the API's coded refusals into next steps. BUSY, PLAN_CHANGED and the 503s (APPROVAL_CHECK_UNAVAILABLE, RULE_WRITE_FAILED, UNAVAILABLE) changed nothing and can be retried in a moment. ROLLOUT_IN_PROGRESS names the flag's live plan: cancel it with cancel_rollout_plan or let it finish. PLAN_AWAITING_APPROVAL means the draft's start request is open. While it is pending, withdraw it with DELETE /api/projects/{id}/change-requests/{changeRequestId} (the requester, or an admin of the plan's service and environment) or Withdraw request on the plan's page in the console, then start the plan again. Once it is approved but not applied, apply it with POST /api/projects/{id}/change-requests/{changeRequestId}/apply (an admin of the plan's service and environment; it starts the plan exactly as approved), or withdraw it with the same DELETE; the plan's page offers Approved — apply and Withdraw request for it. A request past its 7-day expiry can only be withdrawn: applying it answers 409 CHANGE_REQUEST_EXPIRED and retires it. start_rollout_plan on such a draft answers START_APPROVED with the same two choices. ROLLOUT_RULE_PRESENT means a failed, rolled-back or cancelled plan's rule still serves: clear it with abort_canary_rollout and the plan's id as pipelineId, then delete the plan. ROLLOUT_RULE_SHADOWED means a rule ahead of the plan's serves everyone (no conditions or condition groups, or only the match-all condition, no schedule, and 100% or no percentage), such as a rule an earlier plan left at 100%, so the plan's rule would reach nobody. The error names each such rule's remove_targeting_rule call: remove the rule, or give it conditions, a schedule or a percentage below 100, then start the plan again. The check comes before any approval is requested. create_rollout_plan needs an existing flag (FLAG_NOT_FOUND) whose key matches [A-Za-z0-9_][A-Za-z0-9._-]*. EXPERIMENT_RUNNING comes back as the API's own message, which names the running or paused experiment on the flag: end it with end_experiment before starting a plan or canary there (experiments have no environment, so this applies in every environment).
Experiments & bandits
| Tool | Access | What it does |
|---|---|---|
list_experiments | read | List all experiments in a project. |
create_experiment | write | Create a new A/B test experiment on a feature flag. |
start_experiment | write | Start a draft experiment (begins traffic allocation). A running experiment serves its variants for the flag in every environment the flag exists in, so starting needs write on the flag in each of them; it is refused while any of them requires approval (409 APPROVAL_REQUIRED, with the environments — experiments can't go through a change request yet; 503 APPROVAL_CHECK_UNAVAILABLE when that can't be checked) and while a rollout plan is live on the flag (409 ROLLOUT_IN_PROGRESS). |
end_experiment | write | End a running or paused experiment: it stops serving its variants, and its results (per-variant metrics, significance, winner and recommendation) are computed from the events it recorded. Roll a winning value out by updating the flag. |
list_bandit_experiments | read | List active Multi-Armed Bandit experiments, with optional filtering by project, service, or flag. |
create_bandit_experiment | write | Initialize an adaptive Bayesian Multi-Armed Bandit experiment (Thompson Sampling or Epsilon-Greedy) on a feature flag. |
get_bandit_status | read | Get real-time Multi-Armed Bandit experiment status, trials, conversions, Beta distributions, and posterior winning probabilities. |
reallocate_bandit_traffic | write | Dynamically rebalance feature flag variant weights according to Bayesian Thompson Sampling or Epsilon-Greedy, and auto-rollout winner if confident. |
record_bandit_reward | write | Ingest an evaluation trial and optional conversion event for a bandit variant to update Beta priors and conversion rates. |
Bandits are experimental. A bandit experiment is held in one server instance's memory, not in the database: a call that reaches another instance, or comes after a restart, gets 404 (Bandit experiment "…" not found), and the trials recorded so far are lost. For a test that has to last, use create_experiment, which is stored.
Alerts & incidents
| Tool | Access | What it does |
|---|---|---|
list_alert_channels | read | List notification channels (Slack, Discord, webhook, PagerDuty, email) a project's alert rules and rollout plans can notify, including channels inherited from its organization. Webhook URLs, secrets and routing keys are masked. |
create_alert_channel | write | Create a project notification channel. Pass the destination for its type: webhookUrl (slack, discord), url + optional secret (webhook), routingKey (pagerduty) or recipients (email). Verify it with test_alert_channel. |
update_alert_channel | write | Update a project notification channel's name, type, enabled state or destination. Destination fields merge into the stored config, so you can rotate one key (e.g. secret) without resending the rest. Org channels need update_org_alert_channel. |
delete_alert_channel | write | Delete a project notification channel. Alert rules that reference it stop notifying it. Org channels need delete_org_alert_channel. |
test_alert_channel | write | Send a real test notification through a channel (project or inherited org channel) to verify its configuration. |
list_org_alert_channels | read | List an organization's shared notification channels (inherited by all its projects). Destinations are masked. |
create_org_alert_channel | admin | Create a notification channel shared by every project in an organization (requires org admin). Pass webhookUrl (slack, discord), url + optional secret (webhook), routingKey (pagerduty) or recipients (email). |
update_org_alert_channel | admin | Update an organization channel's name, type, enabled state or destination (requires org admin). Destination fields merge into the stored config unless replaceConfig is set. |
delete_org_alert_channel | admin | Delete an organization notification channel; every project in the org stops using it (requires org admin). |
test_org_alert_channel | admin | Send a real test notification through an organization channel to verify its configuration (requires org admin). |
list_alert_rules | read | List a project's alert rules: condition, threshold, window, cooldown, severity, the channels they notify and the latest scheduled check (rules are evaluated every 5 minutes; 'no data' means fewer than 20 evaluations reached flaggr.dev in the window; legacy grpc_errors/cache_hit_rate rules are not evaluated). |
create_alert_rule | write | Create a project alert rule. Enabled rules are checked every 5 minutes against stored evaluation metrics and audit events: a breach opens an incident and notifies the rule's channels once; an Open incident auto-resolves when the condition clears. Incidents — see list_incidents. A project can have at most 100 enabled rules (create more with enabled: false). Rules on the shared demo/showcase can only be managed by project members. |
update_alert_rule | write | Update an alert rule's condition, threshold, window, severity, channels (channelIds replaces the list) or enabled state. Disabling a rule resolves its unresolved incidents; enabling one is refused once the project has 100 enabled rules. |
delete_alert_rule | write | Delete an alert rule; it stops firing and its unresolved incidents are resolved (noted in their timelines). Past incidents stay in list_incidents. |
list_incidents | read | List alert firings as incidents (Open → Investigating → Resolved) with severity, value vs threshold, assignee and note count, newest first. state, severity and ruleId filter server-side before the limit, so older matching incidents are found too. |
get_incident | read | Get one incident (alert firing): state, assignee, the rule behind it, impact (top flag, browser sessions/errors in the window), metric series and the timeline of notes, state changes and assignments. |
update_incident | write | Move an incident through its workflow and/or assign it: investigating acknowledges it, open un-acknowledges it, resolved resolves the firing (final — resolved incidents can't be reopened). Each change is added to the timeline. A state change and an assignment sent together apply together: if the incident was resolved meanwhile (e.g. auto-resolved by the evaluator) the whole update is refused with 409 and nothing is recorded, the assignment included. An assignment on its own also applies to a resolved incident. |
add_incident_note | write | Add a note to an incident's timeline — findings, mitigation steps, links. Needs project membership (not available from the shared demo's public access). |
list_incident_notes | read | List an incident's timeline: notes, state changes and assignments, oldest first. |
Unless the credential can manage the owner's settings (admin tier, and an admin or owner role in the project or organization), channel secrets come back as [redacted]. Pass [redacted] back unchanged to keep a stored secret. Changing where a channel sends it — its URL, recipients or type — while keeping the placeholder needs that same access; otherwise pass the real secret again. Alert rules are evaluated every 5 minutes from the evaluations flaggr.dev records, and new rules can't use the legacy grpc_errors and cache_hit_rate conditions; see Alerting.
Overview & browser analytics
| Tool | Access | What it does |
|---|---|---|
get_project_overview | read | Project Overview KPIs for a window vs the equal window before it: active flags, evaluations, error rate, active rollouts, users exposed (browser sessions carrying a flag) and policy violations, plus browser web-vital p75s and a control-vs-treatment exposure series. Optionally limited to one team's flags. Start here for 'how is this project doing?'. |
get_evaluation_trends | read | Evaluation volume per flag × service × environment as a bucketed series (hourly for 24h, daily for 7d/30d) with the previous window's total for period-over-period change. Use to spot busy, growing, declining or newly silent flags. |
get_flag_exposure | read | Users exposed per flag: distinct browser-analytics sessions stamped with the flag key on the sites of the flag's service, for the window and the window before it. Sessions, not signed-in users. Needs browser analytics (Postgres) and sites linked to services. |
get_project_health_history | read | Hourly health score for the last 24 hours from stored evaluation history (score = 100 − 50 × error fraction − min(avg latency ms ÷ 10, 50)), with per-service scores and the weakest flags each hour. Use to find when a project's flag health dipped; get_project_health gives the current snapshot. |
estimate_flag_audience | read | Who received a flag: browser sessions on the flag's service sites (in its environment) carrying the flag, split by served value, country, browser, device and OS. Filters narrow it like a targeting rule; rolloutPercentage estimates the sessions a rollout at that % would reach. Use before widening targeting or a rollout. |
get_browser_analytics_overview | read | Site traffic KPIs from browser analytics — visitors (distinct sessions), pageviews, average session duration and bounce rate — for the window vs the previous one, with a small time series. Use for traffic health of a site. |
get_web_vitals | read | Real-user Core Web Vitals for a site: p50/p75/p95 and good / needs-improvement / poor split for LCP, INP, CLS, FCP and TTFB, top pages / browsers / devices / countries, render-stage timing and the slowest render traces. For a metric's trend or a trace's waterfall use drilldown_browser_analytics; per-variant vitals: get_flag_rum_report. |
list_browser_issues | read | Grouped browser JavaScript errors for a site: per issue occurrences, sessions, unhandled count, severity, first/last seen, top browsers/pages, the flag variants present when it fired and the release it first appeared in. Use to triage client errors and spot flag-correlated ones. |
drilldown_browser_analytics | read | Drill into one slice of a site's browser analytics: kind=vital (one metric's percentiles, rating split, hourly p75 trend, slowest browsers/pages, previous-window delta), kind=dimension (a browser/device/country/referrer/page segment's traffic, vitals and flags), kind=flag (a flag's variants by pageviews, sessions, LCP, CLS) or kind=render (one render trace's stages, waterfall issues, suspect flags and release comparison). |
query_browser_segments | read | RUM metrics for a site grouped by any of page, browser, browser_version, device, os, flag, variant — sessions, JS error rate, friction (rage/dead clicks per 1k sessions), conversion and LCP/INP/CLS/TTFB/FCP p75 with rating counts — with page/device/browser/version/flag filters, optional previous-window comparison and trend. Use to find which pages, browsers or versions regress. |
get_flag_rum_report | read | Per-flag real-user impact on a site from browser analytics: each variant's sessions, JS error rate, friction, conversion and LCP/CLS/INP/TTFB p75, a treatment-vs-control status (healthy / warning / degraded / insufficient) with evidence, and the degraded flag × browser × page and flag × browser-version segments. Use to judge whether a flag variant hurts users; get_flag_rum_impact covers before/after drift around a toggle. |
export_browser_analytics | read | Export a site's browser analytics as rows — dataset=segments (RUM metrics grouped by page, browser, … with filters) or dataset=flags (one row per flag variant with RUM status and worst segment). Returns the first maxRows rows inline as JSON records or CSV plus the full export's size and a download URL, so large exports don't flood the context. |
list_mobile_processing_reports | read | Inspect native processing reports with stage timings, counts and outcomes; filter by exact report UUID. Separate from crash issues. |
get_mobile_analytics_summary | read | Mobile app analytics for a site/app id: total events, active installs, signed-in users, scan funnel (started → completed), searches, saved products, top events and platforms. Use for mobile app usage questions. |
get_site_session_counts | read | Browser-analytics sessions started per site of a project in the window, with the previous window — the Sites tab's sessions column. Use to compare traffic across sites. |
list_recent_browser_events | read | The newest raw browser-analytics events for a site (pageviews, web vitals, errors, clicks, custom events) with URL, browser, country and flag stamps. Use to confirm a site's snippet/SDK is sending data or to inspect what just arrived. |
Issues & server telemetry
| Tool | Access | What it does |
|---|---|---|
list_issues | read | The project's errors grouped into issues, Sentry-style and across platforms: browser errors (every Site of the project) and server errors (POST /api/ingest/server-events) grouped by fingerprint, with status (unresolved, resolved, ignored, regressed), events, users, first/last seen, culprit and release. Filters: source, status, range (1h to 30d), search query; sorts by last seen, first seen, events or users. |
get_issue | read | One issue in full: status and culprit, events and users, the flag variants its events carried (which flags and variants were on when it fired), release / environment / location / browser / service breakdowns, the event trend, one event's in-app stack frames and breadcrumbs, and the recent events. Takes the source and fingerprint that list_issues prints; 404 ISSUE_NOT_FOUND when the issue has no events in the range. |
update_issue_status | write | Resolve (optionally in a release; an issue that fires again becomes regressed), ignore (for ignoreForHours, or until changed) or reopen up to 100 issues at once, each named by source and fingerprint. |
list_server_events | read | Backend errors and request spans a project's services reported (POST /api/ingest/server-events), newest first, with message, stack, route, status code and duration. Filter by kind, fingerprint and window. |
get_server_event_summary | read | Window aggregates of a project's server telemetry: error and span counts, the top error fingerprints, and span p50/p95 durations. |
get_performance | read | Server transactions (spans without a parent: the requests the project's services served), busiest first, with requests, throughput, p50 / p75 / p95 / p99 latency and failure rate over 1h, 24h or 7d, optionally for one service. Request counts are estimates from sampled traces. With transaction ("METHOD route"), one transaction's stats, duration histogram, slowest traces and recent failures with their trace ids; 404 TRANSACTION_NOT_FOUND when it had no requests in the range. |
get_server_trace | read | One trace as a waterfall: its spans in tree order, indented by depth, with op, service, start offset, duration and status; the errors reported in it (with fingerprints for get_issue, source server); and the browser page loads whose requests started it. Spans are kept 7 days and sampled by trace (404 TRACE_NOT_FOUND). Not the same as get_trace, which reads flag evaluation traces. |
Flag analytics & RUM impact
| Tool | Access | What it does |
|---|---|---|
get_flag_metrics | read | Get evaluation analytics for a flag: volume, realtime evals/sec, error rate, latency percentiles, reason/value breakdowns, time series. |
get_project_health | read | Get aggregated project health: overall score, per-service breakdown, top issues, total evaluation volume. |
get_evaluation_heatmap | read | Get project-wide evaluation heatmap: usage (evals, evals/min, error rate, latency) for every flag x service cell, including zero-evaluation flags. |
get_flag_toggle_impact | read | Analyze post-toggle safety, drift, and performance impact for a feature flag: compares before vs after error rate, P99 latency shift, traffic volume ratio, and provides an automated health assessment (healthy, warning, degraded, insufficient_data) with rollback guidance. |
get_sdk_analytics | read | Get client SDK performance telemetry: L1 cache hit ratios, microsecond evaluation resolution latencies, real user Core Web Vitals (LCP, CLS, INP, FCP, TTFB), and client errors correlated with active feature flags. Scoped to a project or a service: projectId defaults to the configured project when serviceId is omitted; with neither, only a credential bound to a single project is answered (otherwise 400). |
explain_flag_evaluation | read | Run a step-by-step diagnostic evaluation explaining clause-by-clause why a user context resolved to a specific variant or default value. |
simulate_flag_targeting | read | Run a counterfactual blast-radius simulation comparing current baseline flag vs proposed candidate flag across synthetic user cohorts. |
get_flag_rum_impact | read | Inspect Real User Monitoring (RUM) Core Web Vitals drift, per-variant latencies (INP, LCP, CLS, TBT), and operational health assessment for a feature flag. |
optimize_flag_web_vitals | write | Trigger automated closed-loop optimization based on real user Core Web Vitals (INP, LCP, CLS, TBT): reallocates 100% traffic to superior variant, rolls back on degradation, or activates companion performance flags. The tool always POSTs, which connectors need write access for — even with dryRun: true (a preview that doesn't change the flag). |
get_flag_component_hotspots | read | Analyze React component performance, render storms, frame drop risks, thread-blocking renders, and variant regressions correlated with a feature flag. projectId defaults to the configured project when serviceId is omitted. |
get_flag_frustrations | read | Inspect UX frustration signals (rage clicks, dead clicks, friction scores) and flight recorder diagnostic breadcrumbs correlated with a feature flag. projectId defaults to the configured project when serviceId is omitted. |
Sites
| Tool | Access | What it does |
|---|---|---|
list_sites | read | List all onboarded sites and web properties within a service or project, with optional filtering by linked feature flag. |
get_site | read | Get full configuration details of an onboarded site or web property including domain, environment, linked flags, and settings, plus the a.js analytics tag to install. |
create_site | write | Onboard a new site or web property to measure Core Web Vitals, track client telemetry, and link feature flags. The server generates the site ID (site_…), which keys the site's analytics and goes in the a.js script tag's data-site-id; the optional slug is only a label, unique within the service. Reserved slugs (e.g. default, flaggr-marketing, flaggr-showcase, project IDs) are refused with 400 SITE_SLUG_RESERVED, and a slug the service already uses with 409 SITE_SLUG_TAKEN. |
update_site | write | Update an existing site's domain, description, environment, or linked flags. |
delete_site | write | Delete an onboarded site or web property by its site ID. |
link_flag_to_site | write | Link a feature flag to a site or web property for client-side telemetry tracking and evaluation. |
unlink_flag_from_site | write | Unlink a feature flag from a site or web property. |
get_flag_linked_sites | read | List all sites within a service that are currently linked to a specific feature flag. |
get_site_health | read | Get comprehensive real-time site health score (0-100), Core Web Vitals (P75 LCP, INP, CLS), client error impact, and linked flag status. |
check_site_guardrails | write | Check site-level guardrails across linked feature flags and optionally execute automated self-healing mitigations (traffic reallocation away from degraded variants, snapshot rollback, or disabling). |
create_site: the server generates the site ID (site_…), which goes in the browser analytics tag, <script src="https://cdn.flaggr.dev/a.js" data-site-id="site_…" defer></script> (get_site and create_site print the tag with the site's ID, and the CSP origins it needs); slug is an optional label unique within the service. A reserved slug is refused with 400 SITE_SLUG_RESERVED and a duplicate with 409 SITE_SLUG_TAKEN. The siteId parameter of the other site tools is that ID, not the slug. check_site_guardrails lists blocked mitigations with their code (APPROVAL_REQUIRED, ROLLOUT_IN_PROGRESS, FORBIDDEN, BUSY). get_sdk_analytics defaults projectId to the configured project when serviceId is omitted.
Health
| Tool | Access | What it does |
|---|---|---|
check_system_health | read | Check the overall health of the Flaggr platform. |
get_flag_health | read | Get health metrics for a specific flag (error rate, latency, evaluation volume, staleness). |
get_evaluation_stats | read | Get evaluation statistics for a service (evaluation counts, latency percentiles, error rates). |
get_flag_impact | read | Analyze the impact of toggling a flag -- see how many evaluations would be affected. |
Audit & history
| Tool | Access | What it does |
|---|---|---|
get_audit_log | read | List audit log entries for a project with deep path-scoped diffs (e.g. targeting[1].percentage: 50 -> 75) and change summaries. |
get_flag_history | read | Get version history for a flag with per-version deep diffs (path, old/new values, human-readable summary). |
Local server only (stdio)
The local server adds three tools for its own sign-in; the hosted connector signs in with OAuth instead.
| Tool | What it does |
|---|---|
get_auth_status | Check current authentication status and project configuration for Flaggr MCP. |
login | Authenticate the Flaggr MCP server via browser OAuth flow or by supplying an API token directly. |
logout | Remove credentials from the Flaggr MCP server and local config. This doesn't revoke the token: it stays valid until it expires or is revoked in the dashboard (Profile → Personal access tokens). |
With a project API token, the server makes that token's project its default project for the session. A project token reaches only its own project, so this replaces default_project_id from ~/.flaggr/config.json in memory (the file isn't changed), and the server logs the switch to stderr.
MCP Resources
Agents can read context directly via dynamic resource URIs:
ui://flaggr/console— The Flaggr app (MCP Apps HTML resource)flaggr://auth/status— Active token preview, current project, and connection statusflaggr://projects— List of all accessible projectsflaggr://project/{slug}/flags— Feature flags in a projectflaggr://flag/{key}/health— Flag health statusflaggr://flag/{key}/toggle-impact— Post-toggle safety and drift analysisflaggr://site/{siteId}— Site details, domain and linked flags
MCP Prompts
The server provides pre-packaged prompt templates for complex flag management tasks:
verify_toggle_safety
Prompts the agent to inspect the safety of a recent flag toggle:
Verify post-toggle safety for flag "checkout-v2" in service "web-app".The agent calls get_flag_toggle_impact, analyzes before/after error rates and P99 latencies, and proposes rolling back if health is degraded.
gradual_rollout
Guides an agent through a staged percentage rollout: add_targeting_rule without conditions (a rule that matches everyone) at rolloutPercentage: 5, then update_flag raising that rule's percentage (5% → 25% → 50% → 75% → 100%), checking get_flag_health at each step before advancing. Data planes from before Flaggr 0.5.0 (https://api.flaggr.dev until it is updated) match a rule without conditions to nobody, so the prompt also tells the agent to give the rule the match-all condition (targetingKey not_equals __flaggr_rollout_match_all__), which serves everyone on every plane.
ab_test_setup
Designs an experiment with treatment and control variants, sets traffic allocation, and configures outcome metrics.
targeting_strategy
Designs a targeting strategy for a flag from user attributes and a stated goal.
Autonomous Agent Workflow Examples
Example: Verifying a Production Flag Toggle
Ask your assistant:
"Check if toggling
new-payment-enginein production was safe or if there was any error drift."
The assistant invokes:
{
"tool": "get_flag_toggle_impact",
"arguments": {
"flagKey": "new-payment-engine",
"serviceId": "checkout-service",
"environment": "production"
}
}The MCP server responds with:
============================================================
FLAG TOGGLE IMPACT REPORT: new-payment-engine
============================================================
Status: [HEALTHY]
Latest Toggle Event:
- Transition: false -> true
- Actor: lead-dev@flaggr.dev
- Timestamp: 2026-09-12T08:00:00.000Z
- Propagation Latency: 38ms
Before vs After Comparison (±30m window):
┌──────────────────────┬─────────────┬─────────────┬────────────────┐
│ Metric │ Before │ After │ Delta / Ratio │
├──────────────────────┼─────────────┼─────────────┼────────────────┤
│ Evaluations │ 2450 │ 2480 │ 1.01x │
│ Errors │ 1 │ 1 │ +0 │
│ Error Rate │ 0.04% │ 0.04% │ +0.00% │
│ Avg Latency │ 1.35ms │ 1.34ms │ - │
│ P99 Latency │ 3.80ms │ 3.75ms │ -0.05ms │
└──────────────────────┴─────────────┴─────────────┴────────────────┘
Automated Recommendation:
Healthy: Post-toggle metrics are stable with no significant error or latency regression.
============================================================The assistant summarizes the findings and confirms the deployment is stable.
Next Steps
- REST API Reference — Core Flaggr REST endpoints
- Personal Access Tokens — Account-level tokens for the local server, the CLI and Terraform
- Flag Health Guide — Post-toggle safety and drift diagnostics
- OpenFeature SDKs — Evaluate flags in your application code