WebMCP
The product, its domain operations, and its visible effects are the work. Tool registration is an adapter over that work, not a substitute for it. When requested, add a page-independent MCP adapter alongside WebMCP without pretending that either surface automatically invokes the other.
1. Normalize the build profile
Record these axes before implementation:
- Mode:
CREATEfor a new or incomplete product;EXTENDfor an existing product. - Surface:
WEBMCPfor page-bound tools;DUALfor WebMCP plus an independently useful MCP adapter. Route standalone MCP-only work elsewhere. - Target:
webmcp-document,chatgpt-site-tools, orchromium-webmcp. - Experimental branch:
webmcp-declarativeorwebmcp-service-workeronly when explicitly selected. - Release:
DEVELOPMENT,PRODUCTION, orCHALLENGE. - Framework: the repository's actual stack; choose one for CREATE only when the user has not already constrained it.
Read references/product-compiler.md. Read references/compatibility-profiles.md whenever a target, browser, product, declarative form, or Service Worker is involved.
2. Establish the evidence baseline
For repository work, inspect package manifests, framework and language, source roots, routes/components, forms, state stores, services, API clients, authorization and confirmation paths, tests, deployment configuration, and existing WebMCP or MCP symbols.
python scripts/webmcp_toolkit.py scan-repo PATH --format json
python scripts/webmcp_toolkit.py compatibility PATH --format json
Treat scanner matches as candidates until source context proves their meaning. Read references/repository-integration.md. For API or compatibility claims, use references/official-source-map.md and its canonical upstream URLs. The portable Skill has no dependency on a repository-level documentation corpus.
3. Define the shared product journey
Build a capability map before naming tools:
human goal
→ shared artifact or page state
→ normal UI entry point
→ canonical operation and state owner
→ validation, authorization, persistence, and network effects
→ WebMCP tool
→ optional MCP adapter
→ visible and structured completion evidence
→ lifecycle and tests
In CREATE mode, implement the smallest complete human product that makes this journey real. In EXTEND mode, trace the current journey and identify exact gaps. A tool is not complete if the corresponding result cannot be inspected, corrected, or continued through the application.
Represent that journey in a product profile and validate it before code generation:
python scripts/webmcp_toolkit.py validate-product PRODUCT.json
python scripts/webmcp_toolkit.py product-plan PRODUCT.json --target auto
product-plan is read-only. Treat missing handlers, UI ownership, effect bindings, or capability-to-tool mappings as implementation work; rerun it after the canonical operations exist.
4. Pass the surface and API gates
Read references/platform-and-compatibility.md.
- Choose WebMCP when the action depends on the open page, current route, selection, canvas, map, dashboard, document, signed-in browser session, or a shared visible artifact.
- Choose DUAL when both the open-page interaction and page-independent service access are useful. Read
references/dual-webmcp-mcp.md. - Choose imperative document WebMCP for the production baseline.
- Choose declarative only for an existing semantic form under a verified experimental target. Read
references/declarative-forms.md. - Choose Service Worker WebMCP only as an explicit proposal/research profile. Read
references/service-worker-profile.md.
Do not claim that WebMCP automatically calls MCP. A host agent may orchestrate both, or the application may contain an explicit bridge. An MCP server cannot substitute for genuine page-bound WebMCP when WebMCP is the requested output.
For an explicitly selected proposal branch, inspect maturity before rendering any artifact:
python scripts/webmcp_toolkit.py proposal-status --kind declarative
python scripts/webmcp_toolkit.py proposal-status --kind service-worker
Use generate-proposal only for a selected proposal profile. Its output and status sidecar remain proposal evidence, not current document-WebMCP conformance.
python scripts/webmcp_toolkit.py generate-proposal declarative \
--output-dir PROPOSAL_OUT --tool-name TOOL_NAME \
--description "PROPOSAL_ONLY_TOOL_DESCRIPTION"
5. Implement canonical operations and the normal UI
For every capability, establish a real operation before registration. The operation may be an existing handler, a reviewed extraction, or new application code created for the agreed journey.
Requirements:
- one typed and testable application boundary;
- normal UI calls the same boundary as adapters;
- validation, authorization, confirmation, and persistence remain authoritative;
- visible loading, success, partial, conflict, and error states where relevant;
- stable entity IDs or revisions for shared mutable artifacts where relevant;
- human controls remain usable when WebMCP is unavailable;
- agent activity and its visible effects are inspectable in proportion to the product.
6. Design the smallest useful tool topology
Read references/tool-surface-and-schema.md. Prefer an inspect–act–verify topology:
inspect current state → perform one coherent operation → return changed entities/revision → verify visible state
For each tool define its exact completion boundary, current-state preconditions, minimum inputs, JSON Schema, canonical operation, UI effect, result evidence, errors, cancellation, lifetime, annotations, and origin exposure. Do not optimize for tool count; optimize for reliable selection and meaningful application leverage.
Validate the low-level toolset manifest when used:
python scripts/webmcp_toolkit.py validate MANIFEST.json --format json
The manifest's semantics section is build-time review data and MUST NOT be emitted as browser tool metadata.
7. Register and bind WebMCP
Read references/imperative-implementation.md and the relevant section of references/framework-recipes.md.
python scripts/webmcp_toolkit.py patch-plan REPO MANIFEST --target react --format json
python scripts/webmcp_toolkit.py generate MANIFEST.json --target react
Write generated output only when requested:
python scripts/webmcp_toolkit.py generate MANIFEST.json \
--target react --output src/webmcp/useWebMCPTools.ts --write
When a validated product profile exists, prefer the capability-aware compiler over low-level adapter generation. Preview first, then repeat with --write after reviewing the output plan:
python scripts/webmcp_toolkit.py compile-product PRODUCT.json \
--target react --output-dir src/webmcp
python scripts/webmcp_toolkit.py compile-product PRODUCT.json \
--target react --output-dir src/webmcp --write
Supported generator targets are vanilla-js, typescript, react, next, vue, svelte, and angular. Use generated code as an adapter, then bind the actual operation collection in application code.
Implementation requirements:
- feature-detect
document.modelContext?.registerTool; - validate the actual current handler collection before constructing proxies or registering any tool;
- register transactionally with a lifecycle
AbortSignal; - pass callback
options.signalinto cancellable application work; - abort earlier registrations if setup partially fails;
- make teardown idempotent and lifecycle-correct;
- assert that callback results are JSON-serializable;
- update the same state path used by the human UI;
- preserve SSR by registering only in a client lifecycle;
- type-check TypeScript output against the current official
webmcp-typespackage without treating the package as a runtime polyfill.
8. Add the MCP adapter in DUAL mode
Read references/dual-webmcp-mcp.md. Select which canonical operations are independently useful without an open page. Expose only those through the repository's MCP server stack.
When browser and server cannot share an in-memory module, both adapters MUST call the same versioned backend/domain contract. Keep page selection, ephemeral canvas state, and other page-only context on WebMCP. Test each surface independently, then test host-agent composition.
For the high-level official MCP TypeScript SDK, pass the DUAL template's explicit createMCPTypeScriptSDKInputSchemaAdapter(z) hook to bindServer; the SDK expects Zod schemas rather than the portable JSON Schema stored in the DUAL contract. Pin both SDK and Zod versions in the owning server project and fail the build if a schema cannot be translated without weakening it.
Validate the DUAL mapping before adapter integration:
python scripts/webmcp_toolkit.py dual-check DUAL_CONTRACT.json
Passing this check proves contract structure and shared-operation mapping only. It does not replace independent WebMCP, MCP transport, page-closed, authorization, or end-to-end tests.
9. Evaluate in layers
Read references/debugging-and-evaluation.md.
Run deterministic checks before live checks:
- contract and manifest validation;
- generated-code syntax and type checking;
- actual-handler preflight and partial-registration rollback;
- direct operation tests and normal UI tests;
- registration, teardown, navigation, remount, and BFCache behavior;
- execution cancellation and commit-boundary behavior;
- JSON-serializable success and failure results;
- unsupported-browser fallback;
- DUAL adapter parity when selected.
Generate the existing layered plan when useful:
python scripts/webmcp_toolkit.py eval-plan MANIFEST.json --format json
For a product profile, generate the release-aware evidence plan and run the bundled deterministic self-test separately from project checks:
python scripts/webmcp_toolkit.py verification-plan PRODUCT.json
python scripts/webmcp_toolkit.py self-test --profile core --format json
python scripts/webmcp_toolkit.py self-test --profile full --format json
core runs the packaged Python contract/compiler suite in validation/python/ and the Node runtime/fixture suite in validation/node/. full adds framework-generation type checking from the manifests in validation/typecheck/. It installs the locked compiler matrix in an automatically deleted temporary workspace outside the Skill source; installed dependencies MUST NOT be placed in the Skill. Missing Node.js or npm is reported as BLOCKED or NOT_RUN, never as a pass.
Refresh volatile official-source evidence before a release decision, then bind receipts and results to the candidate:
python scripts/webmcp_toolkit.py source-status PRODUCT.json \
--source-refresh SOURCE_REFRESH.json --repository-root REPO
python scripts/webmcp_toolkit.py verify PRODUCT.json TOOLSET.json \
--release RELEASE.json --receipts RECEIPTS.json \
--source-refresh SOURCE_REFRESH.json --repository-root REPO --format json
Then run available WPT/browser discovery, Chrome evaluation, agent-selection, native Chrome, native ChatGPT Site-tools, and end-to-end visible-state checks. Report each layer independently. A shim is not browser conformance; browser registration is not correct tool selection; tool selection is not evidence of the application effect.
10. Apply proportionate assurance
Read references/security-and-authority.md when requested or when tools involve external/user-generated output, sensitive data, cross-origin exposure, remote writes, communication, purchases, permissions, deletion, or irreversible effects.
python scripts/webmcp_toolkit.py threat-model MANIFEST.json --format json
Keep the baseline in every build: accurate metadata, minimum inputs, existing authorization, normal confirmation, output-trust annotation, origin minimization, and UI/tool-path parity. Do not invent unsupported confirmation or elicitation APIs.
11. Finish for the selected release profile
Read references/release-profiles.md for PRODUCTION or CHALLENGE.
Before delivery:
- list exact changed and generated files;
- inventory canonical operations and WebMCP/MCP exposure;
- report deterministic, browser, agent, deployment, and host checks separately;
- identify implementation-specific assumptions and unresolved proposal behavior;
- verify ordinary human use and shared visible state;
- validate the exact tested tree from a fresh extraction;
- for CHALLENGE, prepare the live-app, public-repository, license, narrative, evidence, and demo-video package without claiming external publication that did not occur.
Apply the final release gate only to candidate-bound receipts from the exact tree being delivered:
python scripts/webmcp_toolkit.py release-check PRODUCT.json TOOLSET.json \
--release RELEASE.json --receipts RECEIPTS.json \
--source-refresh SOURCE_REFRESH.json --repository-root REPO --format json
A missing native browser, deployment, video, or ChatGPT-host receipt remains NOT_RUN or BLOCKED; release-check must not synthesize it.
- Outcome — what product capability now works.
- Selected profile — mode, surface, targets, experimental branches, framework, and release.
- Capability mapping — canonical operation, normal UI owner, WebMCP tool, optional MCP tool, and visible/result evidence.
- Files — exact files created, changed, generated, or intentionally untouched.
- Verification matrix — check layer, environment, human-facing status (
PASS,WARN,FAIL,UNSUPPORTED, orNOT RUN), exact machine status when a receipt exists (PASS,FAIL,BLOCKED,UNSUPPORTED, orNOT_RUN), and concrete evidence. - Remaining work — blockers, unsupported proposal behavior, and external actions not performed.
For audits or designs, give the conclusion first, then evidence, compatibility/maturity distinctions, exact findings, and the recommended implementation boundary. Never merge static, shim, browser, model, deployment, or ChatGPT-host evidence into one pass claim.