Skip to content

Fictura

co.fictura/mcpfictura.costreamable-httpv0.1.2Scanned

Paywalls, onboarding, subscription analytics, A/B tests, attribution and errors for mobile apps.

44 tools: 3 can delete or cancel things, 10 change things and 31 only read.

Tools: 3 delete, 0 irreversible, 10 write, 31 read.
  • Reads private data · 6
  • Reads text others write · 10
  • Can send data out · 1
  • 4 findings

Anlyon alternative

13 of these tools change something. Run those as governed actions.

Declare what an action changes, and Anlyon puts it under a shared limit, binds every approval to the exact request, and grades the outcome. It works on any HTTPS API you can describe as an action.

Anlyon does not run, proxy or govern this MCP server. A tool your own code calls directly is not routed through Anlyon and is not governed by it.

Import an OpenAPI spec →

Tools

Grouped by what each tool does, most consequential first. Open one for its reasons and full description; descriptions are the publisher's own words.

44 tools

Deletes or cancels 3Claude Code: deny
  • editor_set_docReplaces the document in the person's open editor with the one given.No findings

    Why it is in this group

    • The name "editor_set_doc" says "set": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Replaces the document in the person's open editor with the one given. It is NOT saved: the person sees the change, can undo it, and saves it themselves. The document is validated first and refused with the problems if it does not parse. Needs an MCP key that can edit.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: true
    • openWorldHint: false
  • save_onboarding_docReplaces a draft flow's document with the one given, as a new version (the dashboard's history shows it as `mcp: <note>` and can roll it back).No findings

    Why it is in this group

    • The name "save_onboarding_doc" says "save": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Replaces a draft flow's document with the one given, as a new version (the dashboard's history shows it as `mcp: <note>` and can roll it back). Refused for a live flow. Needs an MCP key that can edit. Translations, overrides and the exit setting are kept.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: true
    • openWorldHint: false
  • save_paywall_docReplaces a draft paywall's document with the one given, as a new version (History in the dashboard shows it as `mcp: <note>` and can roll it back).No findings

    Why it is in this group

    • The name "save_paywall_doc" says "save": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Replaces a draft paywall's document with the one given, as a new version (History in the dashboard shows it as `mcp: <note>` and can roll it back). Refused for a live paywall — copy it in the dashboard first. Needs an MCP key that can edit. Products, translations and other settings are kept.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: true
    • openWorldHint: false
Changes things 10Claude Code: ask
  • check_entitlementThe authoritative paid/not-paid verdict for one user, unified across Stripe, RevenueCat, App Store and Play — the same answer GET /api/v1/entitlements/{user_id} returns to a server…No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    The authoritative paid/not-paid verdict for one user, unified across Stripe, RevenueCat, App Store and Play — the same answer GET /api/v1/entitlements/{user_id} returns to a server. Note: `environment` is SANDBOX when the verdict rests on test purchases, so always check it before granting production access; a cancellation only flips will_renew (access runs to expires_at); and an unknown user is a valid 'none' answer, not an error.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • create_onboarding_draftCreates a draft onboarding flow from a document you wrote (see get_onboarding_doc's reference).No findings

    Why it is in this group

    • The name "create_onboarding_draft" says "create": a word for a change.
    Description, as the server wrote it
    Creates a draft onboarding flow from a document you wrote (see get_onboarding_doc's reference). It is never made live: going live is done in the dashboard. Needs an MCP key that can edit.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • openWorldHint: false
  • create_paywall_draftCreates a draft paywall from a Studio template (template_key, from list_templates — the webview ones) or from a document you wrote.No findings

    Why it is in this group

    • The name "create_paywall_draft" says "create": a word for a change.
    Description, as the server wrote it
    Creates a draft paywall from a Studio template (template_key, from list_templates — the webview ones) or from a document you wrote. It is never made live: going live is done in the dashboard. Needs an MCP key that can edit.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • openWorldHint: false
  • get_store_analyticsStore-reported numbers synced from Appfigures: downloads, re-downloads, updates, uninstalls, store revenue after the store's cut (subscriptions, in-app purchases, ads), top countri…Reads text others write1 finding

    Why it is in this group

    • The name "get_store_analytics" says "get": a word for reading.
    • The description's first verb is "store": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    What it can reach

    • untrusted-inputThe description's first sentence says "store" and "review": it reads comments, which other people can write.

    Findings

    • Warn

      The server marks "get_store_analytics" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false}; The name "get_store_analytics" says "get": a word for reading.

      What this check looks for
    Description, as the server wrote it
    Store-reported numbers synced from Appfigures: downloads, re-downloads, updates, uninstalls, store revenue after the store's cut (subscriptions, in-app purchases, ads), top countries, the ratings snapshot, recent reviews with text, and category chart positions. Money is in micros of `currency`. Store revenue is a separate figure from RevenueCat revenue; never add the two. Returns connected: false when Appfigures is not set up.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • pair_editorConnects to the paywall editor a person has open, using the 6-character code shown under “Pair an agent” in the Studio.No findings

    Why it is in this group

    • The input takes a statement or command to run (input.code), which can change anything it can reach.
    Description, as the server wrote it
    Connects to the paywall editor a person has open, using the 6-character code shown under “Pair an agent” in the Studio. Returns a pairing_id for the editor_* tools. The code works once and for 10 minutes; a pairing lasts 24 hours or until either side stops it.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • openWorldHint: false
  • start_appsflyer_importImport everything AppsFlyer holds for this app: installs and the channel, campaign, adset and ad behind each one, in-app events and purchases, uninstalls, reinstalls, ad revenue an…Reads text others writeNo findings

    Why it is in this group

    • The name "start_appsflyer_import" says "start": a word for a change.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    Import everything AppsFlyer holds for this app: installs and the channel, campaign, adset and ad behind each one, in-app events and purchases, uninstalls, reinstalls, ad revenue and retargeting traffic. All twelve raw-data reports are walked; ones the AppsFlyer plan lacks are skipped, not failed. Runs in the background and keeps going after this call. mode 'auto' (default) only pulls the days since the last finished import when there is one, and walks the full history otherwise. 'full' re-walks everything. resume=true continues a failed or cancelled run from where it stopped. Safe to call while a run is going: it reports that run instead of starting another. Anything already imported is counted once. Check progress with get_appsflyer_import_status.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: true
  • unpair_editorStops this pairing.No findings

    Why it is in this group

    • The description's first verb is "stop": a word for a change.
    Description, as the server wrote it
    Stops this pairing. The editor shows that the agent left.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • openWorldHint: false
  • update_error_issueResolve, ignore or reopen an issue, assign it, set its priority, or add a note.Can send data outNo findings

    Why it is in this group

    • The name "update_error_issue" says "update": a word for a change.

    What it can reach

    • outboundThe name "update_error_issue" says "update" and "issue": it writes something other people read.
    Description, as the server wrote it
    Resolve, ignore or reopen an issue, assign it, set its priority, or add a note. Only works when the app allows MCP writes (Issues settings → Let MCP keys change issues).

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
  • validate_onboarding_docRuns a document through the same parser, step-key check and renderer a save uses and reports what is wrong, if anything.1 finding

    Why it is in this group

    • The name "validate_onboarding_doc" says "validate": a word for reading.
    • The description's first verb is "run": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "validate_onboarding_doc" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false}; The name "validate_onboarding_doc" says "validate": a word for reading.

      What this check looks for
    Description, as the server wrote it
    Runs a document through the same parser, step-key check and renderer a save uses and reports what is wrong, if anything. Changes nothing.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • validate_paywall_docRuns a document through the same parser and renderer a save uses and reports what is wrong, if anything.1 finding

    Why it is in this group

    • The name "validate_paywall_doc" says "validate": a word for reading.
    • The description's first verb is "run": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "validate_paywall_doc" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false}; The name "validate_paywall_doc" says "validate": a word for reading.

      What this check looks for
    Description, as the server wrote it
    Runs a document through the same parser and renderer a save uses and reports what is wrong, if anything. Changes nothing.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
Only reads 31Show 31 read-only tools
  • editor_get_docThe document exactly as it is on the person's screen (unsaved changes included), which paywall it is, the screen they are on and the node they have selected, plus the document mode…Reads private dataNo findings

    Why it is in this group

    • The name "editor_get_doc" says "get": a word for reading.

    What it can reach

    • private-dataThe name "editor_get_doc" says "get" and "doc": it reads documents.
    • private-dataThe description's first sentence says "document": it reads documents.
    Description, as the server wrote it
    The document exactly as it is on the person's screen (unsaved changes included), which paywall it is, the screen they are on and the node they have selected, plus the document model reference. Read this before editor_set_doc and edit what you got — keep node ids, change only what was asked.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • get_acquisition_report`roas` gives per-campaign spend, attributed installs/trials/paying users, revenue, CPI, CAC and ROAS, plus blended totals and explicitly-unattributed revenue — always keep attribut…No findings

    Why it is in this group

    • The name "get_acquisition_report" says "get": a word for reading.
    Description, as the server wrote it
    `roas` gives per-campaign spend, attributed installs/trials/paying users, revenue, CPI, CAC and ROAS, plus blended totals and explicitly-unattributed revenue — always keep attributed and blended figures apart when reporting these. `spend` gives raw daily ad-spend rows. `links` lists this app's tracking links.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • get_analyticsThis app's real numbers.No findings

    Why it is in this group

    • The name "get_analytics" says "get": a word for reading.
    Description, as the server wrote it
    This app's real numbers. `overview` gives headline metrics (users, trials, trial→paid rate, events by name, cancel reasons, 14-day activity). `funnel` gives the ordered conversion funnel with per-step drop-off. `cohorts` compares behaviour across billing outcomes — what converted users did that cancelled users didn't. Below ~100 users in a step the sample is too small to read. `stores` splits paying users, purchases and revenue by App Store / Google Play / web and by storefront country (last 28 days).

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • get_app_setupThe real values needed to wire the Fictura SDK into a codebase: the API base URL, this app's publishable SDK key (gk_…), and the RevenueCat webhook URL.Reads text others write1 finding

    Why it is in this group

    • The name "get_app_setup" says "get": a word for reading.

    What it can reach

    • untrusted-inputThe description's first sentence says "url": it reads web pages, which anyone can write.

    Findings

    Description, as the server wrote it
    The real values needed to wire the Fictura SDK into a codebase: the API base URL, this app's publishable SDK key (gk_…), and the RevenueCat webhook URL. ALWAYS call this before generating integration code — never leave a placeholder API key in what you write. The SDK key is publishable and safe to commit in app source; it identifies the app, not a person.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • get_appsflyer_attribution_summaryWhat the AppsFlyer import brought in about where people came from: people with an imported attribution, split by media source (organic included) and acquisition vs retargeting, plu…No findings

    Why it is in this group

    • The name "get_appsflyer_attribution_summary" says "get": a word for reading.
    Description, as the server wrote it
    What the AppsFlyer import brought in about where people came from: people with an imported attribution, split by media source (organic included) and acquisition vs retargeting, plus the top campaigns. Filters on the install date. Imported verdicts never overwrite an attribution Fictura's own SDK resolved. For revenue and ROAS by source, use get_attribution_report with view=kpis.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • destructiveHint: false
  • get_appsflyer_import_statusWhether AppsFlyer is connected, the latest import run (status, progress, rows imported, duplicates skipped, people created, date range covered, error if it stopped), and whether an…No findings

    Why it is in this group

    • The name "get_appsflyer_import_status" says "get": a word for reading.
    Description, as the server wrote it
    Whether AppsFlyer is connected, the latest import run (status, progress, rows imported, duplicates skipped, people created, date range covered, error if it stopped), and whether an import has ever finished. Call before start_appsflyer_import so a finished import is not offered again as though nothing had happened.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • destructiveHint: false
  • get_attribution_reportWhere installs and revenue actually came from.No findings

    Why it is in this group

    • The name "get_attribution_report" says "get": a word for reading.
    Description, as the server wrote it
    Where installs and revenue actually came from. `summary` is the headline attribution picture (installs, organic vs non-organic, revenue). `kpis` breaks the same window down by source, campaign, link or day. `installs` lists individual installs with their attribution. Defaults to the trailing 28 days.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • get_error_issueOne issue in full: the group, its 50 most recent occurrences with stack traces, release and environment, and 30 days of daily counts.Reads text others writeNo findings

    Why it is in this group

    • The name "get_error_issue" says "get": a word for reading.

    What it can reach

    • untrusted-inputThe name "get_error_issue" says "get" and "issue": it reads issues, which other people can write.
    • untrusted-inputThe description's first sentence says "issue": it reads issues, which other people can write.
    Description, as the server wrote it
    One issue in full: the group, its 50 most recent occurrences with stack traces, release and environment, and 30 days of daily counts. This is the tool to reach for when asked to fix a production error. When the app uploaded source maps, each occurrence also has `stack_resolved` and `frames` (original file, line, column and function; `in_app` marks the app's own code) — read those instead of the minified `stack`. An occurrence with a trace_id can be opened with get_trace.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • get_error_issue_briefOne issue condensed for fixing it: latest stack (resolved when source maps exist), in-app frames, breadcrumbs before it, facets (release, OS, device, screen), cause chain, and a re…Reads text others writeNo findings

    Why it is in this group

    • The name "get_error_issue_brief" says "get": a word for reading.

    What it can reach

    • untrusted-inputThe name "get_error_issue_brief" says "get" and "issue": it reads issues, which other people can write.
    • untrusted-inputThe description's first sentence says "issue": it reads issues, which other people can write.
    Description, as the server wrote it
    One issue condensed for fixing it: latest stack (resolved when source maps exist), in-app frames, breadcrumbs before it, facets (release, OS, device, screen), cause chain, and a ready-to-use fix prompt.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • get_experimentOne experiment with its variants and full Bayesian results.No findings

    Why it is in this group

    • The name "get_experiment" says "get": a word for reading.
    Description, as the server wrote it
    One experiment with its variants and full Bayesian results.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • get_onboarding_docThe JSON document a builder-made onboarding flow is made of, with its status and version, plus the reference to the document model.Reads private dataNo findings

    Why it is in this group

    • The name "get_onboarding_doc" says "get": a word for reading.

    What it can reach

    • private-dataThe name "get_onboarding_doc" says "get" and "doc": it reads documents.
    • private-dataThe description's first sentence says "document": it reads documents.
    Description, as the server wrote it
    The JSON document a builder-made onboarding flow is made of, with its status and version, plus the reference to the document model. Read this before save_onboarding_doc, and edit the document you got rather than writing one from scratch — keep step keys and node ids, change only what was asked.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • get_paywall_docThe JSON document a Studio (visual editor) paywall is made of, with its status and version, plus the reference to the document model.Reads private dataNo findings

    Why it is in this group

    • The name "get_paywall_doc" says "get": a word for reading.

    What it can reach

    • private-dataThe name "get_paywall_doc" says "get" and "doc": it reads documents.
    • private-dataThe description's first sentence says "document": it reads documents.
    Description, as the server wrote it
    The JSON document a Studio (visual editor) paywall is made of, with its status and version, plus the reference to the document model. Read this before save_paywall_doc, and edit the document you got rather than writing one from scratch — keep node ids, change only what was asked. Prices are never typed: use {{ products.<slot>.price }} and the other product variables.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • get_push_configWhether push is set up and who could receive it: registered-device counts per billing cohort (all / paid / trial / free) and whether OneSignal is configured.No findings

    Why it is in this group

    • The name "get_push_config" says "get": a word for reading.
    Description, as the server wrote it
    Whether push is set up and who could receive it: registered-device counts per billing cohort (all / paid / trial / free) and whether OneSignal is configured. Returns counts and configuration only — never device tokens or individual recipients.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • get_setup_statusWhat is actually configured for this app: the setup checklist, every Fictura feature toggle and whether it is on, and which third-party integrations (Stripe, RevenueCat, Slack, Sen…No findings

    Why it is in this group

    • The name "get_setup_status" says "get": a word for reading.
    Description, as the server wrote it
    What is actually configured for this app: the setup checklist, every Fictura feature toggle and whether it is on, and which third-party integrations (Stripe, RevenueCat, Slack, Sentry, App Store Connect, …) are connected. Use it to check whether a feature is enabled before writing code that depends on it — a disabled tool is a server-side kill switch the SDK obeys.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • get_surfaceThe full configuration of one paywall or onboarding flow, plus its version history.No findings

    Why it is in this group

    • The name "get_surface" says "get": a word for reading.
    Description, as the server wrote it
    The full configuration of one paywall or onboarding flow, plus its version history. Note that configs never contain price strings — prices resolve at render time from the PurchasesAdapter's packages, so never copy a price literal out of (or into) a config.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • get_traceEvery span of one trace (app → backend → dependencies) as a tree: names, services, start offsets, durations, HTTP status and errors, plus the error events linked to the trace.Reads text others writeNo findings

    Why it is in this group

    • The name "get_trace" says "get": a word for reading.

    What it can reach

    • untrusted-inputThe description's first sentence says "http": it reads web pages, which anyone can write.
    Description, as the server wrote it
    Every span of one trace (app → backend → dependencies) as a tree: names, services, start offsets, durations, HTTP status and errors, plus the error events linked to the trace. Take the trace_id from an occurrence in get_error_issue. Use it to see where the time went or what failed first.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • get_tracking_planEvery event this app has ever sent, with volume, last-seen, and whether capture is switched off.No findings

    Why it is in this group

    • The name "get_tracking_plan" says "get": a word for reading.
    Description, as the server wrote it
    Every event this app has ever sent, with volume, last-seen, and whether capture is switched off. Use it before adding instrumentation so you reuse the existing event name instead of introducing a near-duplicate — the name chosen here is the same string an experiment later names as its primary metric.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • get_userOne user's identity (every stitched device / account / RevenueCat id), event breakdown, churn state and recent activity.No findings

    Why it is in this group

    • The name "get_user" says "get": a word for reading.
    Description, as the server wrote it
    One user's identity (every stitched device / account / RevenueCat id), event breakdown, churn state and recent activity. Accepts the Fictura master user id, or any identifier the app knows them by — a device id, account id or RevenueCat id.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • list_campaignsCampaigns read live from a connected ad platform: status, daily budget and ad sets.No findings

    Why it is in this group

    • The name "list_campaigns" says "list": a word for reading.
    Description, as the server wrote it
    Campaigns read live from a connected ad platform: status, daily budget and ad sets. Returns a not_connected result rather than failing when the provider is not set up. This calls the provider's API, so prefer get_acquisition_report for historical numbers.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • list_creatorsCreator records with a 28-day funnel per creator (clicks, installs, trials, paying users) and the tracking links tagged to each.No findings

    Why it is in this group

    • The name "list_creators" says "list": a word for reading.
    Description, as the server wrote it
    Creator records with a 28-day funnel per creator (clicks, installs, trials, paying users) and the tracking links tagged to each.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • list_docsThe full documentation index — every page path, grouped by section, with a one-line description.Reads private dataNo findings

    Why it is in this group

    • The name "list_docs" says "list": a word for reading.

    What it can reach

    • private-dataThe name "list_docs" says "list" and "doc": it reads documents.
    Description, as the server wrote it
    The full documentation index — every page path, grouped by section, with a one-line description. Use it to find the right page when a search term is hard to guess. No API key required.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • list_error_issuesThe error feed: grouped issues with level, status, event and user counts, a 14-day sparkline, plus the app's uptime summary.Reads text others writeNo findings

    Why it is in this group

    • The name "list_error_issues" says "list": a word for reading.

    What it can reach

    • untrusted-inputThe name "list_error_issues" says "list" and "issue": it reads issues, which other people can write.
    • untrusted-inputThe description's first sentence says "issue": it reads issues, which other people can write.
    Description, as the server wrote it
    The error feed: grouped issues with level, status, event and user counts, a 14-day sparkline, plus the app's uptime summary. Defaults to unresolved issues only. `synthetic: true` marks console lines the SDK captured, not crashes.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • list_experimentsEvery experiment with status and, for running or finished ones, full Bayesian results — exposures, conversions, and the probability each variant is best.No findings

    Why it is in this group

    • The name "list_experiments" says "list": a word for reading.
    Description, as the server wrote it
    Every experiment with status and, for running or finished ones, full Bayesian results — exposures, conversions, and the probability each variant is best.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • list_store_productsThis app's auto-renewable subscriptions in App Store Connect: product id, billing period and Apple review state.Reads text others writeNo findings

    Why it is in this group

    • The name "list_store_products" says "list": a word for reading.

    What it can reach

    • untrusted-inputThe description's first sentence says "review": it reads comments, which other people can write.
    Description, as the server wrote it
    This app's auto-renewable subscriptions in App Store Connect: product id, billing period and Apple review state. Use it to check that a paywall references a product that actually exists. Pass subscription_id to also fetch Apple's price ladder for that one product (Apple scopes price points per subscription, so there is no global list).

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • list_surfacesEvery paywall and onboarding flow, what is actually being served at each placement (running experiment > live > none), and the valid placement names.No findings

    Why it is in this group

    • The name "list_surfaces" says "list": a word for reading.
    Description, as the server wrote it
    Every paywall and onboarding flow, what is actually being served at each placement (running experiment > live > none), and the valid placement names. IMPORTANT: read `placements` before writing a placement string into code. The list is configured ∪ observed, so a name that appears only under `observed` is usually a typo in the app — and a placement that does not exist renders nothing at all, with no error.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • list_templatesThe one-click starter templates available for paywalls or onboarding flows, with the template key and what each looks like.No findings

    Why it is in this group

    • The name "list_templates" says "list": a word for reading.
    Description, as the server wrote it
    The one-click starter templates available for paywalls or onboarding flows, with the template key and what each looks like. Use this when asked to add a paywall so you pick a real template key rather than inventing one.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • list_usersThe app's users, most recently active first — each with an identity label, event count, last seen, and derived churn state (in_trial, converted, cancelled, expired, billing_issue, …Reads text others writeNo findings

    Why it is in this group

    • The name "list_users" says "list": a word for reading.

    What it can reach

    • untrusted-inputThe description's first sentence says "issue": it reads issues, which other people can write.
    Description, as the server wrote it
    The app's users, most recently active first — each with an identity label, event count, last seen, and derived churn state (in_trial, converted, cancelled, expired, billing_issue, grace_period, paused, refunded, none). Capped so a large app does not flood the context; `total` reports how many matched before the cap.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • read_docThe complete markdown of one documentation page.Reads private dataNo findings

    Why it is in this group

    • The name "read_doc" says "read": a word for reading.

    What it can reach

    • private-dataThe name "read_doc" says "read" and "doc": it reads documents.
    Description, as the server wrote it
    The complete markdown of one documentation page. Accepts a site-relative path such as '/implementation/welcome/sdk-quickstart' (a full docs.fictura.co URL works too). If the path is wrong, the closest real paths come back as suggestions. No API key required.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • search_docsFull-text search across the Fictura docs, grouped by page.Reads private dataNo findings

    Why it is in this group

    • The name "search_docs" says "search": a word for reading.

    What it can reach

    • private-dataThe name "search_docs" says "search" and "doc": it reads documents.
    • private-dataThe description's first sentence says "doc": it reads documents.
    Description, as the server wrote it
    Full-text search across the Fictura docs, grouped by page. Use this before answering any 'how do I…' question about the SDK, API, paywalls, entitlements, links or webhooks — the docs are the source of truth and are regenerated on every code change. Returns page paths; pass one to read_doc for the full text. No API key required.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false
  • search_error_issuesFind issues by text in the title or culprit, platform, or release (first or last seen in).Reads text others writeNo findings

    Why it is in this group

    • The name "search_error_issues" says "search": a word for reading.

    What it can reach

    • untrusted-inputThe name "search_error_issues" says "search" and "issue": it reads issues, which other people can write.
    • untrusted-inputThe description's first sentence says "find" and "issue": it reads issues, which other people can write.
    Description, as the server wrote it
    Find issues by text in the title or culprit, platform, or release (first or last seen in). Returns the same rows as list_error_issues, filtered.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: false

This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.

Exfil surface

Which tools read private data, which read text someone else can write, and which can send data out. One of each is a path a prompt injection can use.

60 paths in this server alone from private data, through text someone else wrote, to a way out. Denying 1 outbound tool breaks every one.

Reads private data6
Reads files, mail, messages, databases, secrets, calendars or repositories.
Reads text others write10
Brings in text someone else can write: web pages, inbound email, messages, issues and comments.
Can send data out1
Can carry data to people or systems: it sends, posts or publishes, or takes a recipient, channel or URL.
deny to break every path
{
  "permissions": {
    "deny": [
      "mcp__fictura__update_error_issue"
    ]
  }
}

Other servers in the same agent add their own tools to these paths. Audit your whole setup to see them together.

Findings

Matches of fixed checks, with the text they matched.

3 warn1 info
  • The server marks "get_store_analytics" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false}; The name "get_store_analytics" says "get": a word for reading.

    What this check looks for
  • The server marks "validate_paywall_doc" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false}; The name "validate_paywall_doc" says "validate": a word for reading.

    What this check looks for
  • The server marks "validate_onboarding_doc" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false}; The name "validate_onboarding_doc" says "validate": a word for reading.

    What this check looks for
  • The title mentions "credentials".

    Matched text

    title: "Get this app's Fictura credentials and endpoints"

    What this check looks for

History

Changes to its tool definitions and to its remote endpoint, newest first.

No change seen yet. Its tools are rescanned every day, and a remote endpoint is looked at once a week.

Install

Pinned to version 0.1.2. Values in angle brackets are yours to fill in.

claude mcp add --transport http fictura https://mcp.fictura.co/mcp
claude mcp add --transport http fictura https://mcp.fictura.co/mcp

Run in a terminal.

Claude Code permissions

Allow the reads, ask before a change or a way out, deny the deletes. Paste into .claude/settings.json.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__fictura__search_docs",
      "mcp__fictura__list_docs",
      "mcp__fictura__read_doc",
      "mcp__fictura__get_app_setup",
      "mcp__fictura__get_setup_status",
      "mcp__fictura__get_analytics",
      "mcp__fictura__get_attribution_report",
      "mcp__fictura__list_users",
      "mcp__fictura__get_user",
      "mcp__fictura__get_tracking_plan",
      "mcp__fictura__list_surfaces",
      "mcp__fictura__get_surface",
      "mcp__fictura__list_templates",
      "mcp__fictura__list_experiments",
      "mcp__fictura__get_experiment",
      "mcp__fictura__get_acquisition_report",
      "mcp__fictura__list_campaigns",
      "mcp__fictura__list_creators",
      "mcp__fictura__get_link_infrastructure",
      "mcp__fictura__get_push_config",
      "mcp__fictura__list_store_products",
      "mcp__fictura__list_error_issues",
      "mcp__fictura__get_error_issue",
      "mcp__fictura__search_error_issues",
      "mcp__fictura__get_error_issue_brief",
      "mcp__fictura__get_trace",
      "mcp__fictura__get_paywall_doc",
      "mcp__fictura__editor_get_doc",
      "mcp__fictura__get_onboarding_doc",
      "mcp__fictura__get_appsflyer_import_status",
      "mcp__fictura__get_appsflyer_attribution_summary"
    ],
    "ask": [
      "mcp__fictura__check_entitlement",
      "mcp__fictura__get_store_analytics",
      "mcp__fictura__update_error_issue",
      "mcp__fictura__validate_paywall_doc",
      "mcp__fictura__create_paywall_draft",
      "mcp__fictura__pair_editor",
      "mcp__fictura__unpair_editor",
      "mcp__fictura__validate_onboarding_doc",
      "mcp__fictura__create_onboarding_draft",
      "mcp__fictura__start_appsflyer_import"
    ],
    "deny": [
      "mcp__fictura__save_paywall_doc",
      "mcp__fictura__editor_set_doc",
      "mcp__fictura__save_onboarding_doc"
    ]
  }
}

Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. A read that can send data out (it takes a URL, say) asks first too. It assumes the server is installed as fictura. Review it before you use it.

Capability tags behind 17 rules
  • mcp__fictura__search_docs private-data
  • mcp__fictura__list_docs private-data
  • mcp__fictura__read_doc private-data
  • mcp__fictura__get_app_setup untrusted-input
  • mcp__fictura__list_users untrusted-input
  • mcp__fictura__get_store_analytics untrusted-input
  • mcp__fictura__list_store_products untrusted-input
  • mcp__fictura__list_error_issues untrusted-input
  • mcp__fictura__get_error_issue untrusted-input
  • mcp__fictura__search_error_issues untrusted-input
  • mcp__fictura__get_error_issue_brief untrusted-input
  • mcp__fictura__update_error_issue outbound
  • mcp__fictura__get_trace untrusted-input
  • mcp__fictura__get_paywall_doc private-data
  • mcp__fictura__editor_get_doc private-data
  • mcp__fictura__get_onboarding_doc private-data
  • mcp__fictura__start_appsflyer_import untrusted-input

Pin

Keep the decision: fail CI when the tools change, follow every change, or show a badge.

Pin in CI

Fail a build when the tools you reviewed are not the tools the server serves today.

curl -s "https://anlyon.dev/api/v1/servers/co.fictura/mcp/verify?hash=b345e4dfc37a5ce034774533116453bc2fd4d473baa54d82b12d5b327171c124" | jq -e '.changed == false'

Pinned hash b345e4dfc37a, from Oct 29, 2026, 18:24 UTC.

Watch

Get told when its tools change: a new tool, a new description, a new class.

https://anlyon.dev/servers/co.fictura/mcp/changes.xml

An Atom feed. Works in any feed reader or Slack's RSS app.

Badge

anlyon.dev badge for co.fictura/mcp
[![anlyon.dev](https://anlyon.dev/badge/co.fictura/mcp.svg)](https://anlyon.dev/servers/co.fictura/mcp)

Source: MCP Registry · repository. Synced Oct 29, 2026, 18:24 UTC.