Skip to Content
MCP / AITool catalog

MCP — Tool Catalog

All tools require a valid Cognito access token with a tenant_id claim. No tool accepts tenant_id as a parameter. Tenant context is always from the JWT.


Tenants

ToolPermissionDescription
create_tenant(name, slug?, billing_provider?)(authenticated)Create a new tenant. Caller becomes owner. Provisions Stripe customer + subscription and seeds system roles atomically. No credit is applied — see the note below. billing_provider (“stripe” or “copebit”) only takes effect for a caller holding platform:billing:write; an ordinary caller supplying it gets 403, not a silent fallback.
list_my_tenants()(authenticated)List all tenants the calling user is a member of, with role and last-seen per tenant.
get_tenant()tenant:settings:readFetch current tenant metadata (name, slug, tier, status, features map).
update_tenant(name?, slug?)tenant:settings:writeUpdate name or slug. Slug rename is transactional (old slug released, new slug reserved atomically).
soft_delete_tenant(confirm: str)tenant:deleteOwner only. Initiates 30-day soft-delete grace period. Cancels Stripe subscription and revokes all API keys.
transfer_owner(new_owner_sub)tenant:transfer:ownerAtomic owner role swap. Both the current and new owner must be active members.
check_tenant_name(name)(authenticated)Check whether a slug is available and not reserved.
list_tenant_features()tenant:settings:readReturn the features map (hubspot, slack, apn, etc.) with current enabled/disabled state.
set_tenant_feature(feature, enabled: bool)tenant:features:write (owner, admin)Toggle a feature flag. Disabling preserves all data. Emits FEATURE_TOGGLED audit event.

tenant:features:write is currently held by owner and admin roles — see Roles.

No free-credit balance is created on tenant creation — see “Free credit” in Metering.


Members and Invites

ToolPermissionDescription
list_members()tenant:members:readList all active members with their roles and last-seen timestamps.
change_member_role(sub, new_role)tenant:members:role:writeChange a member’s role. Cannot promote to or demote from owner role.
remove_member(sub)tenant:members:removeRemove a member from the tenant. Owner cannot be removed. Revokes the removed member’s API keys.
create_invite(email, role)tenant:members:inviteSend an email invitation. Subject to rate limits: 50 pending invites per tenant, 10 per hour, 5 to the same email per 7 days.
list_invites()tenant:members:readList all pending invitations.
revoke_invite(sub)tenant:members:inviteDelete a pending invitation.
resend_invite(sub)tenant:members:inviteResend a pending invitation email.

Users (self-service)

ToolPermissionDescription
get_my_profile()(authenticated)Return the calling user’s profile, active memberships, and default tenant.
update_my_profile(name?, picture?)(authenticated)Update display name or profile picture URL.
delete_my_account(confirm: str)(authenticated)GDPR self-deletion. Returns 409 if the user is the owner of an undeleted tenant. Anonymises email in all logs.
select_active_tenant(target_tenant_id)(authenticated)Not supported over MCP. The parameter is target_tenant_id, not tenant_id, and the tool always returns {"error": "NOT_SUPPORTED", ...} directing the caller to the web UI — it does not re-issue a token. Use the app’s tenant switcher instead.
export_my_data()(authenticated)Enqueue a GDPR data export job. Emits account.gdpr_export_ready notification with presigned S3 URL when done.
get_my_export_status(job_id)(authenticated)Poll the status of an in-flight export job.

Grants

ToolPermissionDescription
list_grants()tenant:grants:readList all per-membership grants in the current tenant.
get_grant(sub)tenant:grants:read (own grant readable by self)Fetch a specific member’s grant.
set_grant(sub, allowed_features?, allowed_regions?, monthly_budget_usd?, monthly_token_cap?, rate_limit_rpm?)tenant:grants:writeCreate or replace a member’s grant. Grants can only restrict — they cannot grant more than the member’s role allows.
revoke_grant(sub)tenant:grants:writeRemove a member’s grant override, returning them to role defaults.

API Keys

ToolPermissionDescription
create_api_key(name, scopes, expires_in_days?)tenant:keys:writeCreate an API key. The raw key is returned once and never stored in plaintext.
list_api_keys()tenant:keys:read (owner/admin)List API keys with prefix, scopes, status, and expiry. Matches the REST route.
revoke_api_key(prefix)tenant:keys:write (creator or admin+)Revoke an API key immediately.
rotate_api_key(prefix)tenant:keys:writeIssue a new key with a 7-day grace period during which both old and new keys are valid.

Billing

ToolPermissionDescription
get_billing_summary()tenant:billing:readCurrent subscription status, usage this billing period, and next invoice estimate. There is no free-credit balance to report — see Metering.
list_invoices(limit?)tenant:billing:readRecent invoices with amounts and download links.
open_billing_checkout(provider?)tenant:billing:writeStart a new Stripe Checkout session.
open_billing_portal()tenant:billing:writeGenerate a Stripe Customer Portal session URL.
get_usage_breakdown(period?)tenant:billing:readUsage by metering dimension for the specified period (default: current month). Agentic Sales Manager and APN Sync usage currently reads back as 0 — see Metering.

Cancellation is an organisation-level act (one org, one subscription) — there is no tenant-level cancel tool. Use cancel_org_subscription(org_id) (org:billing:write, org-admin of that org, or a platform admin) to schedule the org’s Stripe subscription to cancel at the end of the current billing period.


Notifications

ToolPermissionDescription
get_my_notification_preferences()(authenticated)Return your global preferences (enabled_categories, bounce_state, unsubscribe_token) together with your per-tenant category_overrides for the current tenant.
update_my_notification_preferences(categories: {category: bool}, scope: "global" or "tenant")(authenticated, self)Enable or disable notification categories. Always-on categories are ignored.
list_notification_categories()(authenticated)Full catalog of every notification category with description, default on/off, and always-on flag.
send_test_notification(category)tenant:notifications:write:selfSend a test email to yourself for the specified category.
disable_notification_category(category, scope: "global" or "tenant")(authenticated)Disable a specific category, as an in-app preference toggle — distinct from the public one-click email unsubscribe link.
unsubscribe_all(scope)(authenticated)Disable all non-always-on categories.
list_notification_subscribers(category?)tenant:notifications:read (admin+)Show which members of the current tenant are subscribed to each category.
list_notification_log(before?, category?, limit?)tenant:notifications:audit:read (admin+)Tenant-wide notification send log, paginated. Every logged entry currently has status: "sent" — there is no producer for any other value, so no status filter is exposed.
re_verify_my_email()(authenticated)Send a delivery-check email to re-enable sending after a hard bounce; a no-op unless the account is currently hard_bounce (never re-sent to a complaint address).

Audit

ToolPermissionDescription
list_audit_events(before?, type?, actor?, limit?)tenant:notifications:audit:readPaginated audit log for the current tenant.
get_audit_event(event_id)tenant:notifications:audit:readFull event payload (fetched from S3 for large events).
export_audit_log(start, end, format: "csv" or "json")tenant:notifications:audit:readEnqueue an async audit export job.

HubSpot Integration

ToolPermissionDescription
get_hubspot_status()tenant:integrations:hubspot:readConnection state, scopes granted, hub_id, and webhook health.
start_hubspot_oauth()tenant:integrations:hubspot:connectReturn the HubSpot OAuth authorization URL to open in a browser.
complete_hubspot_oauth(code, state)tenant:integrations:hubspot:connectExchange authorization code for tokens and store the refresh token.
test_hubspot()tenant:integrations:hubspot:readCall the HubSpot pipelines endpoint to verify the stored token is valid.
refresh_hubspot_oauth()tenant:integrations:hubspot:connectManually trigger a token refresh.
disconnect_hubspot(confirm: str)tenant:integrations:hubspot:disconnectDelete the stored token and mark the integration disconnected.
provision_hubspot_properties()tenant:integrations:hubspot:connectIdempotently create the flowstate_apn property group and all 10 custom properties.
list_hubspot_custom_properties()tenant:integrations:hubspot:readVerify all 10 APN custom properties exist in the connected HubSpot portal.

Slack Integration

ToolPermissionDescription
get_slack_status()tenant:integrations:slack:readWorkspace name and bot token status.
start_slack_oauth()tenant:integrations:slack:writeReturn the Slack OAuth authorization URL. In practice the onboarding UI is a bring-your-own-Slack-app wizard (copy a manifest, create the app, paste back Client ID/Secret) — there is no one-click install and no default-channel step.
complete_slack_oauth(code, state)tenant:integrations:slack:writeExchange code for bot token and store it.
test_slack()tenant:integrations:slack:writeDM the caller’s own Slack account a fixed connection-test message. Takes no parameters — the target is always the caller’s own JWT email claim, never an agent-supplied value.
list_slack_channels()tenant:integrations:slack:writeList channels available to the FlowState bot.
set_slack_notification_routing(rules)tenant:integrations:slack:writeStore a list of {event_category, channel_id} routing rules. The two rules FlowState currently reads — deals.outdated and deals.weekly_digest — drive real delivery from the daily pipeline cron; any other event_category is accepted and saved but has no producer yet. See Slack Integration → Notifications.
disconnect_slack()tenant:integrations:slack:writeDelete the bot token and mark the integration disconnected.

APN Integration — Config

Requires tenant:integrations:apn:configure (admin+).

ToolDescription
enable_apn_integration(role_arn, catalog: "Sandbox" or "AWS")Validate and enable the APN integration. Runs AssumeRole + ListOpportunities verification. Implemented today.
disable_apn_integration()Soft-disable APN sync. Preserves all sync state. Implemented today.
test_apn_connection()Live AssumeRole + ListOpportunities(MaxResults=1) test. Implemented today.
rotate_apn_external_id()Rotate the tenant’s ExternalId used in the trust policy.
get_apn_onboarding_artifacts()Return the ExternalId, FlowState principal ARN, Tofu module, CFN template URL, and manual steps.
list_apn_solutions()List the tenant’s configured AWS Partner Central solutions.

APN Integration — Read

Requires tenant:integrations:apn:read.

ToolDescription
list_apn_sync_state(state?, limit?, cursor?)Paginated list of every deal’s sync state, optionally filtered by state. state, limit, and cursor are currently ignored — every deal is returned regardless.
list_apn_conflicts()All deals with conflict_state != none.

APN Integration — Sync Actions

ToolPermissionDescription
resolve_apn_conflict_batch(deal_id, resolutions: dict)tenant:integrations:apn:configureResolve a deal’s sync conflicts with a per-field {field_name: "hubspot" or "apn"} choice. Marks the conflict resolved and clears the deal’s conflict_state so list_apn_conflicts stops surfacing it.
delete_apn_sync_state(deal_id)tenant:integrations:apn:configureDelete a deal’s APN sync-state record. Diagnostic and irreversible — fully unlinks the deal from APN sync tracking.
trigger_apn_sync(deal_id?)tenant:integrations:apn:configureRe-enqueue deals for outbound APN sync. With deal_id, enqueues only that deal; without it, enqueues every eligible deal in the tenant.
trigger_apn_reconcile()tenant:integrations:apn:configureStart an async reconcile of every APN opportunity linked to this tenant. Only one reconcile may be in flight per tenant.
trigger_apn_inbound_sync(opp_id?)tenant:integrations:apn:configureStart an async inbound pull of APN lifecycle fields into HubSpot. With opp_id, narrows the pull to one opportunity.

APN Integration — Stage Mapping

Parity with the REST routes under /v1/tenants/{id}/integrations/apn/stage-mapping*.

ToolPermissionDescription
get_apn_stage_mapping()tenant:integrations:apn:readReturn the tenant’s HubSpot pipelines joined with the stored APN stage mapping, plus the seven valid APN stage values.
set_apn_stage_mapping(pipelines: dict)tenant:integrations:apn:configurePersist pipeline_id → {hubspot_stage_id: apn_stage}. Rejects any value outside the seven-stage enum.
clear_apn_stage_mapping(pipeline_id)tenant:integrations:apn:configureClear the mapping for one HubSpot pipeline, typically after the pipeline was deleted in HubSpot.

APN Integration — Matching

Parity with the REST routes under /v1/tenants/{id}/apn/match/sessions/*.

ToolPermissionDescription
start_apn_match_session()tenant:integrations:apn:configureFetch all open APN opportunities and unlinked sync-flagged HubSpot deals, run Bedrock confidence matching, and persist a session for human confirmation.
list_apn_match_sessions()tenant:apn:readList recent match sessions for the tenant, most-recent first.
get_apn_match_session(session_id)tenant:apn:readFetch one session with its full candidate and unmatched-side lists.
confirm_apn_matches(session_id, candidate_ids)tenant:integrations:apn:configureConfirm one or more Bedrock-suggested matches. Writes apn_opportunity_id and apn_sync_with_aws_enabled=true on the HubSpot deals.
manual_pair_apn_match(session_id, apn_opportunity_id, hubspot_deal_id)tenant:integrations:apn:configureManually pair an opportunity with a deal from the session’s unmatched lists (drag-and-drop equivalent); implicitly confirms the pair.
create_apn_deal(session_id, apn_opportunity_id, amount?)tenant:integrations:apn:configureCreate a new HubSpot deal from an unmatched APN opportunity, link the pair, and drop the opportunity from the session’s unmatched list.

Deal Analytics

Requires tenant:deals:read + tenant:mcp:invoke + features.hubspot enabled.

ToolDescription
get_deal_pipeline_summary(from_date?, to_date?)Pipeline health summary: stage distribution, total value, close-date adherence.
list_stalled_deals(days_inactive?, from_date?, to_date?)Deals with no activity past days_inactive days (default 30).
get_deal_details(deal_id)Full deal data including AI summary, activities, and APN sync state.
get_pipeline_stages()All configured pipeline stages with deal counts and values.
get_deals_by_stage(from_date?, to_date?)Open deal counts and total values grouped by pipeline stage, optionally filtered by close date range.
get_deal_activities(deal_id, max_activities?)Activity history for a deal (notes, emails, calls, tasks). max_activities defaults to 20.
get_owner_action_items(from_date?, to_date?)Per-owner list of deals requiring action.
get_inconsistent_deals()Deals with data inconsistencies (missing close date, missing amount, etc.).
get_rep_won_amounts(from_date?, to_date?)Won revenue per rep for the date range.
list_outdated_deals(limit?)Deals past their close date still in an open stage.
get_win_loss_deals(since_date?, include_activities?)All closed deals (won and lost) since since_date. include_activities (default true) controls whether per-deal activity history is fetched and included.

Pipeline Operations

ToolPermissionDescription
refresh_pipeline()tenant:deals:analyzeEnqueue a pipeline snapshot refresh for the current tenant.
get_queue_status()tenant:settings:readCurrent pipeline-analysis queue depth and active workers.
analyze_deal(deal_id, prompt?)tenant:deals:analyzeInvoke AI analysis on a single deal with an optional custom prompt.
reanalyze_deal(deal_id)tenant:deals:reanalyzeForce a fresh analysis, bypassing the 8-day summary cache.

Goals and Win/Loss

ToolPermissionDescription
get_goals(year?)tenant:goals:readTenant goals for the year: target won amount, target deal count, and per-rep quotas.
set_goals(year, target_won_amount?, target_won_count?, rep_quotas?)tenant:goals:writeSet or update tenant goals.
get_win_loss(window?: "12m"/"24m"/"36m"/"48m")tenant:win-loss:readAggregated win/loss data for the window. Defaults to "12m" when omitted.
trigger_win_loss_analysis()tenant:win-loss:triggerTrigger a win/loss analysis batch — fans out up to 48 Bedrock month-workers. Gated on the write permission rather than tenant:win-loss:read, since a batch run has unbounded inference cost.