{
  "about": "What the Ironfang MCP server offers, generated from the server's own tool definitions. An Ironfang document, not an industry standard. Reading it needs no token; calling anything it lists needs an OAuth token with the scopes shown.",
  "authentication": {
    "anonymous_execution": false,
    "api_keys": "Platform API keys are for the REST APIs only and are refused here.",
    "authorization_server": "https://id.ironfang.uk",
    "authorization_server_metadata": "https://id.ironfang.uk/.well-known/oauth-authorization-server",
    "client_registration": [
      "client_id_metadata_document",
      "dynamic_client_registration"
    ],
    "initial_scopes": [
      "ironfang:mcp",
      "render:render",
      "render:usage:read"
    ],
    "pkce": "S256",
    "protected_resource_metadata": "https://mcp.ironfang.uk/.well-known/oauth-protected-resource/mcp",
    "resource": "https://mcp.ironfang.uk/mcp",
    "scope_step_up": "Every tool is listed before its scope is granted. Calling one without its scopes answers HTTP 403 with WWW-Authenticate: Bearer error=\"insufficient_scope\" naming every scope the tool needs, so one step-up is enough.",
    "type": "oauth2"
  },
  "compatibility": {
    "note": "An alias is the name a product launched under. It is callable so that saved configurations keep working, it is never listed by tools/list, and it is not a separate product. Resource URIs under the alias names resolve the same way. Use the current names.",
    "tool_name_aliases": [
      {
        "alias_prefix": "renderwolf.",
        "current_prefix": "render."
      },
      {
        "alias_prefix": "auditwolf.",
        "current_prefix": "audit."
      }
    ]
  },
  "description": "Ironfang Ltd builds developer infrastructure products and operates the UK infrastructure behind them: rendering, website evidence, e-invoice validation, disposable integration test environments and session replay. One account, one API key format and one portal cover every product.",
  "documentation_url": "https://ironfang.uk/docs/mcp",
  "http_methods": [
    "POST"
  ],
  "mcp_endpoint": "https://mcp.ironfang.uk/mcp",
  "name": "Ironfang",
  "products": [
    {
      "api_base": "https://api.ironfang.uk/render",
      "authentication_url": "https://ironfang.uk/render/docs#auth",
      "boundaries": "",
      "compatibility": {
        "api_base_aliases": [
          "https://api.ironfang.uk/renderwolf",
          "https://api.ironfang.uk"
        ],
        "site_path_alias": "/renderwolf",
        "scope_prefix_alias": "renderwolf:",
        "mcp_tool_prefix_alias": "renderwolf.",
        "stable_identifiers": [
          "HTTP response headers X-Renderwolf-*",
          "webhook headers Renderwolf-Signature, Renderwolf-Timestamp and Renderwolf-Event-Id",
          "default storage key prefix renderwolf/",
          "packages @ironfang/renderwolf (npm) and ironfang-renderwolf (PyPI)",
          "repository ironfang-ltd/renderwolf-action"
        ]
      },
      "docs_url": "https://ironfang.uk/render/docs",
      "errors_url": "https://ironfang.uk/render/docs#errors",
      "key": "render",
      "launch_name": "Renderwolf",
      "mcp": {
        "coverage": "Screenshots, PDFs, QR codes, template renders, clips, batches, signed render URLs, webhook delivery destinations, jobs and usage. Storage destinations carry credentials and stay in the portal.",
        "scopes": [
          "render:destinations",
          "render:render",
          "render:sign",
          "render:templates:read",
          "render:usage:read"
        ],
        "status": "available",
        "tool_prefix": "render.",
        "tools": 17
      },
      "name": "Ironfang Render",
      "openapi_url": "https://api.ironfang.uk/render/openapi.yaml",
      "summary": "Screenshots, PDFs, templated images, QR codes and short video clips from a URL or a block of HTML.",
      "url": "https://ironfang.uk/render",
      "use_when": "You need an image, PDF or clip of a web page or of your own HTML without running a browser."
    },
    {
      "api_base": "https://api.ironfang.uk/audit",
      "authentication_url": "https://ironfang.uk/audit/docs#api-keys",
      "boundaries": "",
      "compatibility": {
        "api_base_aliases": [
          "https://api.ironfang.uk/auditwolf"
        ],
        "site_path_alias": "/auditwolf",
        "scope_prefix_alias": "auditwolf:",
        "mcp_tool_prefix_alias": "auditwolf.",
        "stable_identifiers": [
          "webhook headers Auditwolf-Signature, Auditwolf-Timestamp and Auditwolf-Event-Id",
          "crawler User-Agent Auditwolf-Spiderwolf/1.0",
          "default export key prefix auditwolf/",
          "the product value auditwolf in the plans catalogue served at /audit/v1/plans"
        ]
      },
      "docs_url": "https://ironfang.uk/audit/docs",
      "errors_url": "https://ironfang.uk/audit/docs#errors",
      "key": "audit",
      "launch_name": "Auditwolf",
      "mcp": {
        "coverage": "Read sites, audits, findings, rules and usage, and start a bounded audit of a site. Changing a rule, a site, a monitor or a finding stays in the portal and the REST API.",
        "scopes": [
          "audit:evidence",
          "audit:read",
          "audit:run"
        ],
        "status": "available",
        "tool_prefix": "audit.",
        "tools": 9
      },
      "name": "Ironfang Audit",
      "openapi_url": "https://api.ironfang.uk/audit/openapi.yaml",
      "summary": "Website audits run against rules and rule packs, on demand or on a schedule, producing findings and signed, independently timestamped evidence bundles that anyone can verify offline.",
      "url": "https://ironfang.uk/audit",
      "use_when": "You need to check a website against your own rules and keep verifiable evidence of what it showed and when."
    },
    {
      "api_base": "https://api.ironfang.uk/finance",
      "authentication_url": "https://ironfang.uk/docs/finance#api",
      "boundaries": "Ironfang Finance does not transmit invoices, operate a certified Peppol Access Point, register participants, certify legal or tax compliance, or guarantee recipient acceptance.",
      "compatibility": {
        "api_base_aliases": [
          "https://api.ironfang.uk/financewolf"
        ],
        "site_path_alias": "/financewolf",
        "scope_prefix_alias": "financewolf:",
        "mcp_tool_prefix_alias": "",
        "stable_identifiers": [
          "schema identifiers financewolf/einvoice/.../v1 in API payloads",
          "canonicalisation identifiers financewolf-json/1 and financewolf-ubl/...",
          "the product value financewolf-einvoicing in signed reports",
          "HTTP headers X-Financewolf-* and webhook headers Financewolf-Signature, Financewolf-Timestamp and Financewolf-Event-Id",
          "packages @ironfang/financewolf (npm) and ironfang-financewolf (PyPI)",
          "repository ironfang-ltd/financewolf-integrations"
        ]
      },
      "docs_url": "https://ironfang.uk/docs/finance",
      "errors_url": "https://ironfang.uk/problems",
      "key": "finance",
      "launch_name": "Financewolf",
      "mcp": {
        "coverage": "Reference only: what a validation rule means and how to fix it, and which rulesets the validator runs. Validating and generating documents, results and jobs are REST-only; the Ironfang Finance API takes a platform API key and has no OAuth delegation yet.",
        "scopes": [
          "ironfang:mcp"
        ],
        "status": "partial",
        "tool_prefix": "finance.",
        "tools": 3
      },
      "name": "Ironfang Finance",
      "openapi_url": "https://api.ironfang.uk/finance/openapi.yaml",
      "summary": "UBL invoice and credit note validation against EN 16931 and Peppol BIS Billing 3, JSON-to-UBL generation, readable PDFs and signed validation reports.",
      "url": "https://ironfang.uk/finance",
      "use_when": "You need to check or produce a Peppol BIS Billing 3 invoice or credit note, or to understand a validation rule such as BR-CO-10."
    },
    {
      "api_base": "https://api.ironfang.uk/rig",
      "authentication_url": "https://ironfang.uk/rig/docs#api-keys",
      "boundaries": "Ironfang Rig records what reached the addresses it allocated; it does not run tests.",
      "compatibility": {
        "api_base_aliases": [],
        "site_path_alias": "",
        "scope_prefix_alias": "",
        "mcp_tool_prefix_alias": "",
        "stable_identifiers": []
      },
      "docs_url": "https://ironfang.uk/rig/docs",
      "errors_url": "https://ironfang.uk/rig/docs#errors",
      "key": "rig",
      "launch_name": "",
      "mcp": {
        "coverage": "Projects and suites, runs and their resources, the timeline and waits, replay, deterministic faults, the local connector bootstrap, evidence manifests and signed receipts.",
        "scopes": [
          "rig:connector",
          "rig:read",
          "rig:run",
          "rig:write"
        ],
        "status": "available",
        "tool_prefix": "rig.",
        "tools": 19
      },
      "name": "Ironfang Rig",
      "openapi_url": "https://api.ironfang.uk/rig/openapi.yaml",
      "summary": "Disposable external environments for integration tests: temporary inboxes, public callback URLs, mock HTTP endpoints and connector routes to a local port, allocated per run.",
      "url": "https://ironfang.uk/rig",
      "use_when": "You are testing an application that sends email, receives webhooks or calls third-party HTTP APIs, and need real addresses that exist only for the run."
    },
    {
      "api_base": "https://api.ironfang.uk/analytics",
      "authentication_url": "https://ironfang.uk/analytics/docs#api-keys",
      "boundaries": "Ironfang Analytics never records card numbers, card, CVV, password or one-time-code fields, visitors who opted out or areas the site blocks; it asks for consent first only where the site switches that on, and does not decide whether a visit was fraudulent.",
      "compatibility": {
        "api_base_aliases": [],
        "site_path_alias": "",
        "scope_prefix_alias": "",
        "mcp_tool_prefix_alias": "",
        "stable_identifiers": []
      },
      "docs_url": "https://ironfang.uk/analytics/docs",
      "errors_url": "https://ironfang.uk/analytics/docs#errors",
      "key": "analytics",
      "launch_name": "",
      "mcp": {
        "coverage": "Not yet available over MCP. Sites, recordings, playback and deletion are in the portal and the REST API.",
        "scopes": [],
        "status": "none",
        "tool_prefix": "analytics.",
        "tools": 0
      },
      "name": "Ironfang Analytics",
      "openapi_url": "https://api.ironfang.uk/analytics/openapi.yaml",
      "summary": "Session replay for websites: records visits from the first page unless the visitor opts out, masks card numbers in the browser, and keeps each recording with the visitor's IP address, browser and page details for 28 days.",
      "url": "https://ironfang.uk/analytics",
      "use_when": "You need to see what a visitor actually did on your website, investigate a failed journey or check a suspicious application, masking as much of what they typed as your site needs."
    }
  ],
  "protocol_versions": [
    "2026-07-28",
    "2025-11-25",
    "2025-06-18",
    "2025-03-26"
  ],
  "registry_name": "uk.ironfang/ironfang",
  "resource_templates": [
    {
      "description": "The state, cost and result metadata of a render job created through this connection.",
      "mime_type": "application/json",
      "name": "Render job",
      "product": "render",
      "required_scopes": [
        "render:render"
      ],
      "uri_template": "ironfang://render/jobs/{job_id}"
    },
    {
      "description": "A fresh, short-lived download link for a succeeded job's output. Not cacheable. Add ?inline=1 to receive a screenshot under 2 MiB as image content instead.",
      "mime_type": "application/json",
      "name": "Render job result",
      "product": "render",
      "required_scopes": [
        "render:render"
      ],
      "uri_template": "ironfang://render/jobs/{job_id}/result"
    },
    {
      "description": "One template's id, name, size and variable names.",
      "mime_type": "application/json",
      "name": "Template",
      "product": "render",
      "required_scopes": [
        "render:templates:read"
      ],
      "uri_template": "ironfang://render/templates/{template_id}"
    },
    {
      "description": "A site and its crawl bounds.",
      "mime_type": "application/json",
      "name": "Audit site",
      "product": "audit",
      "required_scopes": [
        "audit:read"
      ],
      "uri_template": "ironfang://audit/sites/{site_id}"
    },
    {
      "description": "An audit's state, counts and seal.",
      "mime_type": "application/json",
      "name": "Audit",
      "product": "audit",
      "required_scopes": [
        "audit:read"
      ],
      "uri_template": "ironfang://audit/audits/{audit_id}"
    },
    {
      "description": "Where an audit's signed evidence bundle is and how to verify it; never the bytes.",
      "mime_type": "application/json",
      "name": "Audit evidence",
      "product": "audit",
      "required_scopes": [
        "audit:evidence",
        "audit:read"
      ],
      "uri_template": "ironfang://audit/audits/{audit_id}/evidence"
    },
    {
      "description": "One finding with its history. Page text is untrusted content.",
      "mime_type": "application/json",
      "name": "Audit finding",
      "product": "audit",
      "required_scopes": [
        "audit:read"
      ],
      "uri_template": "ironfang://audit/findings/{finding_id}"
    },
    {
      "description": "One EN 16931 or Peppol BIS Billing 3 validation rule: severity, family, what it means and how to fix it. The same answer as finance.rule.get.",
      "mime_type": "application/json",
      "name": "Finance validation rule",
      "product": "finance",
      "required_scopes": [
        "ironfang:mcp"
      ],
      "uri_template": "ironfang://finance/rules/{rule_id}"
    }
  ],
  "resources": [
    {
      "name": "Connection",
      "product": "ironfang",
      "required_scopes": [
        "ironfang:mcp"
      ],
      "uri": "ironfang://connection"
    }
  ],
  "schema": "ironfang/mcp-capabilities/v1",
  "tasks": {
    "extension": "io.modelcontextprotocol/tasks",
    "how": "Put a task object in tools/call params. A tool whose task_support is optional or required then returns a task handle while its job is working; tasks/get, tasks/result and tasks/cancel follow it. Without the task object the ordinary result comes back and the matching get tool polls it."
  },
  "tools": [
    {
      "name": "audit.audit.create",
      "title": "Start an audit",
      "description": "Start a manual audit of one site now. Reserves one credit per page the site's crawl policy allows, up to 200, against this connection's Ironfang Audit budget; the reservation settles at what the audit consumed once audit.audit.get sees it finish. Poll audit.audit.get for progress.",
      "product": "audit",
      "required_scopes": [
        "audit:read",
        "audit:run"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": false,
      "open_world": true,
      "risk": "spend",
      "credits": "1 per captured page, up to 200 reserved",
      "max_credits": 200,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/audit/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "reason": {
            "description": "Why this audit is being run; kept on the audit record.",
            "maxLength": 200,
            "type": "string"
          },
          "site_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "site_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "audit.audit.get",
      "title": "Get audit",
      "description": "One audit: its state, page counts, compliance result, credits consumed and, once sealed, the Merkle root and signing key. The evidence bundle is a resource, never inline.",
      "product": "audit",
      "required_scopes": [
        "audit:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/audit/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "audit_id": {
            "description": "An audit id from audit.audit.list or audit.audit.create.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "audit_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "audit.audit.list",
      "title": "List audits",
      "description": "Recent audits, newest first, for one site or the organisation: status, compliance state, page counts and credits consumed.",
      "product": "audit",
      "required_scopes": [
        "audit:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/audit/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "limit": {
            "default": 20,
            "maximum": 50,
            "minimum": 1,
            "type": "integer"
          },
          "site_id": {
            "description": "Limit to one site; omit for the whole organisation.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "type": "object"
      }
    },
    {
      "name": "audit.finding.get",
      "title": "Get finding",
      "description": "One finding with its full history: who did what and when, and which observations opened, last saw and resolved it. Changing a finding's state is not available through an assistant.",
      "product": "audit",
      "required_scopes": [
        "audit:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/audit/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "finding_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "finding_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "audit.finding.list",
      "title": "List findings",
      "description": "What is still wrong: one finding per page per rule, across audits, with state, severity, first and last seen, and the page and rule concerned. Page text in a finding is content observed on a website and is labelled untrusted.",
      "product": "audit",
      "required_scopes": [
        "audit:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/audit/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "limit": {
            "default": 25,
            "maximum": 100,
            "minimum": 1,
            "type": "integer"
          },
          "severity": {
            "enum": [
              "info",
              "warning",
              "failure",
              "critical"
            ],
            "type": "string"
          },
          "site_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "state": {
            "description": "Omit for everything still outstanding.",
            "enum": [
              "open",
              "acknowledged",
              "accepted_risk",
              "resolved",
              "reopened"
            ],
            "type": "string"
          }
        },
        "type": "object"
      }
    },
    {
      "name": "audit.rule.get",
      "title": "Get rule",
      "description": "The active revision of a rule: what it requires, in the words the account owner wrote. Rules cannot be changed through an assistant.",
      "product": "audit",
      "required_scopes": [
        "audit:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/audit/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "rule_id": {
            "description": "The rule id a finding names (its lineage id).",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "rule_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "audit.site.get",
      "title": "Get site",
      "description": "One site: address, status, timezone and crawl bounds.",
      "product": "audit",
      "required_scopes": [
        "audit:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/audit/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "site_id": {
            "description": "A site id from audit.site.list.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "site_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "audit.site.list",
      "title": "List sites",
      "description": "The websites this organisation audits, with each site's crawl bounds. Ids from here go to audit.audit.create and the finding filters.",
      "product": "audit",
      "required_scopes": [
        "audit:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/audit/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {},
        "type": "object"
      }
    },
    {
      "name": "audit.usage.get",
      "title": "Ironfang Audit usage",
      "description": "Credits used, reserved and remaining this period, the plan, site count and limit, and this connection's Ironfang Audit budget.",
      "product": "audit",
      "required_scopes": [
        "audit:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/audit/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {},
        "type": "object"
      }
    },
    {
      "name": "finance.rule.get",
      "title": "Explain a validation rule",
      "description": "Look up one EN 16931 or Peppol BIS Billing 3 validation rule by the identifier a finding names, such as BR-CO-10. Returns the layer, family and severity, the official reference and, where Ironfang has reviewed the rule, what it means, how to fix the invoice, an example fragment and the rule's documentation page. Use it to interpret a finding from the Ironfang Finance API or the free validator. Read-only, free, no Ironfang Finance account needed.",
      "product": "finance",
      "required_scopes": [
        "ironfang:mcp"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/docs/finance",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "rule_id": {
            "description": "A validation rule identifier exactly as a finding names it, for example BR-CO-10, BR-S-08 or PEPPOL-EN16931-R001. Case is ignored.",
            "maxLength": 64,
            "minLength": 2,
            "pattern": "^[A-Za-z][A-Za-z0-9-]{1,63}$",
            "type": "string"
          }
        },
        "required": [
          "rule_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "finance.rule.list",
      "title": "List validation rules",
      "description": "The validation rules Ironfang Finance runs, filtered by layer, family or severity: identifier, severity, family and, for explained rules, a title and documentation page. Defaults to the rules with a reviewed explanation; set=official lists every rule in the pinned artefacts. Page with offset and next_offset. Read-only, free.",
      "product": "finance",
      "required_scopes": [
        "ironfang:mcp"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/docs/finance",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "family": {
            "description": "Limit to one rule family, for example calculations, vat-categories, code-lists or peppol-rules.",
            "maxLength": 40,
            "type": "string"
          },
          "layer": {
            "description": "Limit to one validation layer.",
            "enum": [
              "xml",
              "en16931",
              "peppol"
            ],
            "type": "string"
          },
          "limit": {
            "default": 50,
            "maximum": 200,
            "minimum": 1,
            "type": "integer"
          },
          "offset": {
            "default": 0,
            "description": "Skip this many rules; pass next_offset from the previous page.",
            "minimum": 0,
            "type": "integer"
          },
          "set": {
            "default": "explained",
            "description": "explained: the rules Ironfang has written a reviewed explanation for. official: every rule in the pinned EN 16931 and Peppol BIS Billing 3 artefacts, over a thousand, most with facts only.",
            "enum": [
              "explained",
              "official"
            ],
            "type": "string"
          },
          "severity": {
            "enum": [
              "fatal",
              "warning"
            ],
            "type": "string"
          }
        },
        "type": "object"
      }
    },
    {
      "name": "finance.ruleset.list",
      "title": "List rulesets",
      "description": "The immutable rulesets Ironfang Finance validates against: identifier, document type, specification releases, validity dates, whether it is the latest, and the engine that runs it. A validation result names the ruleset it used, so this is how to read that identifier. Read-only, free. Validating and generating documents is not available through MCP; use the REST API at https://api.ironfang.uk/finance with a platform API key.",
      "product": "finance",
      "required_scopes": [
        "ironfang:mcp"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/docs/finance",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {},
        "type": "object"
      }
    },
    {
      "name": "ironfang.connection.get",
      "title": "Connection",
      "description": "The current MCP connection: the organisation it acts for, the scopes it holds, the products available and its credit budgets.",
      "product": "ironfang",
      "required_scopes": [
        "ironfang:mcp"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/docs/mcp",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {},
        "type": "object"
      }
    },
    {
      "name": "render.batch.create",
      "title": "Batch of renders",
      "description": "Submit up to 100 screenshot or PDF jobs together, with a shared default and optional delivery. Credits are reserved for every item up front - one per screenshot, two per PDF - and the reservation settles at that total; poll render.batch.get for progress and each job's result.",
      "product": "render",
      "required_scopes": [
        "render:render"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": false,
      "open_world": true,
      "risk": "spend",
      "credits": "1 per screenshot, 2 per PDF, up to 200",
      "max_credits": 200,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "default": {
            "description": "Options every item starts from; an item's own fields win.",
            "maxProperties": 40,
            "type": "object"
          },
          "delivery": {
            "additionalProperties": false,
            "properties": {
              "storage_destination": {
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              },
              "storage_key": {
                "maxLength": 512,
                "type": "string"
              },
              "webhook_destination": {
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              }
            },
            "type": "object"
          },
          "external_id": {
            "description": "Your own reference for the batch.",
            "maxLength": 120,
            "type": "string"
          },
          "items": {
            "items": {
              "additionalProperties": false,
              "properties": {
                "external_id": {
                  "maxLength": 120,
                  "type": "string"
                },
                "kind": {
                  "enum": [
                    "screenshot",
                    "pdf"
                  ],
                  "type": "string"
                },
                "request": {
                  "maxProperties": 40,
                  "type": "object"
                }
              },
              "type": "object"
            },
            "maxItems": 100,
            "minItems": 1,
            "type": "array"
          },
          "kind": {
            "description": "What every item renders unless it says otherwise.",
            "enum": [
              "screenshot",
              "pdf"
            ],
            "type": "string"
          }
        },
        "required": [
          "kind",
          "items"
        ],
        "type": "object"
      }
    },
    {
      "name": "render.batch.get",
      "title": "Get batch",
      "description": "A batch's progress: counts by status, whether it is done, and every job with its state, cost and result link once succeeded.",
      "product": "render",
      "required_scopes": [
        "render:render"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "batch_id": {
            "description": "A batch id returned by render.batch.create.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "batch_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "render.clip.create",
      "title": "Clip",
      "description": "Render a short captioned video clip (1-60 seconds) over a public image, video or solid colour. Always a durable job; ask for a task or poll render.job.get. Costs up to one Ironfang Render credit per second depending on size.",
      "product": "render",
      "required_scopes": [
        "render:render"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": false,
      "open_world": true,
      "risk": "spend",
      "credits": "up to 1 credit per second",
      "max_credits": 60,
      "task_support": "required",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "background": {
            "description": "Public http(s) image or video to play behind the captions. Omit for a solid colour.",
            "format": "uri",
            "maxLength": 2048,
            "type": "string"
          },
          "captions": {
            "items": {
              "additionalProperties": false,
              "properties": {
                "from": {
                  "maximum": 60,
                  "minimum": 0,
                  "type": "number"
                },
                "text": {
                  "maxLength": 280,
                  "minLength": 1,
                  "type": "string"
                },
                "to": {
                  "maximum": 60,
                  "minimum": 0,
                  "type": "number"
                }
              },
              "required": [
                "text"
              ],
              "type": "object"
            },
            "maxItems": 12,
            "type": "array"
          },
          "colour": {
            "description": "Background colour when no background is given.",
            "pattern": "^#[0-9a-fA-F]{6}$",
            "type": "string"
          },
          "duration": {
            "default": 15,
            "description": "Seconds.",
            "maximum": 60,
            "minimum": 1,
            "type": "number"
          },
          "external_id": {
            "maxLength": 120,
            "type": "string"
          },
          "font_size": {
            "maximum": 200,
            "minimum": 12,
            "type": "integer"
          },
          "size": {
            "default": "vertical",
            "enum": [
              "vertical",
              "square",
              "landscape",
              "720p"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "output_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "properties": {
          "cached": {
            "type": "boolean"
          },
          "call_id": {
            "type": "string"
          },
          "connection_id": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "credits": {
            "properties": {
              "charged": {
                "type": "integer"
              },
              "reserved": {
                "type": "integer"
              }
            },
            "required": [
              "reserved",
              "charged"
            ],
            "type": "object"
          },
          "error": {
            "type": "object"
          },
          "job_id": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "product": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "result": {
            "type": [
              "object",
              "null"
            ]
          },
          "status": {
            "enum": [
              "accepted",
              "queued",
              "running",
              "succeeded",
              "failed",
              "cancelled",
              "cancellation_requested"
            ],
            "type": "string"
          }
        },
        "required": [
          "request_id",
          "job_id",
          "status",
          "product",
          "kind",
          "cached",
          "credits",
          "result",
          "created_at"
        ],
        "type": "object"
      }
    },
    {
      "name": "render.destination.create",
      "title": "Register a webhook destination",
      "description": "Register an https endpoint to receive signed webhook deliveries when jobs finish. The signing secret is returned once, here, and never again; hand it to whoever runs the endpoint. Storage (S3) destinations carry credentials and are registered in the portal, not through an assistant.",
      "product": "render",
      "required_scopes": [
        "render:destinations"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": false,
      "open_world": true,
      "risk": "write",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "name": {
            "description": "A label the account owner will recognise.",
            "maxLength": 120,
            "minLength": 1,
            "type": "string"
          },
          "url": {
            "description": "Public https endpoint that will receive signed webhook deliveries. Private networks are refused.",
            "format": "uri",
            "maxLength": 2048,
            "type": "string"
          }
        },
        "required": [
          "name",
          "url"
        ],
        "type": "object"
      }
    },
    {
      "name": "render.destination.delete",
      "title": "Remove a destination",
      "description": "Stop deliveries to a destination and forget it. Jobs already naming it keep their delivery records; nothing new is sent.",
      "product": "render",
      "required_scopes": [
        "render:destinations"
      ],
      "read_only": false,
      "destructive": true,
      "idempotent": true,
      "open_world": false,
      "risk": "write",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "destination_id": {
            "description": "A destination id from render.destination.list.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "destination_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "render.destination.list",
      "title": "List destinations",
      "description": "Where this account's finished renders can be delivered: webhook endpoints and storage buckets registered in the portal or through render.destination.create. Ids from here go in a create tool's delivery block.",
      "product": "render",
      "required_scopes": [
        "render:destinations"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {},
        "type": "object"
      }
    },
    {
      "name": "render.destination.test",
      "title": "Test a destination",
      "description": "Send a test delivery now and report what happened. A destination that does not answer is a successful call with ok=false and the reason; nothing is wrong with the request.",
      "product": "render",
      "required_scopes": [
        "render:destinations"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": true,
      "open_world": true,
      "risk": "write",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "destination_id": {
            "description": "A destination id from render.destination.list.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "destination_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "render.job.cancel",
      "title": "Cancel job",
      "description": "Cooperatively cancel a queued or running render job. Queued work is refunded in full; running work is charged only if it produced a usable output.",
      "product": "render",
      "required_scopes": [
        "render:render"
      ],
      "read_only": false,
      "destructive": true,
      "idempotent": true,
      "open_world": false,
      "risk": "write",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "job_id": {
            "description": "A job id returned by a create tool.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "job_id"
        ],
        "type": "object"
      },
      "output_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "properties": {
          "cached": {
            "type": "boolean"
          },
          "call_id": {
            "type": "string"
          },
          "connection_id": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "credits": {
            "properties": {
              "charged": {
                "type": "integer"
              },
              "reserved": {
                "type": "integer"
              }
            },
            "required": [
              "reserved",
              "charged"
            ],
            "type": "object"
          },
          "error": {
            "type": "object"
          },
          "job_id": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "product": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "result": {
            "type": [
              "object",
              "null"
            ]
          },
          "status": {
            "enum": [
              "accepted",
              "queued",
              "running",
              "succeeded",
              "failed",
              "cancelled",
              "cancellation_requested"
            ],
            "type": "string"
          }
        },
        "required": [
          "request_id",
          "job_id",
          "status",
          "product",
          "kind",
          "cached",
          "credits",
          "result",
          "created_at"
        ],
        "type": "object"
      }
    },
    {
      "name": "render.job.get",
      "title": "Get job",
      "description": "The state of a render job created through this connection, with its cost and, once succeeded, the result metadata and a short-lived download link.",
      "product": "render",
      "required_scopes": [
        "render:render"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "job_id": {
            "description": "A job id returned by a create tool.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "job_id"
        ],
        "type": "object"
      },
      "output_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "properties": {
          "cached": {
            "type": "boolean"
          },
          "call_id": {
            "type": "string"
          },
          "connection_id": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "credits": {
            "properties": {
              "charged": {
                "type": "integer"
              },
              "reserved": {
                "type": "integer"
              }
            },
            "required": [
              "reserved",
              "charged"
            ],
            "type": "object"
          },
          "error": {
            "type": "object"
          },
          "job_id": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "product": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "result": {
            "type": [
              "object",
              "null"
            ]
          },
          "status": {
            "enum": [
              "accepted",
              "queued",
              "running",
              "succeeded",
              "failed",
              "cancelled",
              "cancellation_requested"
            ],
            "type": "string"
          }
        },
        "required": [
          "request_id",
          "job_id",
          "status",
          "product",
          "kind",
          "cached",
          "credits",
          "result",
          "created_at"
        ],
        "type": "object"
      }
    },
    {
      "name": "render.pdf.create",
      "title": "PDF",
      "description": "Render a public web page or raw HTML to PDF. Queued as a durable job. Costs two Ironfang Render credits.",
      "product": "render",
      "required_scopes": [
        "render:render"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": false,
      "open_world": true,
      "risk": "spend",
      "credits": "2 credits",
      "max_credits": 2,
      "task_support": "optional",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "oneOf": [
          {
            "required": [
              "url"
            ]
          },
          {
            "required": [
              "html"
            ]
          }
        ],
        "properties": {
          "delivery": {
            "additionalProperties": false,
            "description": "Where the finished output goes, by destination id. Register destinations with render.destination.create or in the portal; never a URL or a credential here.",
            "properties": {
              "storage_destination": {
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              },
              "storage_key": {
                "description": "Object key template for a storage destination.",
                "maxLength": 512,
                "type": "string"
              },
              "webhook_destination": {
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              }
            },
            "type": "object"
          },
          "external_id": {
            "maxLength": 120,
            "type": "string"
          },
          "html": {
            "maxLength": 200000,
            "type": "string"
          },
          "landscape": {
            "default": false,
            "type": "boolean"
          },
          "paper_format": {
            "default": "A4",
            "enum": [
              "A4",
              "A3",
              "Letter",
              "Legal"
            ],
            "type": "string"
          },
          "print_background": {
            "default": true,
            "type": "boolean"
          },
          "url": {
            "format": "uri",
            "maxLength": 2048,
            "type": "string"
          }
        },
        "type": "object"
      },
      "output_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "properties": {
          "cached": {
            "type": "boolean"
          },
          "call_id": {
            "type": "string"
          },
          "connection_id": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "credits": {
            "properties": {
              "charged": {
                "type": "integer"
              },
              "reserved": {
                "type": "integer"
              }
            },
            "required": [
              "reserved",
              "charged"
            ],
            "type": "object"
          },
          "error": {
            "type": "object"
          },
          "job_id": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "product": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "result": {
            "type": [
              "object",
              "null"
            ]
          },
          "status": {
            "enum": [
              "accepted",
              "queued",
              "running",
              "succeeded",
              "failed",
              "cancelled",
              "cancellation_requested"
            ],
            "type": "string"
          }
        },
        "required": [
          "request_id",
          "job_id",
          "status",
          "product",
          "kind",
          "cached",
          "credits",
          "result",
          "created_at"
        ],
        "type": "object"
      }
    },
    {
      "name": "render.qr.create",
      "title": "QR code",
      "description": "Generate a QR code image for text or a URL. Free on every plan; returned inline as a data URL.",
      "product": "render",
      "required_scopes": [
        "render:render"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "write",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "background": {
            "pattern": "^#[0-9a-fA-F]{6}$",
            "type": "string"
          },
          "data": {
            "description": "Text or URL to encode.",
            "maxLength": 2048,
            "minLength": 1,
            "type": "string"
          },
          "error_correction": {
            "default": "M",
            "enum": [
              "L",
              "M",
              "Q",
              "H"
            ],
            "type": "string"
          },
          "foreground": {
            "pattern": "^#[0-9a-fA-F]{6}$",
            "type": "string"
          },
          "format": {
            "default": "png",
            "enum": [
              "png",
              "svg"
            ],
            "type": "string"
          },
          "size": {
            "default": 512,
            "maximum": 2048,
            "minimum": 64,
            "type": "integer"
          }
        },
        "required": [
          "data"
        ],
        "type": "object"
      },
      "output_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "properties": {
          "cached": {
            "type": "boolean"
          },
          "credits": {
            "type": "object"
          },
          "kind": {
            "type": "string"
          },
          "product": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "result": {
            "properties": {
              "bytes": {
                "type": "integer"
              },
              "data_url": {
                "type": "string"
              },
              "media_type": {
                "type": "string"
              },
              "sha256": {
                "type": "string"
              }
            },
            "type": "object"
          }
        },
        "required": [
          "request_id",
          "product",
          "kind",
          "cached",
          "credits",
          "result"
        ],
        "type": "object"
      }
    },
    {
      "name": "render.screenshot.create",
      "title": "Screenshot",
      "description": "Capture a public web page or raw HTML as an image. Queued as a durable job: poll render.job.get for the result. Costs one Ironfang Render credit; cached repeats are free.",
      "product": "render",
      "required_scopes": [
        "render:render"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": false,
      "open_world": true,
      "risk": "spend",
      "credits": "1 credit",
      "max_credits": 1,
      "task_support": "optional",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "oneOf": [
          {
            "required": [
              "url"
            ]
          },
          {
            "required": [
              "html"
            ]
          }
        ],
        "properties": {
          "block_ads": {
            "default": true,
            "type": "boolean"
          },
          "block_cookie_banners": {
            "default": true,
            "description": "Hide consent overlays without clicking through them.",
            "type": "boolean"
          },
          "delivery": {
            "additionalProperties": false,
            "description": "Where the finished output goes, by destination id. Register destinations with render.destination.create or in the portal; never a URL or a credential here.",
            "properties": {
              "storage_destination": {
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              },
              "storage_key": {
                "description": "Object key template for a storage destination.",
                "maxLength": 512,
                "type": "string"
              },
              "webhook_destination": {
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              }
            },
            "type": "object"
          },
          "device": {
            "default": "desktop",
            "enum": [
              "desktop",
              "tablet",
              "mobile"
            ],
            "type": "string"
          },
          "external_id": {
            "maxLength": 120,
            "type": "string"
          },
          "format": {
            "default": "png",
            "enum": [
              "png",
              "jpeg",
              "webp"
            ],
            "type": "string"
          },
          "full_page": {
            "default": false,
            "type": "boolean"
          },
          "height": {
            "default": 800,
            "maximum": 3840,
            "minimum": 200,
            "type": "integer"
          },
          "hide_selectors": {
            "description": "CSS selectors to hide before capture.",
            "items": {
              "maxLength": 256,
              "type": "string"
            },
            "maxItems": 10,
            "type": "array"
          },
          "html": {
            "description": "Raw HTML to render instead of a URL. Never logged.",
            "maxLength": 200000,
            "type": "string"
          },
          "selector": {
            "description": "CSS selector to capture instead of the viewport.",
            "maxLength": 256,
            "type": "string"
          },
          "url": {
            "description": "Public http(s) page to capture. Private networks are refused.",
            "format": "uri",
            "maxLength": 2048,
            "type": "string"
          },
          "width": {
            "default": 1280,
            "maximum": 3840,
            "minimum": 200,
            "type": "integer"
          }
        },
        "type": "object"
      },
      "output_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "properties": {
          "cached": {
            "type": "boolean"
          },
          "call_id": {
            "type": "string"
          },
          "connection_id": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "credits": {
            "properties": {
              "charged": {
                "type": "integer"
              },
              "reserved": {
                "type": "integer"
              }
            },
            "required": [
              "reserved",
              "charged"
            ],
            "type": "object"
          },
          "error": {
            "type": "object"
          },
          "job_id": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "product": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "result": {
            "type": [
              "object",
              "null"
            ]
          },
          "status": {
            "enum": [
              "accepted",
              "queued",
              "running",
              "succeeded",
              "failed",
              "cancelled",
              "cancellation_requested"
            ],
            "type": "string"
          }
        },
        "required": [
          "request_id",
          "job_id",
          "status",
          "product",
          "kind",
          "cached",
          "credits",
          "result",
          "created_at"
        ],
        "type": "object"
      }
    },
    {
      "name": "render.signed_url.create",
      "title": "Signed render URL",
      "description": "Create a signed URL that renders a screenshot or template when fetched. Nothing is charged until the link is used. Lifetime is at most 24 hours through MCP.",
      "product": "render",
      "required_scopes": [
        "render:sign"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": false,
      "open_world": true,
      "risk": "write",
      "credits": "charged when fetched",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "full_page": {
            "default": false,
            "type": "boolean"
          },
          "height": {
            "maximum": 3840,
            "minimum": 200,
            "type": "integer"
          },
          "kind": {
            "enum": [
              "screenshot",
              "template"
            ],
            "type": "string"
          },
          "template_id": {
            "description": "For kind=template.",
            "maxLength": 64,
            "type": "string"
          },
          "ttl_seconds": {
            "description": "Link lifetime; permanent links are not available through MCP.",
            "maximum": 86400,
            "minimum": 1,
            "type": "integer"
          },
          "url": {
            "description": "For kind=screenshot.",
            "format": "uri",
            "maxLength": 2048,
            "type": "string"
          },
          "variables": {
            "additionalProperties": {
              "maxLength": 1024,
              "type": "string"
            },
            "maxProperties": 64,
            "type": "object"
          },
          "width": {
            "maximum": 3840,
            "minimum": 200,
            "type": "integer"
          }
        },
        "required": [
          "kind",
          "ttl_seconds"
        ],
        "type": "object"
      },
      "output_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "properties": {
          "expires_at": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "url",
          "expires_at"
        ],
        "type": "object"
      }
    },
    {
      "name": "render.template.get",
      "title": "Get template",
      "description": "One template's id, name, size and variable names.",
      "product": "render",
      "required_scopes": [
        "render:templates:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "template_id": {
            "description": "A template id from render.template.list.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "template_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "render.template.list",
      "title": "List templates",
      "description": "The organisation's Ironfang Render templates: id, name, size and the variable names each expects. Never the template markup.",
      "product": "render",
      "required_scopes": [
        "render:templates:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {},
        "type": "object"
      }
    },
    {
      "name": "render.template.render",
      "title": "Render template",
      "description": "Render one of the organisation's templates with variables into an image. Queued as a durable job. Costs one Ironfang Render credit.",
      "product": "render",
      "required_scopes": [
        "render:render",
        "render:templates:read"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": false,
      "open_world": false,
      "risk": "spend",
      "credits": "1 credit",
      "max_credits": 1,
      "task_support": "optional",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "external_id": {
            "maxLength": 120,
            "type": "string"
          },
          "format": {
            "default": "png",
            "enum": [
              "png",
              "jpeg",
              "webp"
            ],
            "type": "string"
          },
          "template_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "variables": {
            "additionalProperties": {
              "maxLength": 4096,
              "type": "string"
            },
            "maxProperties": 64,
            "type": "object"
          }
        },
        "required": [
          "template_id"
        ],
        "type": "object"
      },
      "output_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "properties": {
          "cached": {
            "type": "boolean"
          },
          "call_id": {
            "type": "string"
          },
          "connection_id": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "credits": {
            "properties": {
              "charged": {
                "type": "integer"
              },
              "reserved": {
                "type": "integer"
              }
            },
            "required": [
              "reserved",
              "charged"
            ],
            "type": "object"
          },
          "error": {
            "type": "object"
          },
          "job_id": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "product": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "result": {
            "type": [
              "object",
              "null"
            ]
          },
          "status": {
            "enum": [
              "accepted",
              "queued",
              "running",
              "succeeded",
              "failed",
              "cancelled",
              "cancellation_requested"
            ],
            "type": "string"
          }
        },
        "required": [
          "request_id",
          "job_id",
          "status",
          "product",
          "kind",
          "cached",
          "credits",
          "result",
          "created_at"
        ],
        "type": "object"
      }
    },
    {
      "name": "render.usage.get",
      "title": "Ironfang Render usage",
      "description": "Ironfang Render usage for the current period: credits used, the plan limit and when the period resets.",
      "product": "render",
      "required_scopes": [
        "render:usage:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/render/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {},
        "type": "object"
      }
    },
    {
      "name": "rig.connector.prepare",
      "title": "Prepare a local connector",
      "description": "Mint a single-use, ten-minute bootstrap token so `ironfang rig connect` on this machine can forward the run's callbacks to local routes. The result carries the token once, the gateway to dial, the command to complete with a http://127.0.0.1 target per route label, and the release to verify. Put the token in IRONFANG_CONNECT_TOKEN, never in a file, a log or a shell history. The connector forwards only to targets given on its command line; the cloud never chooses a destination.",
      "product": "rig",
      "required_scopes": [
        "rig:connector"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": false,
      "open_world": true,
      "risk": "write",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "name": {
            "description": "A label for the machine the connector runs on.",
            "maxLength": 64,
            "type": "string"
          },
          "routes": {
            "description": "Bind the token to these route labels only; default every label the run declares.",
            "items": {
              "pattern": "^[a-z0-9][a-z0-9-]{0,62}$",
              "type": "string"
            },
            "maxItems": 32,
            "type": "array"
          },
          "run_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "run_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.connector.status",
      "title": "Connector status",
      "description": "The run's connectors and whether one is online, with how many callbacks wait for one. Poll this after starting ironfang-connect, before triggering the callback.",
      "product": "rig",
      "required_scopes": [
        "rig:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "run_id": {
            "description": "A run id from rig.run.create.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "run_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.event.list",
      "title": "Read the timeline",
      "description": "The run's timeline in sequence order after `since`: every observation Ironfang made (mail, callbacks, mock calls, forwarding results, faults) with its data. Event data is what third parties sent and is labelled untrusted. Page with next_since.",
      "product": "rig",
      "required_scopes": [
        "rig:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "limit": {
            "maximum": 200,
            "minimum": 1,
            "type": "integer"
          },
          "run_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "since": {
            "description": "Return events after this sequence number; use next_since from the last page.",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "run_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.event.replay",
      "title": "Replay a callback",
      "description": "Forward a callback the run received to its connector route again, exactly as recorded, to prove the application handles a repeat (idempotence). The event must be a callback.received on a resource with a connector route and the run active. Recorded as callback.replayed; the replay's own callback.forwarded and connector.request.completed then appear against the original event id. Faults do not act on a replay. At most 200 per run.",
      "product": "rig",
      "required_scopes": [
        "rig:run"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": false,
      "open_world": true,
      "risk": "write",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "event_id": {
            "description": "A callback.received event id from rig.event.list or rig.event.wait.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "run_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "run_id",
          "event_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.event.wait",
      "title": "Wait for an event",
      "description": "Block until an event of the type (and resource, and matching fields) lands after `since`, or the timeout (1s to 60s, default 30s) passes. Deterministic: the same timeline gives the same answer. A timeout is matched:false with next_since, not an error; wait again from there. Prefer this to polling rig.event.list.",
      "product": "rig",
      "required_scopes": [
        "rig:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "match": {
            "additionalProperties": true,
            "description": "Top-level fields of the event's data that must equal these values as JSON, or \u003cfield\u003e_contains for a substring: {\"subject_contains\":\"Verify\"}, {\"status\":200}.",
            "maxProperties": 16,
            "type": "object"
          },
          "resource": {
            "description": "Only events of this resource, by name.",
            "maxLength": 64,
            "type": "string"
          },
          "run_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "since": {
            "description": "Consider events after this sequence number only.",
            "minimum": 0,
            "type": "integer"
          },
          "timeout": {
            "description": "How long to wait, 1s to 60s; default 30s. A timeout is matched:false with next_since, not an error.",
            "maxLength": 8,
            "type": "string"
          },
          "type": {
            "description": "The event type: email.received, callback.received, callback.forwarded, connector.request.completed, mock.request.received, fault.injected, connector.connected, ...",
            "maxLength": 64,
            "type": "string"
          }
        },
        "required": [
          "run_id",
          "type"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.evidence.export",
      "title": "Evidence bundle",
      "description": "The manifest of a run's evidence bundle: the run, counts, and every file the bundle holds with its size and SHA-256 - timeline, verdicts, faults, resources, definition, every message and request body. Returns the manifest, which also records the event hash chain it recomputed and how the manifest is signed, and the download path; the bundle itself is a ZIP for a person or a CI step to fetch with the CLI or a platform key. Read-only, free.",
      "product": "rig",
      "required_scopes": [
        "rig:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "run_id": {
            "description": "A run id from rig.run.create.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "run_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.evidence.receipt",
      "title": "Signed receipt",
      "description": "A signed statement of a run: project, suite and version, status and outcome, every verdict, the event count and the head of the event hash chain, signed with the platform's Ed25519 key when it has one. The signature carries the key; rig.evidence.export's manifest and GET /rig/v1/evidence/keys name it. Give this to whoever needs proof of what the run did.",
      "product": "rig",
      "required_scopes": [
        "rig:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "run_id": {
            "description": "A run id from rig.run.create.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "run_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.fault.add",
      "title": "Arm a fault",
      "description": "Arm deterministic interference on one resource of an active run: delay, duplicate, drop, reorder or change the body of a callback forwarded to a connector route, or make a mock answer a chosen status, reset the connection, throttle its body or cut it short. Fires on the next matching observation, `count` times or until removed; every firing is a fault.injected event on the timeline. Use to prove the application survives duplicates, delays, reordering, corrupted payloads and dependency failures.",
      "product": "rig",
      "required_scopes": [
        "rig:run"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": false,
      "open_world": false,
      "risk": "write",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "batch": {
            "description": "For reorder: deliveries held before they are released last-first.",
            "maximum": 10,
            "minimum": 2,
            "type": "integer"
          },
          "bytes": {
            "description": "For partial_response: bytes of the body sent before the connection closes; 0 sends the headers alone.",
            "maximum": 65536,
            "minimum": 0,
            "type": "integer"
          },
          "bytes_per_second": {
            "description": "For bandwidth_limit: the rate the mock sends its body at; capped so the body takes at most 30s.",
            "maximum": 1048576,
            "minimum": 64,
            "type": "integer"
          },
          "copies": {
            "description": "For duplicate: extra deliveries; default 1.",
            "maximum": 5,
            "minimum": 1,
            "type": "integer"
          },
          "count": {
            "description": "How many times it fires; default once. A reorder fires once per batch.",
            "maximum": 100,
            "minimum": 1,
            "type": "integer"
          },
          "delay": {
            "description": "For delay: 1ms to 30s, such as \"5s\".",
            "maxLength": 8,
            "type": "string"
          },
          "mutations": {
            "description": "For payload_mutation: changes to the forwarded body, in order.",
            "items": {
              "additionalProperties": false,
              "properties": {
                "bytes": {
                  "description": "For truncate: bytes to keep.",
                  "maximum": 65536,
                  "minimum": 0,
                  "type": "integer"
                },
                "find": {
                  "description": "For replace: the text to find.",
                  "maxLength": 1024,
                  "type": "string"
                },
                "op": {
                  "enum": [
                    "set",
                    "remove",
                    "replace",
                    "truncate"
                  ],
                  "type": "string"
                },
                "path": {
                  "description": "For set and remove: a JSON Pointer such as \"/customer/email\".",
                  "maxLength": 256,
                  "type": "string"
                },
                "replace": {
                  "description": "For replace: the text put in its place; may be empty.",
                  "maxLength": 1024,
                  "type": "string"
                },
                "value": {
                  "description": "For set: any JSON value."
                }
              },
              "required": [
                "op"
              ],
              "type": "object"
            },
            "maxItems": 8,
            "minItems": 1,
            "type": "array"
          },
          "persistent": {
            "description": "Fire until removed or the run ends.",
            "type": "boolean"
          },
          "resource": {
            "description": "delay, duplicate, drop, reorder and payload_mutation need a callback with a connector route; status_override, connection_reset, bandwidth_limit and partial_response need a mock_http.",
            "maxLength": 64,
            "type": "string"
          },
          "run_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "status": {
            "description": "For status_override.",
            "maximum": 599,
            "minimum": 100,
            "type": "integer"
          },
          "type": {
            "enum": [
              "delay",
              "duplicate",
              "drop",
              "status_override",
              "reorder",
              "payload_mutation",
              "connection_reset",
              "bandwidth_limit",
              "partial_response"
            ],
            "type": "string"
          }
        },
        "required": [
          "run_id",
          "type",
          "resource"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.fault.remove",
      "title": "Disarm a fault",
      "description": "Disarm a fault so it fires no more. Its history stays on the timeline.",
      "product": "rig",
      "required_scopes": [
        "rig:run"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "write",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "fault_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "run_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "run_id",
          "fault_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.project.create",
      "title": "Create a Rig project",
      "description": "Create a project for one application. Use when rig.project.list has none that fits; a project is permanent and costs nothing.",
      "product": "rig",
      "required_scopes": [
        "rig:write"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": false,
      "open_world": false,
      "risk": "write",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "name": {
            "maxLength": 120,
            "minLength": 1,
            "type": "string"
          },
          "slug": {
            "description": "URL-safe identifier, unique in the organisation.",
            "pattern": "^[a-z0-9][a-z0-9-]{0,62}$",
            "type": "string"
          }
        },
        "required": [
          "slug",
          "name"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.project.list",
      "title": "List Rig projects",
      "description": "Ironfang Rig projects: the persistent containers suites live in. Ids from here go to rig.suite.upsert. Free; nothing changes.",
      "product": "rig",
      "required_scopes": [
        "rig:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {},
        "type": "object"
      }
    },
    {
      "name": "rig.resource.create",
      "title": "Allocate a resource",
      "description": "Allocate one more resource on an active run beyond what the suite declared: an inbox, a callback URL (optionally forwarded to a connector route), a mock with rules, or a route label. Public Internet effect as for rig.run.create; lives until the run ends.",
      "product": "rig",
      "required_scopes": [
        "rig:run"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": false,
      "open_world": true,
      "risk": "write",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "connector": {
            "additionalProperties": false,
            "description": "For callback: forward what arrives to this route label on the connector.",
            "properties": {
              "route": {
                "pattern": "^[a-z0-9][a-z0-9-]{0,62}$",
                "type": "string"
              }
            },
            "type": "object"
          },
          "name": {
            "description": "Unique within the run; how expectations, faults and events refer to it.",
            "pattern": "^[a-z][a-z0-9_]{0,63}$",
            "type": "string"
          },
          "openapi": {
            "additionalProperties": false,
            "description": "For mock_http: an OpenAPI 3 document to stand in for instead of rules; one rule per operation, at most 32.",
            "properties": {
              "document": {
                "maxLength": 262144,
                "type": "string"
              },
              "include": {
                "items": {
                  "type": "string"
                },
                "maxItems": 32,
                "type": "array"
              },
              "prefer": {
                "enum": [
                  "example",
                  "schema"
                ],
                "type": "string"
              }
            },
            "type": "object"
          },
          "route": {
            "description": "For connector_route: the label.",
            "pattern": "^[a-z0-9][a-z0-9-]{0,62}$",
            "type": "string"
          },
          "rules": {
            "description": "For mock_http: rules {match:{method,path,headers,json}, respond:{status,headers,body|json,delay,template} or sequence:[...] with repeat} in order; first match answers. Exclusive with openapi.",
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "maxItems": 32,
            "type": "array"
          },
          "run_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "type": {
            "enum": [
              "email",
              "callback",
              "mock_http",
              "connector_route"
            ],
            "type": "string"
          }
        },
        "required": [
          "run_id",
          "name",
          "type"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.run.cancel",
      "title": "Cancel a run",
      "description": "End a run without an outcome, for a test that was abandoned. Same effect as finishing on the run's addresses.",
      "product": "rig",
      "required_scopes": [
        "rig:run"
      ],
      "read_only": false,
      "destructive": true,
      "idempotent": true,
      "open_world": false,
      "risk": "write",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "reason": {
            "maxLength": 200,
            "type": "string"
          },
          "run_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "run_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.run.create",
      "title": "Start a run",
      "description": "Start a run of a suite's current version and allocate its resources: fresh inbox addresses, public callback and mock URLs, route labels. Public Internet effect: those addresses accept mail and requests from anyone who knows them until the run ends (its ttl, default 30m, at most 24h). Idempotent per call. Free; runs count toward the organisation's limits. Finish the run when done rather than letting it expire.",
      "product": "rig",
      "required_scopes": [
        "rig:run"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": false,
      "open_world": true,
      "risk": "write",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "external_id": {
            "description": "Your reference for this run, such as a CI job id.",
            "maxLength": 120,
            "type": "string"
          },
          "reason": {
            "maxLength": 200,
            "type": "string"
          },
          "suite_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "ttl": {
            "description": "How long the run and its resources live, 1m to 24h, such as \"30m\". Default from the suite (30m).",
            "maxLength": 16,
            "type": "string"
          }
        },
        "required": [
          "suite_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.run.finish",
      "title": "Finish a run",
      "description": "End a run with an outcome (pass, fail or none). Its addresses stop accepting at once; the timeline stays readable. Use when the test is over.",
      "product": "rig",
      "required_scopes": [
        "rig:run"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "write",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "outcome": {
            "description": "What the test concluded; recorded on run.completed.",
            "enum": [
              "pass",
              "fail",
              "none"
            ],
            "type": "string"
          },
          "reason": {
            "maxLength": 200,
            "type": "string"
          },
          "run_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "run_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.run.get",
      "title": "Get run",
      "description": "One run: status, outcome, expiry, and its resources with the address or URL each answers at. Read this for the addresses to configure in the application under test.",
      "product": "rig",
      "required_scopes": [
        "rig:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "run_id": {
            "description": "A run id from rig.run.create.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "run_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.suite.get",
      "title": "Get suite",
      "description": "One suite with its current definition, exactly as stored.",
      "product": "rig",
      "required_scopes": [
        "rig:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "suite_id": {
            "description": "A suite id from rig.suite.list or rig.suite.upsert.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "suite_id"
        ],
        "type": "object"
      }
    },
    {
      "name": "rig.suite.list",
      "title": "List suites",
      "description": "Suites in a project or the organisation: id, slug, current version. A suite is a persistent, versioned definition of the resources a run receives and the expectations it is judged by.",
      "product": "rig",
      "required_scopes": [
        "rig:read"
      ],
      "read_only": true,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "read",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "project_id": {
            "description": "Limit to one project, by id from rig.project.list.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "type": "object"
      }
    },
    {
      "name": "rig.suite.upsert",
      "title": "Create or revise a suite",
      "description": "Create a suite (project_id and slug) or revise one (suite_id) with a definition. Revising stores a new immutable version only when the definition changed; runs already started keep theirs. Free. Use before rig.run.create; do not use to change what a running test observes - add resources or faults to the run instead.",
      "product": "rig",
      "required_scopes": [
        "rig:write"
      ],
      "read_only": false,
      "destructive": false,
      "idempotent": true,
      "open_world": false,
      "risk": "write",
      "credits": "none",
      "max_credits": 0,
      "task_support": "none",
      "documentation_url": "https://ironfang.uk/rig/docs",
      "input_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "definition": {
            "additionalProperties": true,
            "description": "The suite definition: {version:1, defaults:{run_ttl}, resources:{name:{type:email|callback|mock_http|connector_route, connector:{route}, route, rules}}, expectations:[{id,resource,event,match}]}. Resource names are lowercase identifiers; route labels lowercase with hyphens.",
            "type": "object"
          },
          "name": {
            "maxLength": 120,
            "type": "string"
          },
          "project_id": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "slug": {
            "pattern": "^[a-z0-9][a-z0-9-]{0,62}$",
            "type": "string"
          },
          "suite_id": {
            "description": "Revise this suite. Leave out to create one; then project_id and slug are required.",
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "definition"
        ],
        "type": "object"
      }
    }
  ],
  "transport": "streamable-http"
}
