# Fine Structure (remote · finestructure.ai)

Remote MCP server for agents that create, edit, validate, and publish Fine Structure apps.

- Trust score: 64/100 (medium)
- Change this week: +4
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-04

## Components

- remote · `finestructure.ai`: 64/100 (this document), [markdown](https://verifymcp.io/servers/ai-finestructure-fine-structure/api-mcp.md), [page](https://verifymcp.io/servers/ai-finestructure-fine-structure/api-mcp)

## Channel facts

- Endpoint: `https://finestructure.ai/api/mcp`
- Transports: `streamable-http`
- Auth: `required`
- Version: `1.0.0`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-04.

- **Endpoint Security**: 63/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation not fully verified: no authorisation is required to call this server, and 95 tool(s) never declared a destructiveHint. The MCP spec treats an absent hint as destructive by default, so we cannot call this surface safe.
  - HTTPS is enforced; there's no plaintext access path.
  - The HSTS (Strict-Transport-Security) header is present.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 71/100
  - AI-judged instruction clarity (good).
  - Tool/resource definitions use about 7378 tokens (~77/item across 95 items; 95 tools + 0 resources), lean.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 29/100
  - Stability check failed: schema churn in the 9 days we've observed: 0 tool removals, 1 breaking changes, 0 auth/transport breaks, 3 additions.
- **Tool Coverage**: 94/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 82% of tool parameters carry a description.
- **Capabilities**: 20/100
  - Spec-recency check failed: implements MCP spec 2024-11-05; the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add --transport http ai-finestructure-fine-structure https://finestructure.ai/api/mcp
```

### Codex

```toml
[mcp_servers.ai-finestructure-fine-structure]
url = "https://finestructure.ai/api/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "ai-finestructure-fine-structure": {
      "type": "remote",
      "url": "https://finestructure.ai/api/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add ai-finestructure-fine-structure --url https://finestructure.ai/api/mcp --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  ai-finestructure-fine-structure:
    url: "https://finestructure.ai/api/mcp"
```

### Other

```json
{
  "mcpServers": {
    "ai-finestructure-fine-structure": {
      "type": "http",
      "url": "https://finestructure.ai/api/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-03 (score 64, +1)

- [security regression] Stability: 0.23 → fail
- [security regression] A breaking change shipped without a version bump: still 1.0.0
- [security] Tool “update_entity_record” rewrote its description, which is the text the model reads
- [security] Tool “restore_saved_version” rewrote its description, which is the text the model reads
- [security] Tool “seed_entity” rewrote its description, which is the text the model reads
- [functional regression] “restore_saved_version” dropped the required parameter “confirm”
- [functional] New tool “create_entity_records”
- [functional] New tool “delete_entity_records”
- [functional] New tool “update_entity_records”
- [cosmetic] “seed_entity” added an optional parameter “reason”
- [cosmetic] “update_entity_record” added an optional parameter “reason”
- [cosmetic] “restore_saved_version” reworded the description of “snapshot_id”
- [cosmetic] “seed_entity” reworded the description of “mode”
- [cosmetic] “seed_entity” reworded the description of “records”

### 2026-08-01 (score 63, +1)

No change was recorded against any check on this day. Stability & Change Management went from 17 to 20. That category is still filling its 30-day observation window: 5 days of observed history at the previous scan, 6 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-31 (score 62, +1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 61, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-29 (score 61, +1)

No change was recorded against any check on this day. Stability & Change Management went from 7 to 10. That category is still filling its 30-day observation window: 2 days of observed history at the previous scan, 3 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-28 (score 60, +1)

No change was recorded against any check on this day. Stability & Change Management went from 3 to 7. That category is still filling its 30-day observation window: 1 days of observed history at the previous scan, 2 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-27 (score 59, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-26 (score 59)

First indexed and scored.

## MCP tools (95)

### `create_app` (~100 tokens)

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.

Input parameters:

- `description` (string): Optional short description
- `name` (string, required): Name for the app (1-100 chars)
- `prompt` (string, required): Detailed description of the app to build

### `agency_create_client` (~84 tokens)

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.

Input parameters:

- `client_email` (string, required): Client email that will be allowed to claim projects
- `client_full_name` (string): Optional client display name
- `note` (string): Optional internal note for the agency

### `agency_list_clients` (~43 tokens)

Agency mode only. List client records and app handoff status for the authenticated agent.

Input parameters:

- `include_handoffs` (boolean): Include claim links status without raw tokens

### `agency_create_client_app` (~176 tokens)

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.

Input parameters:

- `claim_expires_in_days` (integer): Claim link lifetime, 1-90 days
- `client_email` (string, required): Client email allowed to claim ownership
- `client_full_name` (string): Optional client display name
- `description` (string): Optional short app description
- `keep_agent_collaborator` (boolean): After claim, invite the agent back as an editor collaborator
- `name` (string, required): Name for the app (1-100 chars)
- `note` (string): Optional internal client/project note
- `prompt` (string, required): Detailed description of the app to build

### `agency_create_claim_link` (~130 tokens)

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.

Input parameters:

- `app_id` (string, required): Existing app ID owned by the agent
- `claim_expires_in_days` (integer): Claim link lifetime, 1-90 days
- `client_email` (string, required): Client email allowed to claim ownership
- `client_full_name` (string): Optional client display name
- `keep_agent_collaborator` (boolean): Invite agent as editor after claim
- `note` (string): Optional internal note

### `agency_get_claim_status` (~49 tokens)

Agency mode only. Inspect one handoff status without exposing the raw claim token.

Input parameters:

- `handoff_id` (string, required): Handoff ID returned by agency_create_claim_link or agency_create_client_app

### `update_app` (~74 tokens)

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.

Input parameters:

- `app_id` (string, required): The app ID to update
- `prompt` (string, required): What to change in the app

### `publish_app` (~165 tokens)

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.

Input parameters:

- `access_mode` (string): 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 visi…
- `app_id` (string, required): The app ID to publish
- `auth_required` (boolean): Optional explicit override for generated-app login requirement. Prefer access_mode when possible.
- `make_public` (boolean): Optional explicit override for whether published URLs are publicly reachable. Prefer access_mode when possible.

### `get_platform_guide` (~123 tokens)

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.

Input parameters:

- `app_id` (string): Optional app ID. If provided, the guide includes a safe app context summary.
- `sections` (array): Optional subset of guide sections to return.
- `task_type` (string): Optional task hint, for example edit_app, direct_file_edit, seed_data, or publish_app.

### `get_recommended_workflow` (~103 tokens)

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.

Input parameters:

- `app_id` (string): Optional app ID. If provided, the workflow includes a safe app context summary.
- `goal` (string): Optional short description of the user's goal.
- `task_type` (string): The task type to plan.

### `get_job_status` (~70 tokens)

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.

Input parameters:

- `job_id` (string, required): The job_id returned by create_app or update_app

### `get_app_status` (~34 tokens)

Get app overview: files, published state, URL, active jobs.

Input parameters:

- `app_id` (string, required): The app ID

### `get_app_links` (~56 tokens)

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.

Input parameters:

- `app_id` (string, required): The app ID

### `list_app_domains` (~52 tokens)

List an app's platform path, subdomain, and configured custom domain with verification, SSL, primary-domain, redirect, publish, and login-gating status.

Input parameters:

- `app_id` (string, required): The app ID

### `add_custom_domain` (~74 tokens)

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.

Input parameters:

- `app_id` (string, required): The app ID
- `domain` (string, required): Custom domain to connect, for example example.com or app.example.com

### `get_domain_verification` (~60 tokens)

Return the exact DNS records and instructions required to verify and route the app custom domain.

Input parameters:

- `app_id` (string, required): The app ID
- `domain` (string): Optional configured custom domain. If omitted, uses the app's current custom domain.

### `check_domain_verification` (~64 tokens)

Check Fine Structure custom-domain verification and SSL status for the configured custom domain, then save the latest status.

Input parameters:

- `app_id` (string, required): The app ID
- `domain` (string): Optional configured custom domain. If omitted, uses the app's current custom domain.

### `set_primary_domain` (~62 tokens)

Set which app host should be treated as primary for generated links and custom-domain redirects.

Input parameters:

- `app_id` (string, required): The app ID
- `domain` (string, required): Primary host, for example example.com, www.example.com, or the app subdomain host.

### `remove_custom_domain` (~59 tokens)

Remove the configured custom domain from the app and clean up the platform-side hostname registration when possible.

Input parameters:

- `app_id` (string, required): The app ID
- `domain` (string): Optional configured custom domain. If omitted, removes the current custom domain.

### `get_domain_ssl_status` (~60 tokens)

Return SSL/certificate status and pending certificate validation DNS records for the app custom domain.

Input parameters:

- `app_id` (string, required): The app ID
- `domain` (string): Optional configured custom domain. If omitted, uses the app's current custom domain.

### `configure_domain_redirects` (~87 tokens)

Configure custom-domain redirect policy: primary domain, optional www/root redirect, and HTTPS enforcement.

Input parameters:

- `app_id` (string, required): The app ID
- `force_https` (boolean): Redirect HTTP custom-domain requests to HTTPS
- `primary_domain` (string, required): Canonical primary domain, for example example.com
- `redirect_www` (boolean): Redirect the www/root counterpart to primary_domain

### `list_apps` (~17 tokens)

List all applications owned by the authenticated user.

### `get_app_files` (~33 tokens)

Get the file tree for an app with paths and byte sizes.

Input parameters:

- `app_id` (string, required): The app ID

### `read_app_file` (~60 tokens)

Read one source file from an app's virtual filesystem.

Input parameters:

- `app_id` (string, required): The app ID
- `max_chars` (integer): Maximum content characters to return
- `path` (string, required): Virtual file path, for example pages/Home.jsx

### `read_app_files` (~57 tokens)

Read several source files from an app's virtual filesystem.

Input parameters:

- `app_id` (string, required): The app ID
- `max_chars_per_file` (integer): Maximum characters per file
- `paths` (array, required): Virtual file paths to read

### `write_app_file` (~72 tokens)

Create or replace one file in an app's virtual filesystem. Creates a Saved Version before changing content.

Input parameters:

- `app_id` (string, required): The app ID
- `content` (string, required): Complete file contents
- `file_type` (string): Optional file type override
- `path` (string, required): Virtual file path

### `patch_app_file` (~94 tokens)

Patch one file by replacing exact text. Safer than full overwrite for targeted edits. Creates a Saved Version before changing content.

Input parameters:

- `app_id` (string, required): The app ID
- `new_text` (string, required): Replacement text
- `old_text` (string, required): Exact existing text to replace
- `path` (string, required): Virtual file path
- `replace_all` (boolean): Replace all matches instead of the first match

### `rename_app_file` (~115 tokens)

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.

Input parameters:

- `app_id` (string, required): The app ID
- `force` (boolean): Apply even if validation reports blocking errors
- `new_path` (string, required): New virtual file path
- `old_path` (string, required): Existing virtual file path to rename
- `overwrite` (boolean): Allow replacing an existing file at new_path

### `get_app_detail` (~54 tokens)

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.

Input parameters:

- `app_id` (string, required): The app ID

### `get_entities` (~45 tokens)

Get all entity (data model) schemas for an app, with record counts. Each entity has fields, types, and relationships.

Input parameters:

- `app_id` (string, required): The app ID

### `query_entity` (~91 tokens)

Query app data records for one entity with optional exact-match filters.

Input parameters:

- `app_id` (string, required): The app ID
- `entity` (string, required): Entity name, for example Patient
- `filters` (object): Exact-match field filters
- `limit` (integer): Max records to return
- `offset` (integer): Pagination offset
- `sort` (string): Sort field, prefix with - for descending

### `seed_entity` (~126 tokens)

Compatibility tool for proposing starter-record creation. It never inserts records directly: it creates a pending approval that the app owner must approve or reject in Studio chat. Approval-free initial seed is server-controlled inside create_app and cannot be requested through MCP.

Input parameters:

- `app_id` (string, required): The app ID
- `entity` (string, required): Entity name
- `mode` (string): append always proposes creation; skip_if_not_empty proposes only when the entity is empty
- `reason` (string): Why these records should be created
- `records` (array, required): Records to propose for creation after approval

### `create_entity_records` (~99 tokens)

Propose creating/inserting records in one app entity. No records are written until the app owner explicitly approves the frozen request in Studio chat.

Input parameters:

- `app_id` (string, required): The app ID
- `entity` (string, required): Entity name
- `expected_count` (integer): Optional safety check for the number of proposed records
- `reason` (string): Why these records should be created
- `records` (array, required): Records to create after approval

### `update_entity_record` (~97 tokens)

Compatibility tool for proposing an update to one record by ID. It returns a pending approval and never changes the record until the app owner approves it in Studio chat.

Input parameters:

- `app_id` (string, required): The app ID
- `data` (object, required): Fields to merge into the record
- `entity` (string, required): Entity name
- `reason` (string): Why this record should be updated
- `record_id` (string, required): Record ID

### `update_entity_records` (~160 tokens)

Propose updates to exact records. Select explicit record_ids or exact-match filters and provide shared changes, or provide per-record updates. The database remains unchanged until the app owner approves the frozen request in Studio chat.

Input parameters:

- `app_id` (string, required): The app ID
- `changes` (object): Shared fields to merge into every selected record
- `entity` (string, required): Entity name
- `expected_count` (integer): Required match count safety check, when known
- `filters`: One exact-match selector or a list of exact-match selectors
- `reason` (string): Why these records should be updated
- `record_ids` (array): Exact record IDs to update
- `updates` (array): Per-record changes; use instead of shared changes

### `delete_entity_records` (~123 tokens)

Propose deleting exact records by ID or exact-match filters. It freezes the matched IDs and returns a pending approval; zero records are deleted until the app owner approves in Studio chat.

Input parameters:

- `app_id` (string, required): The app ID
- `entity` (string, required): Entity name
- `expected_count` (integer): Required match count safety check, when known
- `filters`: One exact-match selector or a list of exact-match selectors
- `reason` (string): Why these records should be deleted
- `record_ids` (array): Exact record IDs to delete

### `get_pages` (~32 tokens)

Get all pages in an app with their file paths and sizes.

Input parameters:

- `app_id` (string, required): The app ID

### `get_errors` (~53 tokens)

Get recent runtime errors for an app (last 20). Useful for diagnosing issues before updating.

Input parameters:

- `app_id` (string, required): The app ID
- `limit` (integer): Max errors to return (default 20)

### `get_preview_url` (~31 tokens)

Return editor preview and published/public URLs for an app.

Input parameters:

- `app_id` (string, required): The app ID

### `list_saved_versions` (~36 tokens)

List restorable Saved Versions for an app, including versions created by MCP writes.

Input parameters:

- `app_id` (string, required): The app ID

### `restore_saved_version` (~94 tokens)

Compatibility endpoint for full Saved Version restore. MCP cannot execute this operation because it can replace database records without the dedicated in-chat approval flow. Use list_saved_versions and compare_current_to_version for read-only inspection, then ask the authenticated app owner to restore through the Fine Structure UI.

Input parameters:

- `app_id` (string, required): The app ID
- `snapshot_id` (string, required): Saved Version snapshot_id to inspect before restoring in the UI

### `create_change_set` (~54 tokens)

Create a staged file change set. Add multiple file changes, validate them as one app state, then apply atomically.

Input parameters:

- `app_id` (string, required): The app ID
- `label` (string): Optional short label

### `add_file_change` (~97 tokens)

Stage one file upsert or delete inside a change set. Does not modify the live app until apply_change_set.

Input parameters:

- `app_id` (string, required): The app ID
- `change_set_id` (string, required): Change set ID
- `content` (string): Complete file contents for upsert
- `file_type` (string): Optional file type override
- `operation` (string)
- `path` (string, required): Virtual file path

### `validate_change_set` (~53 tokens)

Validate current app files plus staged change set files before applying.

Input parameters:

- `app_id` (string, required): The app ID
- `change_set_id` (string, required): Change set ID
- `include_runtime_errors` (boolean)

### `apply_change_set` (~69 tokens)

Apply a staged change set to the app. Creates a Saved Version before applying. Blocks on validation errors unless force=true.

Input parameters:

- `app_id` (string, required): The app ID
- `change_set_id` (string, required): Change set ID
- `force` (boolean): Apply even if validation has errors

### `discard_change_set` (~44 tokens)

Discard a pending staged change set without changing app files.

Input parameters:

- `app_id` (string, required): The app ID
- `change_set_id` (string, required): Change set ID

### `validate_app` (~51 tokens)

Run deterministic app checks: syntax, imports, routes/pages, entity schemas, missing entities, and recorded runtime errors.

Input parameters:

- `app_id` (string, required): The app ID
- `include_runtime_errors` (boolean)

### `inspect_preview` (~88 tokens)

Return server-side preview context: URLs, persisted runtime/network errors, static clickable candidates, pages, and explicit live-browser availability.

Input parameters:

- `app_id` (string, required): The app ID
- `auth_as` (string): Optional auth simulation: anonymous
- `auth_as_role` (string): Optional app role simulation, e.g. staff/admin/customer
- `route` (string): Optional route to inspect

### `get_app_security_context` (~74 tokens)

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.

Input parameters:

- `app_id` (string, required): The app ID
- `audit_limit` (integer)

### `set_route_policy` (~78 tokens)

Create or update a server-owned route policy for a generated app route.

Input parameters:

- `allowed_roles` (array, required): Allowed app roles
- `app_id` (string, required): The app ID
- `redirect_to` (string)
- `require_auth` (boolean, required)
- `route` (string, required): Route or wildcard route, e.g. /admin/*

### `set_entity_policy` (~70 tokens)

Create or update server-side read/write role policy for an app entity.

Input parameters:

- `app_id` (string, required): The app ID
- `entity` (string, required): Entity name, e.g. Booking
- `read` (array, required): Roles allowed to read
- `write` (array, required): Roles allowed to write

### `list_app_members` (~39 tokens)

List generated-app runtime users/members for an app. This is separate from Studio project collaborators.

Input parameters:

- `app_id` (string, required): The app ID

### `invite_app_member` (~110 tokens)

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.

Input parameters:

- `app_id` (string, required): The app ID
- `email` (string, required): Member email
- `full_name` (string)
- `password` (string): Optional initial password. If omitted, one is generated.
- `role` (string, required): App role, e.g. admin/staff/customer

### `update_app_member_role` (~63 tokens)

Update a generated-app runtime member role. This cannot assign owner and cannot change the Fine Structure account owner.

Input parameters:

- `app_id` (string, required): The app ID
- `role` (string, required): New role
- `user_id` (string, required): Generated app user id

### `remove_app_member` (~39 tokens)

Remove a generated-app runtime member.

Input parameters:

- `app_id` (string, required): The app ID
- `user_id` (string, required): Generated app user id

### `get_app_security_audit` (~40 tokens)

Read recent server-side security audit events for an app.

Input parameters:

- `app_id` (string, required): The app ID
- `limit` (integer)

### `compare_saved_versions` (~77 tokens)

Compare two Saved Versions and return per-file additions, removals, modifications, and compact diffs.

Input parameters:

- `app_id` (string, required): The app ID
- `base_snapshot_id` (string, required): Older/base snapshot ID
- `max_diff_chars` (integer)
- `target_snapshot_id` (string, required): Newer/target snapshot ID

### `compare_current_to_version` (~59 tokens)

Compare the current app files to a Saved Version and return compact per-file diffs.

Input parameters:

- `app_id` (string, required): The app ID
- `max_diff_chars` (integer)
- `snapshot_id` (string, required): Saved Version snapshot ID

### `restore_file_from_version` (~75 tokens)

Restore one file from a Saved Version instead of restoring the entire app. Creates a Saved Version before changing the file.

Input parameters:

- `app_id` (string, required): The app ID
- `confirm` (boolean, required)
- `path` (string, required): Virtual file path to restore
- `snapshot_id` (string, required): Saved Version snapshot ID

### `create_entity_schema` (~86 tokens)

Create an entity schema file in entities/<Entity>.json. Creates a Saved Version before writing.

Input parameters:

- `app_id` (string, required): The app ID
- `entity` (string, required): Entity name
- `indexes` (array)
- `metadata` (object)
- `overwrite` (boolean)
- `relationships` (array)
- `schema` (object, required): JSON schema object

### `update_entity_schema` (~88 tokens)

Replace or shallow-merge an existing entity schema file. Creates a Saved Version before writing.

Input parameters:

- `app_id` (string, required): The app ID
- `entity` (string, required): Entity name
- `indexes` (array)
- `merge` (boolean)
- `metadata` (object)
- `relationships` (array)
- `schema` (object, required): Schema fields to set or merge

### `validate_entity_relationships` (~34 tokens)

Validate entity relationship metadata and *_id references against existing entity schemas.

Input parameters:

- `app_id` (string, required): The app ID

### `update_entity_metadata` (~78 tokens)

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.

Input parameters:

- `app_id` (string, required): The app ID
- `entity` (string, required): Entity name
- `indexes` (array)
- `metadata` (object)
- `relationships` (array)

### `list_secret_keys` (~34 tokens)

List secret key names for an app. Secret values are never returned.

Input parameters:

- `app_id` (string, required): The app ID

### `set_secret` (~57 tokens)

Create or update one encrypted app secret. The secret value is never returned.

Input parameters:

- `app_id` (string, required): The app ID
- `key` (string, required): Secret key name
- `value` (string, required): Secret value to encrypt and store

### `delete_secret` (~36 tokens)

Delete one app secret by key.

Input parameters:

- `app_id` (string, required): The app ID
- `key` (string, required): Secret key name

### `list_integrations` (~39 tokens)

List supported integrations and safe connected integration metadata for an app. Tokens/secrets are never returned.

Input parameters:

- `app_id` (string, required): The app ID

### `configure_integration` (~81 tokens)

Store safe non-secret integration metadata for an app. Use set_secret for API keys/tokens.

Input parameters:

- `app_id` (string, required): The app ID
- `config` (object, required): Safe metadata only, such as workspace/team/name/email
- `is_active` (boolean): Set false to disconnect this integration metadata
- `provider` (string, required): Integration provider ID

### `list_ab_tests` (~31 tokens)

List the platform A/B tests configured for an app.

Input parameters:

- `app_id` (string, required): The app ID

### `create_ab_test` (~152 tokens)

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.

Input parameters:

- `app_id` (string, required): The app ID
- `goal_event_filter` (object): Optional goal filter, for example {'entity_name': 'Lead'}
- `goal_event_type` (string): Optional conversion goal type: entity_create, any, form_submit
- `is_active` (boolean): Whether to activate the test immediately
- `name` (string, required): Experiment name
- `page_name` (string, required): Base route page that triggers the experiment
- `variants` (array, required): At least two variants. Traffic must total 100.

### `update_ab_test` (~135 tokens)

Update a native A/B test, including active state, variants, traffic, and conversion goal. Creates a Saved Version before the change.

Input parameters:

- `app_id` (string, required): The app ID
- `goal_event_filter` (object): Optional conversion goal filter
- `goal_event_type` (string): Optional conversion goal type
- `is_active` (boolean): Optional active state
- `name` (string): Optional new name
- `page_name` (string): Optional new base route page
- `test_id` (string, required): A/B test ID
- `variants` (array): Optional replacement variants. Traffic must total 100.

### `delete_ab_test` (~50 tokens)

Delete a native A/B test from an app. Creates a Saved Version before the change.

Input parameters:

- `app_id` (string, required): The app ID
- `test_id` (string, required): A/B test ID

### `get_ab_test_stats` (~50 tokens)

Get views, unique visitors, conversions, and conversion rates for an A/B test.

Input parameters:

- `app_id` (string, required): The app ID
- `test_id` (string, required): A/B test ID

### `email_marketing_status` (~50 tokens)

Admin only. Inspect the isolated Email Marketing module: enabled state, sender settings, templates, sequences, variable triggers, and recent campaign status.

Input parameters:

- `include_logs` (boolean): Include recent delivery logs

### `email_marketing_configure_sender` (~127 tokens)

Admin only. Configure global Email Marketing sender details and module enabled state. Unsubscribe footer remains mandatory.

Input parameters:

- `default_timezone` (string): Default timezone for scheduling
- `is_enabled` (boolean): Enable or disable the module at settings level
- `organization_name` (string): Organization name used in unsubscribe footer
- `postal_address` (string): Optional postal/contact address for compliance
- `reply_to` (string): Reply-To email address
- `sender_email` (string): Sender email address used by the email provider
- `sender_name` (string): Display sender name

### `email_marketing_update_template` (~95 tokens)

Admin only. Update an automatic Email Marketing template, such as user_joined welcome email. The unsubscribe block is still appended by the server.

Input parameters:

- `body_html` (string): HTML body with {{variables}}
- `enabled` (boolean): Whether this automatic template is active
- `subject` (string): Email subject with {{variables}}
- `template_id` (string, required): Template/event id, e.g. user_joined

### `email_marketing_create_broadcast` (~142 tokens)

Admin only. Create a filtered broadcast campaign, optionally scheduled or sent now.

Input parameters:

- `body_html` (string, required): HTML body. Unsubscribe is appended automatically.
- `filters` (object): Recipient filters: plans, roles, active_status, email_verified, min_apps, max_apps, has_published_app, search
- `name` (string): Internal campaign name
- `scheduled_at` (string): Optional ISO datetime. If no timezone is included, timezone is used.
- `send_now` (boolean): Send immediately after creating the campaign
- `subject` (string, required): Email subject
- `timezone` (string): Timezone for naive scheduled_at

### `email_marketing_create_sequence` (~129 tokens)

Admin only. Create a scheduled email sequence using fixed dates or day offsets. Each generated email keeps mandatory unsubscribe.

Input parameters:

- `filters` (object): Recipient filters
- `name` (string, required): Sequence name
- `schedule_mode` (string, required): fixed_dates uses each step.scheduled_at; day_offsets uses start_at + step day offsets
- `start_at` (string): ISO datetime for day_offsets mode
- `steps` (array, required): Steps with subject, body_html, and either scheduled_at (fixed_dates) or day_offset/gap_days (day_offsets).
- `timezone` (string)

### `email_marketing_create_variable_trigger` (~133 tokens)

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.

Input parameters:

- `body_html` (string, required): HTML body. Unsubscribe is appended automatically.
- `enabled` (boolean)
- `filters` (object): Optional recipient filters
- `from_value` (string): Previous value or empty wildcard
- `name` (string): Trigger name
- `subject` (string, required): Email subject
- `to_value` (string): New value or empty wildcard
- `variable_name` (string, required): Variable name, e.g. plan

### `email_marketing_trigger_variable` (~85 tokens)

Admin only. Manually fire variable-transition email rules for one user. Useful for MCP/agent workflows and tests.

Input parameters:

- `context` (object): Extra template variables
- `from_value` (string): Previous value
- `to_value` (string): New value
- `user_id` (string, required): Platform user id
- `variable_name` (string, required): Variable name

### `email_marketing_app_status` (~54 tokens)

Inspect app-scoped Email Marketing for one generated app: settings, contacts, campaigns, event triggers, and recent events.

Input parameters:

- `app_id` (string, required): The app ID
- `include_logs` (boolean)

### `email_marketing_app_configure` (~120 tokens)

Configure isolated Email Marketing settings for a generated app. Can be used by Studio/chat agents.

Input parameters:

- `app_id` (string, required): The app ID
- `default_contact_entity` (string): Entity to sync as contacts, e.g. Customer or Lead
- `default_email_field` (string): Field containing contact email
- `default_name_field` (string): Field containing contact name
- `is_enabled` (boolean)
- `reply_to` (string)
- `sender_email` (string)
- `sender_name` (string)

### `email_marketing_app_sync_contacts` (~84 tokens)

Sync an app entity table into app-scoped Email Marketing contacts. Records without a valid email are skipped.

Input parameters:

- `app_id` (string, required): The app ID
- `email_field` (string)
- `entity_name` (string, required): Entity name, e.g. Customer or Lead
- `limit` (integer)
- `name_field` (string)

### `email_marketing_app_create_broadcast` (~110 tokens)

Create an app-scoped broadcast to contacts synced from that generated app, optionally scheduled or sent now.

Input parameters:

- `app_id` (string, required): The app ID
- `body_html` (string, required)
- `filters` (object): App contact filters such as source_entity, search, tags, field_equals
- `name` (string)
- `scheduled_at` (string)
- `send_now` (boolean)
- `subject` (string, required)
- `timezone` (string)

### `email_marketing_app_create_event_trigger` (~121 tokens)

Create an app-scoped email rule that sends when an app event is recorded, for example entity_created or Customer.created.

Input parameters:

- `app_id` (string, required): The app ID
- `body_html` (string, required)
- `enabled` (boolean)
- `entity_name` (string): Optional entity filter
- `event_name` (string, required): Event name, e.g. entity_created, Customer.created, order_paid
- `filters` (object): Optional app contact filters
- `name` (string)
- `subject` (string, required)

### `email_marketing_app_record_event` (~110 tokens)

Record an app event and send matching app-scoped Email Marketing triggers.

Input parameters:

- `app_id` (string, required): The app ID
- `contact_id` (string)
- `email` (string): Contact email if no contact_id is known
- `entity_name` (string)
- `event_name` (string, required)
- `properties` (object): Extra event properties
- `record` (object): Entity record fields for template variables and contact extraction
- `record_id` (string)

### `email_marketing_app_create_workflow` (~133 tokens)

Create an app-scoped automation workflow with email, wait, condition, split, and goal steps.

Input parameters:

- `app_id` (string, required): The app ID
- `definition` (object): Optional full workflow definition; steps can also be supplied here.
- `enabled` (boolean)
- `name` (string)
- `steps` (array): Ordered workflow steps. Supported type values: email, wait, condition, split, goal.
- `trigger_entity_name` (string): Optional entity filter
- `trigger_event_name` (string, required): Event that enrolls a contact, e.g. Customer.created

### `email_marketing_app_create_sequence` (~115 tokens)

Create an app-scoped email sequence using fixed dates or day offsets between emails.

Input parameters:

- `app_id` (string, required): The app ID
- `filters` (object): App contact filters
- `name` (string)
- `schedule_mode` (string)
- `start_at` (string): Sequence start date/time for day_offsets mode
- `steps` (array, required): Emails in order. Each step supports subject, body_html, scheduled_at, day_offset, or gap_days.
- `timezone` (string)

### `email_marketing_app_report` (~66 tokens)

Read app-scoped Email Marketing reporting: delivery counts, open/click rates, and recent tracking events.

Input parameters:

- `app_id` (string, required): The app ID
- `include_events` (boolean)
- `limit` (integer)
- `segment_limit` (integer)

### `email_marketing_app_create_segment` (~80 tokens)

Create an app-scoped saved audience segment using field, tag, and behavior filters.

Input parameters:

- `app_id` (string, required): The app ID
- `filters` (object, required): Segment filters. Supports rules with field/operator/value plus opened/clicked/sent behavior fields.
- `name` (string, required)
- `sample_limit` (integer)

### `email_marketing_app_contact_profile` (~56 tokens)

Read a contact profile with email delivery, tracking, app-event, workflow, suppression, and unsubscribe timeline.

Input parameters:

- `app_id` (string, required): The app ID
- `contact` (string, required): Contact id or email address

### `email_marketing_app_deliverability` (~44 tokens)

Read provider readiness, bounce/complaint rates, suppression reasons, and recent deliverability risk events.

Input parameters:

- `app_id` (string, required): The app ID

### `email_marketing_app_process_queue` (~52 tokens)

Process due app-scoped automation workflow runs and email queue jobs with locks, retries, and suppression checks.

Input parameters:

- `app_id` (string, required): The app ID
- `max_jobs` (integer)

### `email_marketing_app_queue_status` (~54 tokens)

Inspect app-scoped Email Marketing queue jobs and per-status counts.

Input parameters:

- `app_id` (string, required): The app ID
- `limit` (integer)
- `status` (string): Optional queue status filter

### `email_marketing_app_suppress_contact` (~73 tokens)

Suppress an app contact email after a bounce, complaint, manual block, provider block, or unsubscribe.

Input parameters:

- `app_id` (string, required): The app ID
- `email` (string, required)
- `metadata` (object)
- `reason` (string)
- `source` (string)

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/ai-finestructure-fine-structure/api-mcp#diagnostics

## Score history

- 2026-08-04: 64
- 2026-08-03: 64
- 2026-08-02: 63
- 2026-08-01: 63
- 2026-07-31: 62
- 2026-07-30: 61
- 2026-07-29: 61
- 2026-07-28: 60
- 2026-07-27: 59
- 2026-07-26: 59

## Links

- Remote endpoint: https://finestructure.ai/api/mcp
- Authorisation metadata: https://finestructure.ai/.well-known/oauth-protected-resource/api/mcp
- Changelog RSS feed: https://verifymcp.io/servers/ai-finestructure-fine-structure/api-mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/ai-finestructure-fine-structure/api-mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/ai-finestructure-fine-structure/api-mcp
