Koskamo

Fictura MCP

An official MCP server provided by Fictura that allows AI coding agents to read live app data including paywalls, funnels, experiments, errors, and documentation. It supports limited write operations such as creating draft paywalls and onboarding flows, and managing error issues, enabling agents to integrate against real app configurations without guessing.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Fictura MCP logo, by FicturaVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-01Operated by Fictura
You need:active Fictura subscriptionthe AI plan (or its own Anthropic key)MCP key minted with Can connect and import dataMCP key minted with Can edit drafts
MCP endpoint (Streamable HTTP)
https://mcp.fictura.co/mcp
Vendor documentation

What you can do with it

  • Read live paywall and funnel data
  • Create draft paywalls and onboarding flows
  • Manage error issues and attribution
  • Connect AppsFlyer data imports

Source and maintenance

Vendor evidenceRegistry 0.1.2
Maintenance checked

Protocol and capabilities

Server
fictura 1.0.0
MCP protocol
2025-06-18
Tools
44 advertised
Resources
Not advertised
Resource templates
Not advertised
Prompts
1 advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  },
  "prompts": {
    "listChanged": true
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Fictura documentation is available without signing in (search_docs, read_doc, list_docs). Not authenticated. Fictura data tools need you to sign in with your Fictura account (your client offers this when it supports MCP sign-in) or an MCP key: open the Fictura dashboard → Setup → “Coding agents (MCP)” → create a key, then reconnect with the header `x-api-key: fk_mcp_…` or `Authorization: Bearer fk_mcp_…` (or set FICTURA_MCP_KEY if you are using the @fictura/mcp npx shim). The documentation tools — search_docs, read_doc, list_docs — work without either.

Tools

44 advertised

search_docs — Search Fictura documentation
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

search_docs input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "query"
  ],
  "properties": {
    "limit": {
      "type": "integer",
      "maximum": 20,
      "minimum": 1,
      "description": "Max pages to return (default 8)"
    },
    "query": {
      "type": "string",
      "maxLength": 200,
      "minLength": 1,
      "description": "What to search for, e.g. 'purchases adapter'"
    }
  }
}
search_docs annotations
{
  "title": "Search Fictura documentation",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
list_docs — List Fictura documentation pages
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

list_docs input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {}
}
list_docs annotations
{
  "title": "List Fictura documentation pages",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
read_doc — Read a Fictura documentation page
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

read_doc input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "path"
  ],
  "properties": {
    "path": {
      "type": "string",
      "maxLength": 300,
      "minLength": 1,
      "description": "Page path, e.g. /implementation/sdk-reference/expo-react-native"
    }
  }
}
read_doc annotations
{
  "title": "Read a Fictura documentation page",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_app_setup — Get this app's Fictura credentials and endpoints
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

get_app_setup input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {}
}
get_app_setup annotations
{
  "title": "Get this app's Fictura credentials and endpoints",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_setup_status — Get integration and feature status
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

get_setup_status input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {}
}
get_setup_status annotations
{
  "title": "Get integration and feature status",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_analytics — Get funnel, overview or cohort analytics
Advertised by the server during the last successful anonymous check.
Advertised read-only

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).

get_analytics input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "view"
  ],
  "properties": {
    "view": {
      "enum": [
        "overview",
        "funnel",
        "cohorts",
        "stores"
      ],
      "type": "string",
      "description": "Which analytics view to return"
    }
  }
}
get_analytics annotations
{
  "title": "Get funnel, overview or cohort analytics",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_attribution_report — Get attribution, install and KPI reporting
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

get_attribution_report input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "view"
  ],
  "properties": {
    "view": {
      "enum": [
        "summary",
        "kpis",
        "installs"
      ],
      "type": "string",
      "description": "Which report to return"
    },
    "limit": {
      "type": "integer",
      "maximum": 500,
      "minimum": 1,
      "description": "For view=installs (default 100)"
    },
    "since": {
      "type": "string",
      "description": "YYYY-MM-DD (default 28 days ago)"
    },
    "until": {
      "type": "string",
      "description": "YYYY-MM-DD (default today)"
    },
    "group_by": {
      "enum": [
        "source",
        "campaign",
        "link",
        "day"
      ],
      "type": "string",
      "description": "For view=kpis (default source)"
    }
  }
}
get_attribution_report annotations
{
  "title": "Get attribution, install and KPI reporting",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
list_users — List users
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

list_users input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "limit": {
      "type": "integer",
      "maximum": 200,
      "minimum": 1,
      "description": "Max users (default 50)"
    },
    "churn_state": {
      "enum": [
        "in_trial",
        "converted",
        "cancelled",
        "expired",
        "billing_issue",
        "grace_period",
        "paused",
        "refunded",
        "none"
      ],
      "type": "string",
      "description": "Only users in this billing state"
    }
  }
}
list_users annotations
{
  "title": "List users",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_user — Get one user's full history
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

get_user input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "user_id"
  ],
  "properties": {
    "user_id": {
      "type": "string",
      "maxLength": 200,
      "minLength": 1,
      "description": "Master user id, or any known identifier"
    }
  }
}
get_user annotations
{
  "title": "Get one user's full history",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
check_entitlement — Check whether a user is subscribed
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

check_entitlement input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "user_id"
  ],
  "properties": {
    "user_id": {
      "type": "string",
      "maxLength": 200,
      "minLength": 1,
      "description": "Device id, account id or RevenueCat id"
    }
  }
}
check_entitlement annotations
{
  "title": "Check whether a user is subscribed",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_tracking_plan — Get the event tracking plan
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

get_tracking_plan input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {}
}
get_tracking_plan annotations
{
  "title": "Get the event tracking plan",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
list_surfaces — List paywalls, onboarding flows and placements
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

list_surfaces input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {}
}
list_surfaces annotations
{
  "title": "List paywalls, onboarding flows and placements",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_surface — Get one paywall or onboarding flow's config
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

get_surface input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "kind",
    "id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "The surface id, from list_surfaces"
    },
    "kind": {
      "enum": [
        "paywall",
        "onboarding"
      ],
      "type": "string",
      "description": "Which kind of surface"
    }
  }
}
get_surface annotations
{
  "title": "Get one paywall or onboarding flow's config",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
list_templates — List built-in paywall and onboarding templates
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

list_templates input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "kind"
  ],
  "properties": {
    "kind": {
      "enum": [
        "paywall",
        "onboarding"
      ],
      "type": "string",
      "description": "Which template catalog"
    }
  }
}
list_templates annotations
{
  "title": "List built-in paywall and onboarding templates",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
list_experiments — List experiments
Advertised by the server during the last successful anonymous check.
Advertised read-only

Every experiment with status and, for running or finished ones, full Bayesian results — exposures, conversions, and the probability each variant is best.

list_experiments input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {}
}
list_experiments annotations
{
  "title": "List experiments",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_experiment — Get one experiment
Advertised by the server during the last successful anonymous check.
Advertised read-only

One experiment with its variants and full Bayesian results.

get_experiment input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "Experiment id, from list_experiments"
    }
  }
}
get_experiment annotations
{
  "title": "Get one experiment",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_acquisition_report — Get paid acquisition performance
Advertised by the server during the last successful anonymous check.
Advertised read-only

`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.

get_acquisition_report input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "view"
  ],
  "properties": {
    "days": {
      "type": "integer",
      "maximum": 90,
      "minimum": 1,
      "description": "Lookback, for view=spend"
    },
    "view": {
      "enum": [
        "roas",
        "spend",
        "links"
      ],
      "type": "string",
      "description": "Which acquisition view"
    },
    "since": {
      "type": "string",
      "description": "YYYY-MM-DD, for view=roas"
    },
    "until": {
      "type": "string",
      "description": "YYYY-MM-DD, for view=roas"
    },
    "provider": {
      "type": "string",
      "description": "Filter, for view=spend"
    }
  }
}
get_acquisition_report annotations
{
  "title": "Get paid acquisition performance",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_store_analytics — Get App Store and Google Play analytics (Appfigures)
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

get_store_analytics input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "days": {
      "type": "integer",
      "maximum": 1095,
      "minimum": 1,
      "description": "Lookback in days, default 28"
    },
    "reviews": {
      "type": "integer",
      "maximum": 200,
      "minimum": 0,
      "description": "How many recent reviews to include, default 20"
    }
  }
}
get_store_analytics annotations
{
  "title": "Get App Store and Google Play analytics (Appfigures)",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
list_campaigns — List live ad campaigns
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

list_campaigns input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "provider"
  ],
  "properties": {
    "provider": {
      "enum": [
        "meta",
        "apple_search_ads",
        "snapchat",
        "tiktok",
        "google_ads",
        "reddit",
        "test"
      ],
      "type": "string",
      "description": "Which ad platform"
    }
  }
}
list_campaigns annotations
{
  "title": "List live ad campaigns",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
list_creators — List creators and their performance
Advertised by the server during the last successful anonymous check.
Advertised read-only

Creator records with a 28-day funnel per creator (clicks, installs, trials, paying users) and the tracking links tagged to each.

list_creators input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {}
}
list_creators annotations
{
  "title": "List creators and their performance",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_link_infrastructure — Get deep link and tracking domain configuration
Advertised by the server during the last successful anonymous check.
Advertised read-only

How links reach the app. `app_links` is the most important for integration work: it returns the iOS team id, bundle id, Android package and SHA-256 fingerprints that Fictura serves in the Universal Links / App Links association files, plus ios_ready and android_ready. Get these wrong and BOTH files fail SILENTLY — they parse, associate nothing, report no error, and links simply keep opening the browser instead of the app, so verify the ready flags rather than assuming. `domains` lists branded link domains and their DNS verification state, `web_config` the web-to-app smart banner, `esp` the email provider link setup.

get_link_infrastructure input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "view"
  ],
  "properties": {
    "view": {
      "enum": [
        "app_links",
        "domains",
        "web_config",
        "esp"
      ],
      "type": "string",
      "description": "Which part of the link setup"
    }
  }
}
get_link_infrastructure annotations
{
  "title": "Get deep link and tracking domain configuration",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_push_config — Get push notification configuration
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

get_push_config input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {}
}
get_push_config annotations
{
  "title": "Get push notification configuration",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
list_store_products — List App Store subscription products
Advertised by the server during the last successful anonymous check.
Advertised read-only

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).

list_store_products input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "territory": {
      "type": "string",
      "description": "Territory for price points (default USA)"
    },
    "subscription_id": {
      "type": "string",
      "description": "Also return price points for this subscription"
    }
  }
}
list_store_products annotations
{
  "title": "List App Store subscription products",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
list_error_issues — List error issues
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

list_error_issues input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "status": {
      "enum": [
        "unresolved",
        "resolved",
        "ignored",
        "discarded",
        "all"
      ],
      "type": "string",
      "description": "Which issues to include (default unresolved)"
    },
    "include_legacy": {
      "type": "boolean",
      "description": "Also list issues grouped before grouping v2 (default false)"
    }
  }
}
list_error_issues annotations
{
  "title": "List error issues",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_error_issue — Get one error issue with stack traces
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

get_error_issue input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "issue_id"
  ],
  "properties": {
    "issue_id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "Issue id, from list_error_issues"
    }
  }
}
get_error_issue annotations
{
  "title": "Get one error issue with stack traces",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
search_error_issues — Search error issues
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

search_error_issues input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "limit": {
      "type": "integer",
      "maximum": 100,
      "minimum": 1
    },
    "query": {
      "type": "string",
      "maxLength": 200,
      "description": "Text to look for in the title or culprit"
    },
    "status": {
      "enum": [
        "unresolved",
        "resolved",
        "ignored",
        "discarded",
        "all"
      ],
      "type": "string"
    },
    "release": {
      "type": "string",
      "maxLength": 200
    },
    "platform": {
      "type": "string",
      "maxLength": 20
    }
  }
}
search_error_issues annotations
{
  "title": "Search error issues",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_error_issue_brief — Get an issue brief and a fix prompt
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

get_error_issue_brief input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "issue_id"
  ],
  "properties": {
    "issue_id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "Issue id, from list_error_issues"
    }
  }
}
get_error_issue_brief annotations
{
  "title": "Get an issue brief and a fix prompt",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
update_error_issue — Change an error issue
Advertised by the server during the last successful anonymous check.

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).

update_error_issue input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "issue_id"
  ],
  "properties": {
    "note": {
      "type": "string",
      "maxLength": 4000,
      "minLength": 1
    },
    "status": {
      "enum": [
        "resolved",
        "ignored",
        "ongoing"
      ],
      "type": "string"
    },
    "assignee": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 200
        },
        {
          "type": "null"
        }
      ]
    },
    "issue_id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    },
    "priority": {
      "anyOf": [
        {
          "enum": [
            "high",
            "medium",
            "low"
          ],
          "type": "string"
        },
        {
          "type": "null"
        }
      ]
    },
    "resolved_in_release": {
      "type": "string",
      "maxLength": 200
    }
  }
}
update_error_issue annotations
{
  "title": "Change an error issue",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
get_trace — Get one distributed trace
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

get_trace input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "trace_id"
  ],
  "properties": {
    "trace_id": {
      "type": "string",
      "description": "32-character hex W3C trace id"
    }
  }
}
get_trace annotations
{
  "title": "Get one distributed trace",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_paywall_doc — Get a Studio paywall's document
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

get_paywall_doc input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "The paywall id, from list_surfaces"
    }
  }
}
get_paywall_doc annotations
{
  "title": "Get a Studio paywall's document",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
validate_paywall_doc — Check a paywall document without saving it
Advertised by the server during the last successful anonymous check.
Advertised read-only

Runs a document through the same parser and renderer a save uses and reports what is wrong, if anything. Changes nothing.

validate_paywall_doc input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "doc"
  ],
  "properties": {
    "doc": {
      "type": "object",
      "description": "A paywall document (version: 1)",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    }
  }
}
validate_paywall_doc annotations
{
  "title": "Check a paywall document without saving it",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
save_paywall_doc — Save a DRAFT paywall's document
Advertised by the server during the last successful anonymous check.
Advertised destructive

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.

save_paywall_doc input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "id",
    "doc"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "The draft paywall's id"
    },
    "doc": {
      "type": "object",
      "description": "The complete edited document",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    },
    "note": {
      "type": "string",
      "maxLength": 160,
      "description": "What changed, for the version history"
    }
  }
}
save_paywall_doc annotations
{
  "title": "Save a DRAFT paywall's document",
  "readOnlyHint": false,
  "openWorldHint": false,
  "destructiveHint": true
}
create_paywall_draft — Create a new DRAFT Studio paywall
Advertised by the server during the last successful anonymous check.

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.

create_paywall_draft input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "name"
  ],
  "properties": {
    "doc": {
      "type": "object",
      "description": "A complete document, instead of a template",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    },
    "name": {
      "type": "string",
      "maxLength": 80,
      "minLength": 1,
      "description": "The paywall's name in the dashboard"
    },
    "template_key": {
      "type": "string",
      "maxLength": 80,
      "description": "A webview template key to start from"
    }
  }
}
create_paywall_draft annotations
{
  "title": "Create a new DRAFT Studio paywall",
  "readOnlyHint": false,
  "openWorldHint": false,
  "destructiveHint": false
}
pair_editor — Pair with an open Studio editor
Advertised by the server during the last successful anonymous check.

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.

pair_editor input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "code"
  ],
  "properties": {
    "code": {
      "type": "string",
      "maxLength": 12,
      "minLength": 4,
      "description": "The code shown in the editor"
    }
  }
}
pair_editor annotations
{
  "title": "Pair with an open Studio editor",
  "readOnlyHint": false,
  "openWorldHint": false,
  "destructiveHint": false
}
editor_get_doc — Read the document open in the paired editor
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

editor_get_doc input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "pairing_id"
  ],
  "properties": {
    "pairing_id": {
      "type": "string",
      "maxLength": 80,
      "minLength": 8,
      "description": "From pair_editor"
    }
  }
}
editor_get_doc annotations
{
  "title": "Read the document open in the paired editor",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
editor_set_doc — Put a document on the paired editor's canvas
Advertised by the server during the last successful anonymous check.
Advertised destructive

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.

editor_set_doc input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "pairing_id",
    "doc"
  ],
  "properties": {
    "doc": {
      "type": "object",
      "description": "The complete edited document",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    },
    "note": {
      "type": "string",
      "maxLength": 160,
      "description": "What changed, shown to the person in the editor"
    },
    "pairing_id": {
      "type": "string",
      "maxLength": 80,
      "minLength": 8,
      "description": "From pair_editor"
    }
  }
}
editor_set_doc annotations
{
  "title": "Put a document on the paired editor's canvas",
  "readOnlyHint": false,
  "openWorldHint": false,
  "destructiveHint": true
}
unpair_editor — End the pairing with the editor
Advertised by the server during the last successful anonymous check.

Stops this pairing. The editor shows that the agent left.

unpair_editor input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "pairing_id"
  ],
  "properties": {
    "pairing_id": {
      "type": "string",
      "maxLength": 80,
      "minLength": 8,
      "description": "From pair_editor"
    }
  }
}
unpair_editor annotations
{
  "title": "End the pairing with the editor",
  "readOnlyHint": false,
  "openWorldHint": false,
  "destructiveHint": false
}
get_onboarding_doc — Get an onboarding flow's document
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

get_onboarding_doc input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "The onboarding flow id, from list_surfaces"
    }
  }
}
get_onboarding_doc annotations
{
  "title": "Get an onboarding flow's document",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
validate_onboarding_doc — Check an onboarding document without saving it
Advertised by the server during the last successful anonymous check.
Advertised read-only

Runs a document through the same parser, step-key check and renderer a save uses and reports what is wrong, if anything. Changes nothing.

validate_onboarding_doc input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "doc"
  ],
  "properties": {
    "doc": {
      "type": "object",
      "description": "An onboarding document (version: 1)",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    }
  }
}
validate_onboarding_doc annotations
{
  "title": "Check an onboarding document without saving it",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
save_onboarding_doc — Save a DRAFT onboarding flow's document
Advertised by the server during the last successful anonymous check.
Advertised destructive

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.

save_onboarding_doc input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "id",
    "doc"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "The draft flow's id"
    },
    "doc": {
      "type": "object",
      "description": "The complete edited document",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    },
    "note": {
      "type": "string",
      "maxLength": 160,
      "description": "What changed, for the version history"
    }
  }
}
save_onboarding_doc annotations
{
  "title": "Save a DRAFT onboarding flow's document",
  "readOnlyHint": false,
  "openWorldHint": false,
  "destructiveHint": true
}
create_onboarding_draft — Create a new DRAFT onboarding flow
Advertised by the server during the last successful anonymous check.

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.

create_onboarding_draft input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "name",
    "doc"
  ],
  "properties": {
    "doc": {
      "type": "object",
      "description": "A complete onboarding document",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    },
    "name": {
      "type": "string",
      "maxLength": 80,
      "minLength": 1,
      "description": "The flow's name in the dashboard"
    }
  }
}
create_onboarding_draft annotations
{
  "title": "Create a new DRAFT onboarding flow",
  "readOnlyHint": false,
  "openWorldHint": false,
  "destructiveHint": false
}
start_appsflyer_import — Start the AppsFlyer import
Advertised by the server during the last successful anonymous check.
Open-world

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.

start_appsflyer_import input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "mode": {
      "enum": [
        "auto",
        "full"
      ],
      "type": "string",
      "description": "Default auto"
    },
    "resume": {
      "type": "boolean",
      "description": "Continue the last failed or cancelled run"
    }
  }
}
start_appsflyer_import annotations
{
  "title": "Start the AppsFlyer import",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
get_appsflyer_import_status — Get AppsFlyer import status
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

get_appsflyer_import_status input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {}
}
get_appsflyer_import_status annotations
{
  "title": "Get AppsFlyer import status",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_appsflyer_attribution_summary — Summarize imported AppsFlyer attribution
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

get_appsflyer_attribution_summary input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "since": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Install date from, YYYY-MM-DD"
    },
    "until": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Install date to, YYYY-MM-DD"
    },
    "top_campaigns": {
      "type": "integer",
      "maximum": 100,
      "minimum": 1,
      "description": "Default 20"
    }
  }
}
get_appsflyer_attribution_summary annotations
{
  "title": "Summarize imported AppsFlyer attribution",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}

Prompts

1 advertised

integrate_fictura_sdk — Integrate the Fictura SDK

Advertised by the server during the last successful anonymous check.

Wire @fictura/sdk into an Expo / React Native app using this app's real credentials.

No arguments advertised.

Resources

Not advertised

No resource definitions available.

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
986 ms
95th percentile latency
986 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 986 ms · metadata changed · 44 tool(s), 1 prompt(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http fictura-mcp https://mcp.fictura.co/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add fictura-mcp --url https://mcp.fictura.co/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable fictura-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "fictura-mcp": {
      "url": "https://mcp.fictura.co/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "fictura-mcp": {
      "type": "streamableHttp",
      "url": "https://mcp.fictura.co/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start fictura-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "fictura-mcp": {
      "type": "http",
      "url": "https://mcp.fictura.co/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http fictura-mcp https://mcp.fictura.co/mcp

Claude Desktop

Merge this into claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\), then restart Claude Desktop.
Claude Desktop configuration
{
  "mcpServers": {
    "fictura-mcp": {
      "url": "https://mcp.fictura.co/mcp"
    }
  }
}

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "fictura-mcp": {
      "serverUrl": "https://mcp.fictura.co/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Fictura MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run Fictura MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing