[MCP reslice 2/2] @churnkey/mcp tool definitions#25
Merged
Conversation
This was referenced Jun 16, 2026
355857a to
e426a51
Compare
f7bae95 to
cc9d339
Compare
e574e11 to
335ca11
Compare
confirmLiteral(), the shared confirm-token guard the mutating tool definitions gate their writes behind.
list/get_blueprint, create_blueprint, granular draft edits (update_blueprint_draft/ _step/_offer, edit_survey_structure, add/remove_blueprint_step), and the confirm-gated publish_blueprint. Draft-only; publish is the single live gate.
list_segments, list_segment_attributes, create_segment_flow, and the confirm-gated reorder/set_enabled/update_filter/archive on live segment config.
get_flow_metrics (per-flow performance, boosted revenue, outcomes, sample-size warning) and the shared filter/query-builder coverage used by the session and recovery analytics tools.
Recovery blueprint config CRUD, the clone template library, dashboard-parity email/SMS/offer/audience editing, running-instance reads + engagement, and the irreversible stop_recovery_campaign. Rolls up the XDEV-2332 tools + parity follow-up.
list/create/start/pause/complete_ab_test, get_ab_test_metrics (per-arm significance, n>=30 rule), and the confirm-gated pick_ab_test_winner.
get_dns_config, set_hosted_subdomain, add/remove_custom_domain, check_domain_status with the exact customer-side records surfaced in every response.
…335) get/update_stripe_settings (per-setting descriptions + recommendations, conflict explanations) and get/update_adaptive_offers (strategy presets, guardrails, Intelligence gating, compound-scope rule).
The attributed workspace audit trail (summaries, source filtering for agent vs dashboard actions, before/after diffs) under account.audit_log.read.
Assemble allTools() from every family above. Sweep commit — reconciles the tree to the tool-definitions layer exactly.
Add get_account (no scope required): org / user / entitlements / granted scopes / effective mode — registered first to nudge agents to orient before acting. Backed by GET /v1/data/account. Introduce a `modeScoped` tool flag that drives (a) a "Mode: LIVE|TEST" echo on results and (b) a mode-sensitivity note appended to the description (data vs traffic flavor by readOnlyHint). Applied ONLY to list_sessions / aggregate_sessions — the sole mode-partitioned surface. Recovery analytics, flow metrics, and DSR are mode-independent server-side, so they are deliberately left unmarked. README + CHANGELOG updated to match.
e234a8a to
e7ff2b4
Compare
Generic MCP OAuth clients (Claude.ai, ChatGPT, Claude Code) discover which scopes to request from the resource's RFC 9728 Protected Resource Metadata. The PRM omitted `scopes_supported`, so those clients began the authorization request with an empty scope set, which the authorization server rejects with "At least one scope is required" — blocking OAuth login entirely for every generic client. Only the SDK CLI was unaffected (it sends DEFAULT_SCOPES explicitly via `churnkey auth login`). Echo DEFAULT_SCOPES (the full supported set, matching the AS metadata's scopes_supported) from the PRM so clients know what to request. Add a regression test asserting the live PRM advertises scopes. This affects prod (mcp.churnkey.co) and dev (mcp-dev.churnkey.co) identically — both PRMs were missing the field. Claude-Session: https://claude.ai/code/session_01HJRLEbMuREpbVfyNeMoP6h
jordancardwell
approved these changes
Jul 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
MCP reslice 2 of 2 for
@churnkey/sdk— stacked on #24[MCP reslice 1/2]transport + OAuth client (merged). Together the two PRs reproduce the #23 MCP Overhaul byte-for-byte, re-sliced into reviewable layers — plus one deliberate fix on top (MCP OAuth login for generic clients; see “Included fix” at the bottom).This PR is the tool surface of the
@churnkey/mcpserver: every tool definition (thin, well-described wrappers over the/v1/dataAPI), thetools/index.tsregistry, and the per-tool test suites. Authorization is enforced server-side by the OAuth scopes from reslice 1/2 — the tools just declare and call.Tool families in this PR
list_sessions,aggregate_sessions,get_flow_metricslist_payment_recoveries,aggregate_payment_recoverieslist_blueprints,get_blueprint,create_blueprint,update_blueprint_draft/_step/_offer,edit_survey_structure,add/remove_blueprint_step,publish_blueprintlist_segments,list_segment_attributes,create_segment_flow,reorder_segments,set_segment_enabled,update_segment_filter,archive_segmentget/update_stripe_settings,get/update_adaptive_offersget_dns_config,set_hosted_subdomain,add/remove_custom_domain,check_domain_statuslist/get/clone_recovery_blueprint,update_recovery_email/_email_offers/_sms,add/remove_recovery_email,update_recovery_audience,list_recovery_audience_attributes,set_recovery_blueprint_enabled,publish_recovery_blueprint,list_recovery_campaigns,get_recovery_campaign_messages,get_recovery_engagement,stop_recovery_campaignlist/create/start/pause/complete_ab_test,get_ab_test_metrics,pick_ab_test_winnerget_audit_logdsr_access,dsr_deleteget_accountRolls up these (now-closed) per-feature PRs
The overhaul squashed a series of standalone tool PRs; this reslice carries their tool-layer content forward:
get_flow_metrics(XDEV-2331)get_audit_log(audit-trail read surface)(OAuth/per-user auth from #15 / XDEV-2334 and the HTTP transport from #10 live in reslice 1/2, #24.)
Added since the reslice
get_account+ effective-mode visibility (commitecdb80f): a no-scopeget_accounttool (org / user / entitlements / granted scopes / live-or-test mode) registered first so agents orient before acting; plus amodeScopedflag that echoesMode: LIVE|TESTand a mode-sensitivity note onlist_sessions/aggregate_sessions— the only mode-partitioned surface. Pairs withGET /v1/data/accountin churnkey-api #889.Verification
tscclean,tsupbuild clean.Supersedes: the tool portion of #23 (and #6, #16–#22).
🤖 Generated with Claude Code
Included fix — MCP OAuth login for generic clients (folds in the former #29)
Discovered while running the MCP feature end-to-end against dev: generic MCP OAuth clients (Claude Code, Claude.ai, ChatGPT) could not complete login — the
/authorizestep returned "At least one scope is required."Root cause: the RFC 9728 protected-resource metadata served by the MCP HTTP server (
packages/mcp/src/http.ts) omittedscopes_supported. Clients that discover scopes from the PRM therefore began the authorization request with an empty scope, which the authorization server rejects. The SDK CLI was unaffected (it sendsDEFAULT_SCOPESexplicitly).Fix (commit
a696bde): the PRM now advertisesDEFAULT_SCOPES. Confirmed against both live prod (mcp.churnkey.co) and dev (mcp-dev.churnkey.co) metadata; adds a regression test that boots the real server and asserts the PRM advertises scopes. This is the one intentional delta on top of the byte-for-byte overhaul reproduction.Server-side companion (defense-in-depth): churnkey-api#928 makes the
/authorizeendpoint default an omitted scope (RFC 6749 §3.3) instead of hard-rejecting. Independent review/merge — not required for this fix.Deploy note: the PRM is served by the hosted MCP server (Elastic Beanstalk), built from this repo via
ops/mcp/deploy-mcp.sh dev|prod.