#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; /** * ONE registry, TWO transports. * * `server` was a module-level singleton because stdio is the only transport * that has ever existed here. A hosted endpoint needs its own instance per * process (and, in stateless HTTP, potentially per request), so construction * moves into a factory and both entry points call it. * * THE POINT OF THE FACTORY is not reuse, it is preventing DRIFT. A second, * hand-written tool list for the HTTP surface would diverge within weeks and * the divergence would be invisible: hosted users would silently get a * different product from stdio users. `tests/transport-parity.test.mjs` pins * that both transports expose byte-identical tool definitions. */ export declare function createServer(): Server; declare const server: Server<{ method: string; params?: { [x: string]: unknown; _meta?: { [x: string]: unknown; progressToken?: string | number | undefined; "io.modelcontextprotocol/related-task"?: { taskId: string; } | undefined; } | undefined; } | undefined; }, { method: string; params?: { [x: string]: unknown; _meta?: { [x: string]: unknown; progressToken?: string | number | undefined; "io.modelcontextprotocol/related-task"?: { taskId: string; } | undefined; } | undefined; } | undefined; }, { [x: string]: unknown; _meta?: { [x: string]: unknown; progressToken?: string | number | undefined; "io.modelcontextprotocol/related-task"?: { taskId: string; } | undefined; } | undefined; }>; /** Every tool this server implements. ONE registry — the hosted list is * derived from it, never written separately. * * transport_parity.test.mjs exists because "a second file with its own tool * list diverges within weeks, and the divergence is INVISIBLE: hosted users * silently get a different product, and nothing goes red." That reasoning is * still right, and it is why this is a filter over one array rather than two * arrays. What the parity test now pins is that the hosted set is a SUBSET * whose shared definitions are byte-identical — a visible, tested divergence * instead of an accidental one. */ export declare const ALL_TOOLS: ({ readonly name: "list_specs"; readonly description: string; readonly inputSchema: { readonly type: "object"; readonly properties: { readonly filter: { readonly type: "string"; readonly description: string; }; }; readonly additionalProperties: false; }; } | { readonly name: "list_workflows"; readonly description: string; readonly inputSchema: { readonly type: "object"; readonly properties: { readonly spec_id: { readonly type: "string"; readonly description: "The spec_id returned by import_spec."; }; readonly spec_slug: { readonly type: "string"; readonly description: string; }; }; readonly additionalProperties: false; }; } | { readonly name: "validate_integration"; readonly description: string; readonly inputSchema: { readonly type: "object"; readonly properties: { readonly providers: { readonly type: "array"; readonly items: { readonly type: "string"; }; readonly description: string; }; readonly app_base_url: { readonly type: "string"; readonly description: string; }; readonly session_id: { readonly type: "string"; readonly description: string; }; readonly arm: { readonly type: "string"; readonly description: "Probe ID from the matrix to arm before running the app. Requires session_id."; }; readonly probe: { readonly type: "string"; readonly description: "Probe ID from the matrix to evaluate after running the app. Requires session_id and run_id."; }; readonly run_id: { readonly type: "string"; readonly description: "Attempt ID returned by arm. Required with probe or cancel; prevents stale calls from consuming a newer attempt."; }; readonly cancel: { readonly type: "boolean"; readonly description: "Abort the attempt or retry failed cleanup. Requires session_id and run_id; cannot combine with arm or probe."; }; readonly suite: { readonly type: "string"; readonly enum: readonly ["receipt_delivery_v1", "receipt_recovery_v1", "application_workflow_v1"]; readonly description: "Configure the declared application receipt suite on this session."; }; readonly receipt_config: { readonly type: "object"; readonly properties: { readonly webhook_url: { readonly type: "string"; readonly description: "Exact normal application webhook URL, including path."; }; readonly recipient_a: { readonly type: "string"; readonly description: "Expected test recipient for purchase A, fixed before execution."; }; readonly recipient_b: { readonly type: "string"; readonly description: "Different test recipient for the different-customer case."; }; readonly purchase_marker: { readonly type: "object"; readonly properties: { readonly field: { readonly type: "string"; readonly enum: readonly ["html", "text", "subject", "tags"]; }; readonly tag_name: { readonly type: "string"; }; }; readonly required: readonly ["field"]; readonly additionalProperties: false; readonly description: "Where the normal receipt includes its Paddle transaction ID; same-record recipient/marker matching is required."; }; readonly observation_seconds: { readonly type: "number"; readonly minimum: 0.1; readonly maximum: 5; readonly description: "Observation window after each checkpoint; default 2 seconds. Verdict covers only measured windows."; }; readonly app_version: { readonly type: "string"; readonly description: "Declared application build identifier; not code attestation."; }; readonly source_lookup_required: { readonly type: "boolean"; readonly description: "Whether the app reads the source provider during its normal webhook handler."; }; readonly purchase_context: { readonly type: "object"; readonly description: "Application routing custom_data, e.g. test workspace ID. Never credentials."; }; }; readonly required: readonly ["webhook_url", "recipient_a", "recipient_b", "purchase_marker", "app_version", "source_lookup_required"]; readonly additionalProperties: false; }; readonly preflight: { readonly type: "boolean"; readonly description: "Read-only public readiness check for a configured application_workflow_v1. Requires session_id/run_id. Checks frozen empty baseline and token enforcement without creating orders, injecting faults or rotating secrets. Retry same run after its exact setup blocker is repaired."; }; readonly execute: { readonly type: "boolean"; readonly description: "Drive the configured app and evaluate the frozen receipt suite. Requires session_id/run_id; configuration acknowledgment alone is not proof. Starts the existing backend job asynchronously and returns promptly; follow status in this agent without allocating a background helper."; }; readonly fixtures: { readonly type: "object"; readonly required: readonly ["id", "steps"]; readonly additionalProperties: false; readonly description: "Prepare session-owned twin data before app tests. Requires session_id. Stable id makes repeated calls replay-safe. Every step names spec, method and relative path. Use {{step1.id}} for dependencies. End with GET and an exact identity assertion. No live provider calls."; readonly properties: { readonly id: { readonly type: "string"; readonly minLength: 1; readonly maxLength: 100; }; readonly steps: { readonly type: "array"; readonly minItems: 1; readonly maxItems: 40; readonly items: { readonly type: "object"; readonly required: readonly ["spec", "method", "path"]; readonly additionalProperties: false; readonly properties: { readonly name: { readonly type: "string"; }; readonly spec: { readonly type: "string"; }; readonly method: { readonly type: "string"; readonly enum: readonly ["GET", "POST", "PUT", "PATCH", "DELETE"]; }; readonly path: { readonly type: "string"; }; readonly body: { readonly type: "object"; }; readonly query_params: { readonly type: "object"; }; readonly expect_status: { readonly type: "integer"; readonly minimum: 200; readonly maximum: 299; }; readonly assertion: { readonly type: "object"; readonly required: readonly ["select", "equals", "required", "count"]; readonly additionalProperties: false; readonly description: "GET read-back only. Exactly four fields, e.g. {select: data.id, equals: '{{step2.id}}', required: true, count: 1} for Paddle. Use separate GET assertions for amount and currency; application all_of/where and JSON scalar predicates are not supported here."; readonly properties: { readonly select: { readonly type: "string"; }; readonly equals: { readonly type: "string"; }; readonly required: { readonly type: "boolean"; readonly enum: readonly [true]; }; readonly count: { readonly type: "integer"; readonly enum: readonly [1]; }; }; }; }; }; }; }; }; readonly application_context: { readonly type: "object"; readonly required: readonly ["goal"]; readonly additionalProperties: false; readonly description: "Bounded inspected app summary, not credentials or raw code. The existing requirements model proposes rules; it cannot issue a verdict. Requires session_id; separate from fixtures/execution."; readonly properties: { readonly goal: { readonly type: "string"; }; readonly app_version: { readonly type: "string"; }; readonly workflow: { readonly type: "string"; }; readonly entry_points: { readonly type: "array"; readonly items: { readonly type: "string"; }; }; readonly state_store: { readonly type: "string"; }; readonly fixture_requirements: { readonly type: "array"; readonly items: { readonly type: "string"; }; }; }; }; readonly application_config: { readonly type: "object"; readonly required: readonly ["app_version", "disposable_test_app", "checks"]; readonly additionalProperties: false; readonly description: "Frozen HTTP app drive/read-back contract: 1-30 checks, 1-20 actions per executable check, at most 300 declared actions in total, below 64 KiB. Preserve intermediate reads within these bounds; do not silently remove them. First check id=baseline must establish success. Checks require id, name, before {path,assertion}, ordinary HTTP actions [{method,path,body?,expect_status?}] or signed-event actions [{event:{provider,type,payload},expect_status?}], observe {path}, and assertion using select/equals/count/required or all_of. where and all_of must be lists of assertion objects, not field maps. equals accepts JSON strings, numbers, booleans and null; numeric/boolean literals preserve type, and null must be a present null field. Stripe event.payload is only the resource inside data.object, never a full event or a data.object wrapper: the server constructs and signs the envelope. Optional per-check observation_deadline_seconds (0-180, repeat=1 only) records bounded polling for eventual saved state; it does not drive a browser or turn a timeout into a pass. Every check first reads its declared starting-state precondition. Baseline requires count=0 on the same observed collection, with no where filter. Use {{run_id}} to scope fresh synthetic records. All paths are app-relative without query strings or fragments, including non-secret run_id queries; preserve run scoping through an inspected protected path-segment observer. Baseline permits only ordinary HTTP actions without signed events; prove signed purchase/access in later checks. Do not combine event actions with method/path/body/headers. {{step1.id}} binds a real action response to read-back. assertion.repeat (1-5) and stable_under_repeat support replay. Optional fault {provider,scenario} requires independently recorded provider refusal. Unsupported checks contain id,name,unsupported_reason only. No user-supplied credentials, auth headers or live data. require_verifier_token=true generates an owner-only temporary Bearer token through secure handoff for protected test endpoints."; readonly properties: { readonly app_version: { readonly type: "string"; }; readonly disposable_test_app: { readonly type: "boolean"; readonly enum: readonly [true]; }; readonly require_verifier_token: { readonly type: "boolean"; }; readonly coverage_review: { readonly type: "array"; readonly maxItems: 17; readonly description: "Applicability review against the returned coverage_policy. Missing dimensions remain unreviewed. Link relevant dimensions to declared checks, including explicitly unsupported checks. This is a proposed review, not execution proof."; readonly items: { readonly type: "object"; readonly required: readonly ["dimension", "relevance", "reason", "rule_ids"]; readonly additionalProperties: false; readonly properties: { readonly dimension: { readonly type: "string"; }; readonly relevance: { readonly type: "string"; readonly enum: readonly ["relevant", "not_applicable", "unresolved"]; }; readonly reason: { readonly type: "string"; }; readonly rule_ids: { readonly type: "array"; readonly items: { readonly type: "string"; }; }; }; }; }; readonly event_destinations: { readonly type: "object"; readonly additionalProperties: { readonly type: "string"; }; readonly description: "Session-provider to same-origin webhook path without query/fragment. Requires require_verifier_token=true and the isolated FETCHSANDBOX__WEBHOOK_SECRET from secure handoff. Complete signed action shape: {event:{provider,type,payload},expect_status:200}; exact replay: {event:{provider,replay_of:'{{step2.event_id}}'},expect_status:200}. No method/path/body/headers on signed actions. Baseline uses ordinary HTTP actions; signed events belong in later checks. Existing signature checks must remain enabled."; }; readonly observation_seconds: { readonly type: "number"; readonly minimum: 0.1; readonly maximum: 5; }; readonly checks: { readonly type: "array"; readonly minItems: 1; readonly maxItems: 30; readonly items: { readonly type: "object"; }; }; }; }; }; readonly additionalProperties: false; }; } | { readonly name: "list_runs"; readonly description: string; readonly inputSchema: { readonly type: "object"; readonly properties: { readonly sandbox_id: { readonly type: "string"; readonly description: "The sandbox_id returned by import_spec."; }; readonly limit: { readonly type: "number"; readonly description: "Max number of runs to return (default 20, server may cap)."; }; }; readonly required: readonly ["sandbox_id"]; readonly additionalProperties: false; }; } | { readonly name: "list_scenarios"; readonly description: string; readonly inputSchema: { readonly type: "object"; readonly properties: { readonly sandbox_id: { readonly type: "string"; readonly description: "The sandbox_id returned by quickrun, run_workflow or import_spec."; }; }; readonly required: readonly ["sandbox_id"]; readonly additionalProperties: false; }; } | { readonly name: "set_scenario"; readonly description: string; readonly inputSchema: { readonly type: "object"; readonly properties: { readonly sandbox_id: { readonly type: "string"; readonly description: "The sandbox to arm. From quickrun, run_workflow or import_spec."; }; readonly scenario: { readonly type: "string"; readonly description: string; }; }; readonly required: readonly ["sandbox_id", "scenario"]; readonly additionalProperties: false; }; } | { readonly name: "run_workflow"; readonly description: string; readonly inputSchema: { readonly type: "object"; readonly properties: { readonly sandbox_id: { readonly type: "string"; readonly description: "The sandbox_id returned by import_spec."; }; readonly workflow_name: { readonly type: "string"; readonly description: string; }; readonly scenario: { readonly type: "string"; readonly description: string; }; }; readonly required: readonly ["sandbox_id", "workflow_name"]; readonly additionalProperties: false; }; } | { readonly name: "run_all_workflows"; readonly description: string; readonly inputSchema: { readonly type: "object"; readonly properties: { readonly sandbox_id: { readonly type: "string"; readonly description: "The sandbox_id returned by import_spec."; }; readonly workflow_names: { readonly type: "array"; readonly items: { readonly type: "string"; }; readonly description: string; }; }; readonly required: readonly ["sandbox_id"]; readonly additionalProperties: false; }; } | { name: string; description: string; inputSchema: { type: string; properties: { intent: { type: string; description: string; }; hints: { type: string; description: string; properties: { spec: { type: string; description: string; }; workflow: { type: string; description: string; }; scenario: { type: string; description: string; }; }; }; }; required: string[]; }; } | { name: string; description: string; inputSchema: { type: string; properties: { intent: { type: string; description: string; }; session_id: { type: string; description: string; }; user_response: { type: string; description: string; }; context: { type: string; description: string; }; }; }; } | { readonly name: "verify_behavior"; readonly description: string; readonly inputSchema: { readonly type: "object"; readonly properties: { readonly bug_pattern_id: { readonly type: "string"; readonly description: string; }; readonly prompt: { readonly type: "string"; readonly description: string; }; readonly sandbox_id: { readonly type: "string"; readonly description: string; }; readonly flow_run_id: { readonly type: "string"; readonly description: string; }; }; readonly required: readonly ["bug_pattern_id"]; readonly additionalProperties: false; }; } | { name: string; description: string; inputSchema: { type: string; properties: { sandbox_id: { type: string; description: string; }; flow_run_id: { type: string; description: string; }; bug_pattern_id: { type: string; description: string; }; summary: { type: string; description: string; }; proofs: { type: string; description: string; items: { type: string; properties: { name: { type: string; }; request: { type: string; properties: { method: { type: string; }; path: { type: string; }; body: {}; }; }; before: { type: string; properties: { status: { type: string; }; body: {}; error: { type: string; }; }; }; after: { type: string; properties: { status: { type: string; }; body: {}; error: { type: string; }; }; }; }; required: string[]; }; }; }; required: string[]; }; } | { readonly name: "quickrun"; readonly description: string; readonly inputSchema: { readonly type: "object"; readonly properties: { readonly spec_slug: { readonly type: "string"; readonly description: "The bundled spec slug from guide (e.g. 'stripe'). Lowercase."; }; readonly workflow_name: { readonly type: "string"; readonly description: "The workflow id from guide (e.g. 'accept_payment')."; }; readonly scenario: { readonly type: "string"; readonly description: string; }; }; readonly required: readonly ["spec_slug", "workflow_name"]; readonly additionalProperties: false; }; } | { readonly name: "find_bugs"; readonly description: string; readonly inputSchema: { readonly type: "object"; readonly properties: { readonly path: { readonly type: "string"; readonly description: string; }; readonly spec: { readonly type: "string"; readonly description: string; }; readonly timeout_s: { readonly type: "number"; readonly description: "OPTIONAL. Analysis budget in seconds (default 300, max 600)."; }; }; readonly additionalProperties: false; }; } | { readonly name: "fix_bug"; readonly description: string; readonly inputSchema: { readonly type: "object"; readonly properties: { readonly bug: { readonly type: "string"; readonly description: string; }; readonly fix_pattern: { readonly type: "string"; readonly description: string; }; readonly path: { readonly type: "string"; readonly description: string; }; readonly spec: { readonly type: "string"; readonly description: "OPTIONAL. Grounding hint for the integration (e.g. 'stripe')."; }; readonly timeout_s: { readonly type: "number"; readonly description: "OPTIONAL. Fix budget in seconds (default 300, max 600)."; }; }; readonly required: readonly ["bug"]; readonly additionalProperties: false; }; } | { readonly name: "prove_fix"; readonly description: string; readonly inputSchema: { readonly type: "object"; readonly properties: { readonly diff: { readonly type: "string"; readonly description: "The unified diff returned by fix_bug."; }; readonly bug: { readonly type: "string"; readonly description: "The finding being fixed — used to select FetchSandbox's scenario."; }; readonly scenario: { readonly type: "string"; readonly description: "OPTIONAL. Explicit scenario id, if known."; }; readonly sandbox_id: { readonly type: "string"; readonly description: string; }; readonly path: { readonly type: "string"; readonly description: string; }; readonly timeout_s: { readonly type: "number"; readonly description: "OPTIONAL. Budget in seconds (default 300)."; }; }; readonly required: readonly ["diff"]; readonly additionalProperties: false; }; })[]; /** What a browser-based app builder is shown. MEASURED, not guessed. * * Hosted callers were being offered 17 tools of which FOUR CANNOT WORK: * find_bugs, fix_bug and prove_fix read the filesystem and throw, and * import_spec now redirects. Worse, find_bugs opens "FIRST STEP for any * API-integration bug — reach for this the moment a user reports a symptom", * so the loudest routing claim in the whole list belonged to a tool a Lovable * agent can never call. * * The rest were near-duplicates competing for the same slot: three ways to run * a workflow, four ways to list something. Selection accuracy is measured to * peak at 5–8 tools and degrade past 10–15, and closely-related tools are the * worst case — which is exactly the shape we had. * * Nothing here was removed on taste. Across every hosted session ever served, * exactly seven tools have been called: quickrun, coach, run_workflow, guide, * list_workflows, verify_behavior, submit_proof. Everything dropped below has * zero hosted calls, all time. * * set_scenario and list_scenarios are dropped despite being "the moat": both * require a sandbox_id, list_workflows now returns the scenarios anyway, and * NEITHER HAS EVER BEEN CALLED BY ANY CLIENT, ONCE, in 5,200+ calls. Arming is * reachable through quickrun/run_workflow's `scenario` argument, which is how * the 1.72% of runs that do inject a failure got there. * * STDIO IS UNTOUCHED. Claude Code and Cursor keep all of ALL_TOOLS, byte for * byte: they have a filesystem, they compose tools correctly, and they have a * human in the loop. */ export declare const HOSTED_TOOL_NAMES: Set; export declare function registerHandlers(server: Server): void; export { server };