{"name":"fine-structure-mcp","version":"1.0.0","description":"Fine Structure MCP Server - Create, update, and publish web applications using AI. Allows AI agents to generate complete web apps on behalf of users.","tools":[{"name":"create_app","description":"Create a new application from a natural language prompt. The AI generates a complete web app with pages, components, styling, and data models. Returns a job_id - poll get_job_status to track progress. When the job is done, the app is ready.","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Name for the app (1-100 chars)"},"prompt":{"type":"string","description":"Detailed description of the app to build"},"description":{"type":"string","description":"Optional short description","default":""}},"required":["name","prompt"]}},{"name":"agency_create_client","description":"Agency mode only. Create or update a client record for an account-level agent. This does not create a verified Fine Structure user account and does not transfer ownership.","inputSchema":{"type":"object","properties":{"client_email":{"type":"string","description":"Client email that will be allowed to claim projects"},"client_full_name":{"type":"string","description":"Optional client display name","default":""},"note":{"type":"string","description":"Optional internal note for the agency","default":""}},"required":["client_email"]}},{"name":"agency_list_clients","description":"Agency mode only. List client records and app handoff status for the authenticated agent.","inputSchema":{"type":"object","properties":{"include_handoffs":{"type":"boolean","description":"Include claim links status without raw tokens","default":true}}}},{"name":"agency_create_client_app","description":"Agency mode only. Create a new app owned by the agent, start generation, and create a claim link for the client. Ownership transfers only when the invited client logs in with the same email and accepts the claim link.","inputSchema":{"type":"object","properties":{"client_email":{"type":"string","description":"Client email allowed to claim ownership"},"client_full_name":{"type":"string","description":"Optional client display name","default":""},"name":{"type":"string","description":"Name for the app (1-100 chars)"},"prompt":{"type":"string","description":"Detailed description of the app to build"},"description":{"type":"string","description":"Optional short app description","default":""},"note":{"type":"string","description":"Optional internal client/project note","default":""},"keep_agent_collaborator":{"type":"boolean","description":"After claim, invite the agent back as an editor collaborator","default":true},"claim_expires_in_days":{"type":"integer","description":"Claim link lifetime, 1-90 days","default":14}},"required":["client_email","name","prompt"]}},{"name":"agency_create_claim_link","description":"Agency mode only. Create a client claim link for an existing app owned by the agent. The client must log in with the invited email before ownership transfers.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"Existing app ID owned by the agent"},"client_email":{"type":"string","description":"Client email allowed to claim ownership"},"client_full_name":{"type":"string","description":"Optional client display name","default":""},"note":{"type":"string","description":"Optional internal note","default":""},"keep_agent_collaborator":{"type":"boolean","description":"Invite agent as editor after claim","default":true},"claim_expires_in_days":{"type":"integer","description":"Claim link lifetime, 1-90 days","default":14}},"required":["app_id","client_email"]}},{"name":"agency_get_claim_status","description":"Agency mode only. Inspect one handoff status without exposing the raw claim token.","inputSchema":{"type":"object","properties":{"handoff_id":{"type":"string","description":"Handoff ID returned by agency_create_claim_link or agency_create_client_app"}},"required":["handoff_id"]}},{"name":"update_app","description":"Update an existing application with a new prompt. The AI modifies the app based on your instructions. Creates a Saved Version before the update. Returns a job_id - poll get_job_status to track progress.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID to update"},"prompt":{"type":"string","description":"What to change in the app"}},"required":["app_id","prompt"]}},{"name":"publish_app","description":"Publish an app - freeze current state and make it live at a URL. Also configures whether the public URL is open, app-login gated, private, or inferred from the app.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID to publish"},"access_mode":{"type":"string","enum":["infer","public_open","public_auth","private","keep"],"default":"infer","description":"Live access policy. public_open = anyone can view. public_auth = public URL opens but app login is required. private = published snapshot remains owner/collaborator-only. keep = preserve current visibility/auth settings. infer = choose from existing settings and obvious app structure."},"auth_required":{"type":"boolean","description":"Optional explicit override for generated-app login requirement. Prefer access_mode when possible."},"make_public":{"type":"boolean","description":"Optional explicit override for whether published URLs are publicly reachable. Prefer access_mode when possible."}},"required":["app_id"]}},{"name":"get_platform_guide","description":"Return a machine-readable Fine Structure / FSe2 guide for AI agents. Call this at the start of an MCP session to learn app files, entities, safe edit workflows, validation, publishing, A/B testing, secrets, and platform rules.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"Optional app ID. If provided, the guide includes a safe app context summary."},"sections":{"type":"array","description":"Optional subset of guide sections to return.","items":{"type":"string","enum":["ab_testing","agency","app_code","checklists","data_model","direct_file_edit","domains","file_model","generation","overview","publishing","saas","safety","sdk","secrets_integrations","security","validation"]}},"task_type":{"type":"string","description":"Optional task hint, for example edit_app, direct_file_edit, seed_data, or publish_app."}}}},{"name":"get_recommended_workflow","description":"Return the recommended MCP tool sequence for a task type. Use this before creating apps, editing files, seeding data, publishing, setting up A/B tests, restoring versions, or configuring secrets/integrations.","inputSchema":{"type":"object","properties":{"task_type":{"type":"string","description":"The task type to plan.","enum":["ab_test","agency_client_app","create_app","direct_file_edit","domain_setup","edit_app","fix_runtime_error","inspect_preview","publish_app","saas_setup","schema_change","secrets_integration","security_setup","seed_data","unknown","version_restore"],"default":"unknown"},"goal":{"type":"string","description":"Optional short description of the user's goal.","default":""},"app_id":{"type":"string","description":"Optional app ID. If provided, the workflow includes a safe app context summary."}}}},{"name":"get_job_status","description":"Poll the status of an async generation job. Use this after create_app or update_app to know when the job is done. Returns status ('running' or 'done'), progress events, and result summary when complete.","inputSchema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job_id returned by create_app or update_app"}},"required":["job_id"]}},{"name":"get_app_status","description":"Get app overview: files, published state, URL, active jobs.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"}},"required":["app_id"]}},{"name":"get_app_links","description":"Return editor, preview, published path, subdomain, and custom-domain links plus whether each works for anonymous visitors, app users, or Studio users based on publish and auth settings.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"}},"required":["app_id"]}},{"name":"list_app_domains","description":"List an app's platform path, subdomain, and configured custom domain with verification, SSL, primary-domain, redirect, publish, and login-gating status.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"}},"required":["app_id"]}},{"name":"add_custom_domain","description":"Attach or replace the app custom domain through the same Fine Structure Studio custom-domain flow. Returns exact DNS verification and routing records for the user to configure at their DNS provider.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"domain":{"type":"string","description":"Custom domain to connect, for example example.com or app.example.com"}},"required":["app_id","domain"]}},{"name":"get_domain_verification","description":"Return the exact DNS records and instructions required to verify and route the app custom domain.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"domain":{"type":"string","description":"Optional configured custom domain. If omitted, uses the app's current custom domain."}},"required":["app_id"]}},{"name":"check_domain_verification","description":"Check Fine Structure custom-domain verification and SSL status for the configured custom domain, then save the latest status.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"domain":{"type":"string","description":"Optional configured custom domain. If omitted, uses the app's current custom domain."}},"required":["app_id"]}},{"name":"set_primary_domain","description":"Set which app host should be treated as primary for generated links and custom-domain redirects.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"domain":{"type":"string","description":"Primary host, for example example.com, www.example.com, or the app subdomain host."}},"required":["app_id","domain"]}},{"name":"remove_custom_domain","description":"Remove the configured custom domain from the app and clean up the platform-side hostname registration when possible.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"domain":{"type":"string","description":"Optional configured custom domain. If omitted, removes the current custom domain."}},"required":["app_id"]}},{"name":"get_domain_ssl_status","description":"Return SSL/certificate status and pending certificate validation DNS records for the app custom domain.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"domain":{"type":"string","description":"Optional configured custom domain. If omitted, uses the app's current custom domain."}},"required":["app_id"]}},{"name":"configure_domain_redirects","description":"Configure custom-domain redirect policy: primary domain, optional www/root redirect, and HTTPS enforcement.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"primary_domain":{"type":"string","description":"Canonical primary domain, for example example.com"},"redirect_www":{"type":"boolean","description":"Redirect the www/root counterpart to primary_domain","default":true},"force_https":{"type":"boolean","description":"Redirect HTTP custom-domain requests to HTTPS","default":true}},"required":["app_id","primary_domain"]}},{"name":"list_apps","description":"List all applications owned by the authenticated user.","inputSchema":{"type":"object","properties":{}}},{"name":"get_app_files","description":"Get the file tree for an app with paths and byte sizes.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"}},"required":["app_id"]}},{"name":"read_app_file","description":"Read one source file from an app's virtual filesystem.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"path":{"type":"string","description":"Virtual file path, for example pages/Home.jsx"},"max_chars":{"type":"integer","description":"Maximum content characters to return","default":200000}},"required":["app_id","path"]}},{"name":"read_app_files","description":"Read several source files from an app's virtual filesystem.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"paths":{"type":"array","items":{"type":"string"},"description":"Virtual file paths to read"},"max_chars_per_file":{"type":"integer","description":"Maximum characters per file","default":100000}},"required":["app_id","paths"]}},{"name":"write_app_file","description":"Create or replace one file in an app's virtual filesystem. Creates a Saved Version before changing content.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"path":{"type":"string","description":"Virtual file path"},"content":{"type":"string","description":"Complete file contents"},"file_type":{"type":"string","description":"Optional file type override"}},"required":["app_id","path","content"]}},{"name":"patch_app_file","description":"Patch one file by replacing exact text. Safer than full overwrite for targeted edits. Creates a Saved Version before changing content.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"path":{"type":"string","description":"Virtual file path"},"old_text":{"type":"string","description":"Exact existing text to replace"},"new_text":{"type":"string","description":"Replacement text"},"replace_all":{"type":"boolean","description":"Replace all matches instead of the first match","default":false}},"required":["app_id","path","old_text","new_text"]}},{"name":"rename_app_file","description":"Rename or move one app source file atomically. Internally stages an upsert at new_path and a delete at old_path, validates the resulting app state, and creates a Saved Version before applying.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"old_path":{"type":"string","description":"Existing virtual file path to rename"},"new_path":{"type":"string","description":"New virtual file path"},"overwrite":{"type":"boolean","description":"Allow replacing an existing file at new_path","default":false},"force":{"type":"boolean","description":"Apply even if validation reports blocking errors","default":false}},"required":["app_id","old_path","new_path"]}},{"name":"get_app_detail","description":"Deep introspection of an app: entities, pages, settings, integrations, environment variables, and file structure. Use this to understand what an app contains before updating it.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"}},"required":["app_id"]}},{"name":"get_entities","description":"Get all entity (data model) schemas for an app, with record counts. Each entity has fields, types, and relationships.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"}},"required":["app_id"]}},{"name":"query_entity","description":"Query app data records for one entity with optional exact-match filters.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"entity":{"type":"string","description":"Entity name, for example Patient"},"filters":{"type":"object","description":"Exact-match field filters","default":{}},"sort":{"type":"string","description":"Sort field, prefix with - for descending","default":"-created_date"},"limit":{"type":"integer","description":"Max records to return","default":100},"offset":{"type":"integer","description":"Pagination offset","default":0}},"required":["app_id","entity"]}},{"name":"seed_entity","description":"Seed records into one app entity. Useful during EDIT when new screens need sample data. Creates a Saved Version before inserting records.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"entity":{"type":"string","description":"Entity name"},"records":{"type":"array","items":{"type":"object"},"description":"Records to insert"},"mode":{"type":"string","enum":["append","skip_if_not_empty"],"description":"append always inserts; skip_if_not_empty inserts only into an empty entity","default":"skip_if_not_empty"}},"required":["app_id","entity","records"]}},{"name":"update_entity_record","description":"Update one app entity record by ID. Creates a Saved Version before the update.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"entity":{"type":"string","description":"Entity name"},"record_id":{"type":"string","description":"Record ID"},"data":{"type":"object","description":"Fields to merge into the record"}},"required":["app_id","entity","record_id","data"]}},{"name":"get_pages","description":"Get all pages in an app with their file paths and sizes.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"}},"required":["app_id"]}},{"name":"get_errors","description":"Get recent runtime errors for an app (last 20). Useful for diagnosing issues before updating.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"limit":{"type":"integer","description":"Max errors to return (default 20)","default":20}},"required":["app_id"]}},{"name":"get_preview_url","description":"Return editor preview and published/public URLs for an app.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"}},"required":["app_id"]}},{"name":"list_saved_versions","description":"List restorable Saved Versions for an app, including versions created by MCP writes.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"}},"required":["app_id"]}},{"name":"restore_saved_version","description":"Restore an app to a Saved Version. Requires versions:write scope and confirm=true. This restores files, records, app settings, and A/B test state captured in the snapshot.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"snapshot_id":{"type":"string","description":"Saved Version snapshot_id to restore"},"confirm":{"type":"boolean","description":"Must be true to execute the restore","default":false}},"required":["app_id","snapshot_id","confirm"]}},{"name":"create_change_set","description":"Create a staged file change set. Add multiple file changes, validate them as one app state, then apply atomically.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"label":{"type":"string","description":"Optional short label"}},"required":["app_id"]}},{"name":"add_file_change","description":"Stage one file upsert or delete inside a change set. Does not modify the live app until apply_change_set.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"change_set_id":{"type":"string","description":"Change set ID"},"path":{"type":"string","description":"Virtual file path"},"content":{"type":"string","description":"Complete file contents for upsert","default":""},"file_type":{"type":"string","description":"Optional file type override","default":""},"operation":{"type":"string","enum":["upsert","delete"],"default":"upsert"}},"required":["app_id","change_set_id","path"]}},{"name":"validate_change_set","description":"Validate current app files plus staged change set files before applying.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"change_set_id":{"type":"string","description":"Change set ID"},"include_runtime_errors":{"type":"boolean","default":true}},"required":["app_id","change_set_id"]}},{"name":"apply_change_set","description":"Apply a staged change set to the app. Creates a Saved Version before applying. Blocks on validation errors unless force=true.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"change_set_id":{"type":"string","description":"Change set ID"},"force":{"type":"boolean","description":"Apply even if validation has errors","default":false}},"required":["app_id","change_set_id"]}},{"name":"discard_change_set","description":"Discard a pending staged change set without changing app files.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"change_set_id":{"type":"string","description":"Change set ID"}},"required":["app_id","change_set_id"]}},{"name":"validate_app","description":"Run deterministic app checks: syntax, imports, routes/pages, entity schemas, missing entities, and recorded runtime errors.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"include_runtime_errors":{"type":"boolean","default":true}},"required":["app_id"]}},{"name":"inspect_preview","description":"Return server-side preview context: URLs, persisted runtime/network errors, static clickable candidates, pages, and explicit live-browser availability.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"route":{"type":"string","description":"Optional route to inspect","default":""},"auth_as":{"type":"string","description":"Optional auth simulation: anonymous","default":""},"auth_as_role":{"type":"string","description":"Optional app role simulation, e.g. staff/admin/customer","default":""}},"required":["app_id"]}},{"name":"get_app_security_context","description":"Return safe security context for one owned app: owner id/email, Studio collaborators, generated-app members, route policies, entity policies, and recent security audit entries. Does not return secrets and does not grant access to other apps.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"audit_limit":{"type":"integer","default":50}},"required":["app_id"]}},{"name":"set_route_policy","description":"Create or update a server-owned route policy for a generated app route.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"route":{"type":"string","description":"Route or wildcard route, e.g. /admin/*"},"require_auth":{"type":"boolean","default":true},"allowed_roles":{"type":"array","items":{"type":"string"},"description":"Allowed app roles"},"redirect_to":{"type":"string","default":"/Login"}},"required":["app_id","route","require_auth","allowed_roles"]}},{"name":"set_entity_policy","description":"Create or update server-side read/write role policy for an app entity.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"entity":{"type":"string","description":"Entity name, e.g. Booking"},"read":{"type":"array","items":{"type":"string"},"description":"Roles allowed to read"},"write":{"type":"array","items":{"type":"string"},"description":"Roles allowed to write"}},"required":["app_id","entity","read","write"]}},{"name":"list_app_members","description":"List generated-app runtime users/members for an app. This is separate from Studio project collaborators.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"}},"required":["app_id"]}},{"name":"invite_app_member","description":"Provision a generated-app runtime member with a role. This does not create a Studio collaborator. The owner role cannot be assigned. If password is omitted, a temporary password is generated and returned once.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"email":{"type":"string","description":"Member email"},"role":{"type":"string","description":"App role, e.g. admin/staff/customer"},"full_name":{"type":"string","default":""},"password":{"type":"string","description":"Optional initial password. If omitted, one is generated."}},"required":["app_id","email","role"]}},{"name":"update_app_member_role","description":"Update a generated-app runtime member role. This cannot assign owner and cannot change the Fine Structure account owner.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"user_id":{"type":"string","description":"Generated app user id"},"role":{"type":"string","description":"New role"}},"required":["app_id","user_id","role"]}},{"name":"remove_app_member","description":"Remove a generated-app runtime member.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"user_id":{"type":"string","description":"Generated app user id"}},"required":["app_id","user_id"]}},{"name":"get_app_security_audit","description":"Read recent server-side security audit events for an app.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"limit":{"type":"integer","default":100}},"required":["app_id"]}},{"name":"compare_saved_versions","description":"Compare two Saved Versions and return per-file additions, removals, modifications, and compact diffs.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"base_snapshot_id":{"type":"string","description":"Older/base snapshot ID"},"target_snapshot_id":{"type":"string","description":"Newer/target snapshot ID"},"max_diff_chars":{"type":"integer","default":12000}},"required":["app_id","base_snapshot_id","target_snapshot_id"]}},{"name":"compare_current_to_version","description":"Compare the current app files to a Saved Version and return compact per-file diffs.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"snapshot_id":{"type":"string","description":"Saved Version snapshot ID"},"max_diff_chars":{"type":"integer","default":12000}},"required":["app_id","snapshot_id"]}},{"name":"restore_file_from_version","description":"Restore one file from a Saved Version instead of restoring the entire app. Creates a Saved Version before changing the file.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"snapshot_id":{"type":"string","description":"Saved Version snapshot ID"},"path":{"type":"string","description":"Virtual file path to restore"},"confirm":{"type":"boolean","default":false}},"required":["app_id","snapshot_id","path","confirm"]}},{"name":"create_entity_schema","description":"Create an entity schema file in entities/<Entity>.json. Creates a Saved Version before writing.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"entity":{"type":"string","description":"Entity name"},"schema":{"type":"object","description":"JSON schema object"},"relationships":{"type":"array","items":{"type":"object"},"default":[]},"indexes":{"type":"array","items":{"type":"object"},"default":[]},"metadata":{"type":"object","default":{}},"overwrite":{"type":"boolean","default":false}},"required":["app_id","entity","schema"]}},{"name":"update_entity_schema","description":"Replace or shallow-merge an existing entity schema file. Creates a Saved Version before writing.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"entity":{"type":"string","description":"Entity name"},"schema":{"type":"object","description":"Schema fields to set or merge"},"relationships":{"type":"array","items":{"type":"object"},"default":[]},"indexes":{"type":"array","items":{"type":"object"},"default":[]},"metadata":{"type":"object","default":{}},"merge":{"type":"boolean","default":true}},"required":["app_id","entity","schema"]}},{"name":"validate_entity_relationships","description":"Validate entity relationship metadata and *_id references against existing entity schemas.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"}},"required":["app_id"]}},{"name":"update_entity_metadata","description":"Set relationship/index metadata on an entity schema. This stores metadata in the schema file; DB index creation is automatic where supported by the platform.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"entity":{"type":"string","description":"Entity name"},"relationships":{"type":"array","items":{"type":"object"},"default":[]},"indexes":{"type":"array","items":{"type":"object"},"default":[]},"metadata":{"type":"object","default":{}}},"required":["app_id","entity"]}},{"name":"list_secret_keys","description":"List secret key names for an app. Secret values are never returned.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"}},"required":["app_id"]}},{"name":"set_secret","description":"Create or update one encrypted app secret. The secret value is never returned.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"key":{"type":"string","description":"Secret key name"},"value":{"type":"string","description":"Secret value to encrypt and store"}},"required":["app_id","key","value"]}},{"name":"delete_secret","description":"Delete one app secret by key.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"key":{"type":"string","description":"Secret key name"}},"required":["app_id","key"]}},{"name":"list_integrations","description":"List supported integrations and safe connected integration metadata for an app. Tokens/secrets are never returned.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"}},"required":["app_id"]}},{"name":"configure_integration","description":"Store safe non-secret integration metadata for an app. Use set_secret for API keys/tokens.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"provider":{"type":"string","description":"Integration provider ID"},"config":{"type":"object","description":"Safe metadata only, such as workspace/team/name/email"},"is_active":{"type":"boolean","description":"Set false to disconnect this integration metadata","default":true}},"required":["app_id","provider","config"]}},{"name":"list_ab_tests","description":"List the platform A/B tests configured for an app.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"}},"required":["app_id"]}},{"name":"create_ab_test","description":"Create a native Fine Structure A/B test between existing app pages. Use update_app first if a variant page still needs to be generated. Creates a Saved Version before the change.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"name":{"type":"string","description":"Experiment name"},"page_name":{"type":"string","description":"Base route page that triggers the experiment"},"variants":{"type":"array","items":{"type":"object","properties":{"page_name":{"type":"string","description":"Existing app page name or path"},"traffic_percent":{"type":"integer","description":"Traffic percentage for this variant"}},"required":["page_name","traffic_percent"]},"description":"At least two variants. Traffic must total 100."},"goal_event_type":{"type":"string","description":"Optional conversion goal type: entity_create, any, form_submit"},"goal_event_filter":{"type":"object","description":"Optional goal filter, for example {'entity_name': 'Lead'}"},"is_active":{"type":"boolean","description":"Whether to activate the test immediately","default":true}},"required":["app_id","name","page_name","variants"]}},{"name":"update_ab_test","description":"Update a native A/B test, including active state, variants, traffic, and conversion goal. Creates a Saved Version before the change.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"test_id":{"type":"string","description":"A/B test ID"},"name":{"type":"string","description":"Optional new name"},"page_name":{"type":"string","description":"Optional new base route page"},"variants":{"type":"array","items":{"type":"object"},"description":"Optional replacement variants. Traffic must total 100."},"is_active":{"type":"boolean","description":"Optional active state"},"goal_event_type":{"type":"string","description":"Optional conversion goal type"},"goal_event_filter":{"type":"object","description":"Optional conversion goal filter"}},"required":["app_id","test_id"]}},{"name":"delete_ab_test","description":"Delete a native A/B test from an app. Creates a Saved Version before the change.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"test_id":{"type":"string","description":"A/B test ID"}},"required":["app_id","test_id"]}},{"name":"get_ab_test_stats","description":"Get views, unique visitors, conversions, and conversion rates for an A/B test.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"test_id":{"type":"string","description":"A/B test ID"}},"required":["app_id","test_id"]}},{"name":"email_marketing_status","description":"Admin only. Inspect the isolated Email Marketing module: enabled state, sender settings, templates, sequences, variable triggers, and recent campaign status.","inputSchema":{"type":"object","properties":{"include_logs":{"type":"boolean","description":"Include recent delivery logs","default":false}}}},{"name":"email_marketing_configure_sender","description":"Admin only. Configure global Email Marketing sender details and module enabled state. Unsubscribe footer remains mandatory.","inputSchema":{"type":"object","properties":{"is_enabled":{"type":"boolean","description":"Enable or disable the module at settings level"},"sender_name":{"type":"string","description":"Display sender name"},"sender_email":{"type":"string","description":"Sender email address used by the email provider"},"reply_to":{"type":"string","description":"Reply-To email address"},"organization_name":{"type":"string","description":"Organization name used in unsubscribe footer"},"postal_address":{"type":"string","description":"Optional postal/contact address for compliance"},"default_timezone":{"type":"string","description":"Default timezone for scheduling"}}}},{"name":"email_marketing_update_template","description":"Admin only. Update an automatic Email Marketing template, such as user_joined welcome email. The unsubscribe block is still appended by the server.","inputSchema":{"type":"object","properties":{"template_id":{"type":"string","description":"Template/event id, e.g. user_joined"},"enabled":{"type":"boolean","description":"Whether this automatic template is active"},"subject":{"type":"string","description":"Email subject with {{variables}}"},"body_html":{"type":"string","description":"HTML body with {{variables}}"}},"required":["template_id"]}},{"name":"email_marketing_create_broadcast","description":"Admin only. Create a filtered broadcast campaign, optionally scheduled or sent now.","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Internal campaign name"},"subject":{"type":"string","description":"Email subject"},"body_html":{"type":"string","description":"HTML body. Unsubscribe is appended automatically."},"filters":{"type":"object","description":"Recipient filters: plans, roles, active_status, email_verified, min_apps, max_apps, has_published_app, search"},"scheduled_at":{"type":"string","description":"Optional ISO datetime. If no timezone is included, timezone is used."},"timezone":{"type":"string","description":"Timezone for naive scheduled_at","default":"UTC"},"send_now":{"type":"boolean","description":"Send immediately after creating the campaign","default":false}},"required":["subject","body_html"]}},{"name":"email_marketing_create_sequence","description":"Admin only. Create a scheduled email sequence using fixed dates or day offsets. Each generated email keeps mandatory unsubscribe.","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Sequence name"},"schedule_mode":{"type":"string","enum":["fixed_dates","day_offsets"],"description":"fixed_dates uses each step.scheduled_at; day_offsets uses start_at + step day offsets"},"filters":{"type":"object","description":"Recipient filters"},"start_at":{"type":"string","description":"ISO datetime for day_offsets mode"},"timezone":{"type":"string","default":"UTC"},"steps":{"type":"array","items":{"type":"object"},"description":"Steps with subject, body_html, and either scheduled_at (fixed_dates) or day_offset/gap_days (day_offsets)."}},"required":["name","schedule_mode","steps"]}},{"name":"email_marketing_create_variable_trigger","description":"Admin only. Create an email rule that sends when a named variable changes from one value to another. Empty from_value/to_value acts as wildcard.","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Trigger name"},"enabled":{"type":"boolean","default":true},"variable_name":{"type":"string","description":"Variable name, e.g. plan"},"from_value":{"type":"string","description":"Previous value or empty wildcard"},"to_value":{"type":"string","description":"New value or empty wildcard"},"subject":{"type":"string","description":"Email subject"},"body_html":{"type":"string","description":"HTML body. Unsubscribe is appended automatically."},"filters":{"type":"object","description":"Optional recipient filters"}},"required":["variable_name","subject","body_html"]}},{"name":"email_marketing_trigger_variable","description":"Admin only. Manually fire variable-transition email rules for one user. Useful for MCP/agent workflows and tests.","inputSchema":{"type":"object","properties":{"user_id":{"type":"string","description":"Platform user id"},"variable_name":{"type":"string","description":"Variable name"},"from_value":{"type":"string","description":"Previous value"},"to_value":{"type":"string","description":"New value"},"context":{"type":"object","description":"Extra template variables"}},"required":["user_id","variable_name"]}},{"name":"email_marketing_app_status","description":"Inspect app-scoped Email Marketing for one generated app: settings, contacts, campaigns, event triggers, and recent events.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"include_logs":{"type":"boolean","default":false}},"required":["app_id"]}},{"name":"email_marketing_app_configure","description":"Configure isolated Email Marketing settings for a generated app. Can be used by Studio/chat agents.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"is_enabled":{"type":"boolean"},"default_contact_entity":{"type":"string","description":"Entity to sync as contacts, e.g. Customer or Lead"},"default_email_field":{"type":"string","description":"Field containing contact email"},"default_name_field":{"type":"string","description":"Field containing contact name"},"sender_name":{"type":"string"},"sender_email":{"type":"string"},"reply_to":{"type":"string"}},"required":["app_id"]}},{"name":"email_marketing_app_sync_contacts","description":"Sync an app entity table into app-scoped Email Marketing contacts. Records without a valid email are skipped.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"entity_name":{"type":"string","description":"Entity name, e.g. Customer or Lead"},"email_field":{"type":"string","default":"email"},"name_field":{"type":"string"},"limit":{"type":"integer","default":1000}},"required":["app_id","entity_name"]}},{"name":"email_marketing_app_create_broadcast","description":"Create an app-scoped broadcast to contacts synced from that generated app, optionally scheduled or sent now.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"name":{"type":"string"},"subject":{"type":"string"},"body_html":{"type":"string"},"filters":{"type":"object","description":"App contact filters such as source_entity, search, tags, field_equals"},"scheduled_at":{"type":"string"},"timezone":{"type":"string","default":"UTC"},"send_now":{"type":"boolean","default":false}},"required":["app_id","subject","body_html"]}},{"name":"email_marketing_app_create_event_trigger","description":"Create an app-scoped email rule that sends when an app event is recorded, for example entity_created or Customer.created.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"name":{"type":"string"},"enabled":{"type":"boolean","default":true},"event_name":{"type":"string","description":"Event name, e.g. entity_created, Customer.created, order_paid"},"entity_name":{"type":"string","description":"Optional entity filter"},"subject":{"type":"string"},"body_html":{"type":"string"},"filters":{"type":"object","description":"Optional app contact filters"}},"required":["app_id","event_name","subject","body_html"]}},{"name":"email_marketing_app_record_event","description":"Record an app event and send matching app-scoped Email Marketing triggers.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"event_name":{"type":"string"},"email":{"type":"string","description":"Contact email if no contact_id is known"},"contact_id":{"type":"string"},"entity_name":{"type":"string"},"record_id":{"type":"string"},"record":{"type":"object","description":"Entity record fields for template variables and contact extraction"},"properties":{"type":"object","description":"Extra event properties"}},"required":["app_id","event_name"]}},{"name":"email_marketing_app_create_workflow","description":"Create an app-scoped automation workflow with email, wait, condition, split, and goal steps.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"name":{"type":"string"},"enabled":{"type":"boolean","default":true},"trigger_event_name":{"type":"string","description":"Event that enrolls a contact, e.g. Customer.created"},"trigger_entity_name":{"type":"string","description":"Optional entity filter"},"steps":{"type":"array","description":"Ordered workflow steps. Supported type values: email, wait, condition, split, goal.","items":{"type":"object"}},"definition":{"type":"object","description":"Optional full workflow definition; steps can also be supplied here."}},"required":["app_id","trigger_event_name"]}},{"name":"email_marketing_app_create_sequence","description":"Create an app-scoped email sequence using fixed dates or day offsets between emails.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"name":{"type":"string"},"schedule_mode":{"type":"string","enum":["fixed_dates","day_offsets"],"default":"day_offsets"},"start_at":{"type":"string","description":"Sequence start date/time for day_offsets mode"},"timezone":{"type":"string","default":"UTC"},"filters":{"type":"object","description":"App contact filters"},"steps":{"type":"array","description":"Emails in order. Each step supports subject, body_html, scheduled_at, day_offset, or gap_days.","items":{"type":"object"}}},"required":["app_id","steps"]}},{"name":"email_marketing_app_report","description":"Read app-scoped Email Marketing reporting: delivery counts, open/click rates, and recent tracking events.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"include_events":{"type":"boolean","default":true},"limit":{"type":"integer","default":50},"segment_limit":{"type":"integer","default":25}},"required":["app_id"]}},{"name":"email_marketing_app_create_segment","description":"Create an app-scoped saved audience segment using field, tag, and behavior filters.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"name":{"type":"string"},"filters":{"type":"object","description":"Segment filters. Supports rules with field/operator/value plus opened/clicked/sent behavior fields."},"sample_limit":{"type":"integer","default":10}},"required":["app_id","name","filters"]}},{"name":"email_marketing_app_contact_profile","description":"Read a contact profile with email delivery, tracking, app-event, workflow, suppression, and unsubscribe timeline.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"contact":{"type":"string","description":"Contact id or email address"}},"required":["app_id","contact"]}},{"name":"email_marketing_app_deliverability","description":"Read provider readiness, bounce/complaint rates, suppression reasons, and recent deliverability risk events.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"}},"required":["app_id"]}},{"name":"email_marketing_app_process_queue","description":"Process due app-scoped automation workflow runs and email queue jobs with locks, retries, and suppression checks.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"max_jobs":{"type":"integer","default":50}},"required":["app_id"]}},{"name":"email_marketing_app_queue_status","description":"Inspect app-scoped Email Marketing queue jobs and per-status counts.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"limit":{"type":"integer","default":50},"status":{"type":"string","description":"Optional queue status filter"}},"required":["app_id"]}},{"name":"email_marketing_app_suppress_contact","description":"Suppress an app contact email after a bounce, complaint, manual block, provider block, or unsubscribe.","inputSchema":{"type":"object","properties":{"app_id":{"type":"string","description":"The app ID"},"email":{"type":"string"},"reason":{"type":"string","default":"manual"},"source":{"type":"string","default":"mcp"},"metadata":{"type":"object"}},"required":["app_id","email"]}}],"authentication":{"type":"bearer","description":"Use an MCP token obtained from the Fine Structure dashboard. Pass it as: Authorization: Bearer fse2_mcp_<token>"}}