Feature flag service exposing a flag store to AI agents over the Model Context Protocol, with HTTP API and MCP server support
Flagpole demonstrates solid tool design with clear verb-based naming (list_, get_, evaluate_, toggle_, upsert_), complete input schemas using JSON Schema with type definitions, and consistent descriptions. All 5 tools have descriptions (avg ~90 chars, within baseline 34-392 range). Parameters are typed and described. However, output schemas are not explicitly documented in the code, responses are inferred from the implementation (e.g., 'flags' array, 'enabled' boolean, 'version' integer). Error handling is basic: the code returns raw store errors (ErrNotFound, ErrStaleVersion) without recovery guidance. No tool annotations (readOnlyHint/destructiveHint) despite clear risk profiles (3 READ_ONLY, 2 WRITE). Parameter descriptions lack format constraints (e.g., 'percentage' accepts 0-100 but this is not stated in the description text, only in the code comment). Composition is clean, each tool has one responsibility, and output includes chaining IDs (key, version) needed for follow-up calls.
Evaluate a flag for a given context and explain the outcome (kill switch, rule match, rollout bucket).
Get one feature flag by key, including its rules, rollout and version.
List every feature flag with its state, targeting rules and rollout percentage.
Turn a feature flag on or off. Rules and rollout settings are kept as they are.
Create a feature flag, or update its description, state and rollout percentage if it already exists.
Output schemas not documented. Code returns structured objects (flags array, enabled boolean, version integer, evaluation result) but no formal schema definition is visible. LLMs cannot plan downstream calls without knowing response structure.
Tool annotations missing. toggle_flag and upsert_flag are destructive (WRITE risk) but lack destructiveHint annotation. list_flags, get_flag, evaluate_flag are read-only but lack readOnlyHint. Annotations help LLMs reason about safety and retry logic.
Error handling lacks recovery guidance. Raw store errors (ErrNotFound, ErrStaleVersion) are returned without actionable context. E.g., 'flag not found' should suggest 'Call list_flags() to see available flags' or 'Check the flag key spelling'.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 62 | 2025-06-18+ | v2 |
Parameter constraints not stated in descriptions. 'percentage' parameter accepts 0-100 (per code comment) but the description text does not specify this range. LLMs cannot read code comments, they rely on description text for constraints.
evaluate_flag context parameter type is map[string]string but description says 'object'. LLMs expect 'object' to mean arbitrary JSON; the string-only constraint should be explicit: 'object with string values (e.g., {"id": "user-123", "region": "us-west"})'.