Repository navigation
feat(website): a website env may be an MCP server too, its tools declared on its card (FD-4683) - #508
Open
williamloo-scale wants to merge 13 commits into
Open
williamloo-scale wants to merge 13 commits into
williamloo-scale wants to merge 13 commits into
Conversation
…ses the conformance check (FD-4683) This PR's change, rebased as one commit onto #428. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s, and adds a note once per submit (FD-4683) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…sign-in fails, and reloads itself at its slash-ending address (FD-4683) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…hrough data/get, not /go (FD-4683) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s, settles a save the server accepted, and reloads itself on its own origin (FD-4683) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…through website/v1's ready alone (FD-4683) The SDK on main keeps no store and serves no health path, so Notes holds its users and notes itself, starting from data/seed.json, serves them through @reset_data, @add_data and @get_data, and names its acting user with acting_user(). Its readiness is website/v1's ready (@ready_check seeded); env.toml and the image's health check no longer name /healthz, which the compose health check now reads as the card. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
williamloo-scale
force-pushed
the
wloo/website-mcp
branch
from
November 5, 2026 22:58
ca89cc2 to
6bacb91
Compare
williamloo-scale
changed the base branch from
main
to
wloo/website-notes-example
November 5, 2026 22:58
…oncurrent writes keep every note (FD-4683) Plain def handlers run in worker threads, so two creates could choose one id, and a create could append to a list a delete was replacing. Every read and write of the site's data is under one lock, ids chosen and notes inserted together, and the handlers answer copies. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ared on its card (FD-4683) - A WebsiteEnvironment with @tool or @resource methods serves them at /mcp (streamable HTTP, the mcp package) beside its pages, @api routes and data plane, in the site's process and under its clock; its card declares that endpoint as its mcp interface and lists the tools. A site without them serves no /mcp and declares none (serves_mcp()). - The gateway reads each site's card when it starts and serves the tools of one whose card declares an mcp interface as it does an MCP env's, with the caller's role in ToolContext. A site's interfaces are among the paths its card advertises, so its browsing route never reaches its /mcp. - Conformance checks a declared mcp endpoint: it answers initialize and lists the card's tools; a site without one skips the check. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e, sites are found at once, and conformance reads every page - A call to a site's MCP endpoint through /svc/<name>/ gets the gateway's role in its JSON-RPC _meta, as an MCP server's does, at the endpoint its card declares (site_mcp_endpoints), so a caller can't claim another role there. - The gateway asks every site for its card at once, so a site that never comes up leaves another its own retries. - Conformance reads every page of tools/list, fails a listed tool the card doesn't name, and warns on a card's tool it doesn't list, as a hidden-by-default one is listed to no caller. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
williamloo-scale
force-pushed
the
wloo/website-mcp
branch
from
November 5, 2026 23:06
6bacb91 to
7a909f1
Compare
…wever its card writes it, and conformance reads whole events - The gateway takes a card's MCP endpoint written as a full URL when it names the site's own server, joining a path under the site's address as before, and leaves out, saying so, one on another server. - A site's reserved paths come from each URL its card advertises, a full one or one with a query as well as a bare path, so its browsing route never reaches /mcp however the card writes it. - Conformance reads an event stream's events whole, their data lines joined, and takes the reply to its own request, as ToolSession does, so a reply split over lines or beside notifications is read right. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…d the /svc role stamp matches it by address A card may write its own server differently from the gateway's base (https://shop.test:443/mcp beside https://shop.test). Discovery now returns the endpoint under the base's own spelling, and site_mcp_endpoints compares parsed scheme, host and port rather than a string prefix, so a call through /svc/<name>/ to that endpoint still gets the gateway's role in its _meta. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… own path A card's full URL already names its path from the server's root, so the gateway keeps that path on the site's scheme and host instead of joining it under the site's base path, which a prefixed base doubled. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A website env can now also be an MCP server. A site gives agents tools beside its pages, its card declares them, and the gateway serves them as it does an MCP env's. Stacked on #429 (the Notes example, rebased onto main after #428 merged). The Notes example skips the new
mcpcheck, since it serves no tools.What changes
agentenv_protocol.website):WebsiteEnvironmentwith@toolor@resourcemethods serves them at/mcp(streamable HTTP, needs themcppackage). They run in the site's own process, beside its pages,@apiroutes and data plane, so a tool call changes what the pages show and whatdata/getreturns, and it reads the universe clock (self.now()).mcpinterface (additionalInterfaces) and lists the tools undercapabilities.tools./mcpand declares no interface.serves_mcp()tells you which kind a site is.mcpinterface, the gateway adds the site as an internal MCP server, so agents see its tools with the rest, called with the caller's role inToolContext.site_reserved_pathsnow includes a card's interfaces, so the browsing route (/website/<name>/) never reaches a site's/mcp, as with the data plane.mcpcheck. When the card declares the interface, the endpoint must answerinitializeandtools/listmust name exactly the card's tools. A site without one skips the check.Tests
packages/agentenv-protocol/tests/test_website_mcp.py:/mcpand its tools;data/getreturn, with the caller's role andX-Universe-Now;/mcp;mcpcheck fails on a tools mismatch or a missing endpoint, and sends nothing when the interface names another server.tst/unit/env/gateway/website_mcp_test.py:/website/shop/mcpanswers 404, and/svc/shop/agentenvdata/getsees the order the tool placed.cua_driver_test,test_disk_recipeand two intest_optional_extras_stay_optional.process_scope_socket_test::test_an_armed_time_trigger_keeps_firing_after_a_client_leaves, is a timing test that failed under full-suite load and passed 5 out of 5 on its own.tst/unit/env/gatewaypasses on its own (810 tests).🤖 Generated with Claude Code


Confidence Score: 5/5
The PR appears safe to merge; no blocking issues remain.Summary
Websites can serve MCP tools beside their pages. The gateway discovers those tools from each site's card and keeps MCP endpoints out of browser routes.
Diagram
%%{init: {'theme': 'neutral'}}%% flowchart LR Card[Website card] --> Discovery[Gateway discovery] Discovery --> Tools[Gateway tools] Tools --> MCP[Website MCP endpoint] Service[Service route] --> Stamp[Gateway writes caller role] Stamp --> MCP Browser[Browser route] --> Block[Declared MCP path returns 404]Reviews (7) · Last reviewed commit: "fix(website): a full MCP URL on a site b..." · Reviewed by Greptile