feat(plugin-webmcp): add WebMCP support - #3520
Conversation
7cb9b96 to
79a3d1a
Compare
Deploying rspress-v2 with
|
| Latest commit: |
b19adaf
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://337c6da5.rspress-v2.pages.dev |
| Branch Preview URL: | https://codex-plugin-webmcp.rspress-v2.pages.dev |
There was a problem hiding this comment.
Pull request overview
Adds a new official @rspress/plugin-webmcp package that exposes Rspress documentation tools to browser agents via the native document.modelContext WebMCP API, with accompanying docs, fixtures, and core runtime updates to support hot-refreshable local search and awaited internal navigation.
Changes:
- Introduces
@rspress/plugin-webmcp(runtime + types + tests) with built-in current-page, search, and internal navigation tools plus custom tool registration APIs. - Updates core runtime to (a) reinitialize local search across language/version changes and (b) support awaited/cancellable link navigation.
- Adds docs (EN/ZH), changeset, dictionary entry, and Playwright fixtures covering production + dev/HMR behavior.
Reviewed changes
Copilot reviewed 49 out of 51 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| website/docs/zh/plugin/official-plugins/webmcp.mdx | Adds Chinese documentation for the new WebMCP plugin. |
| website/docs/zh/plugin/official-plugins/overview.mdx | Links the new plugin from the official plugins overview (ZH). |
| website/docs/zh/plugin/official-plugins/_meta.json | Adds webmcp to the official plugin docs sidebar ordering (ZH). |
| website/docs/en/plugin/official-plugins/webmcp.mdx | Adds English documentation for the new WebMCP plugin. |
| website/docs/en/plugin/official-plugins/overview.mdx | Links the new plugin from the official plugins overview (EN). |
| website/docs/en/plugin/official-plugins/_meta.json | Adds webmcp to the official plugin docs sidebar ordering (EN). |
| scripts/dictionary.txt | Adds webmcp to the spellcheck dictionary. |
| pnpm-lock.yaml | Locks new dependencies/importers for the plugin and fixtures. |
| packages/plugin-webmcp/tsconfig.json | Adds TS project config for the new plugin package. |
| packages/plugin-webmcp/tests/useWebMcpTool.test.ts | Unit tests for descriptor dependency tracking/serialization behavior. |
| packages/plugin-webmcp/tests/types.test.ts | Compile-time structural compatibility assertions vs MCP-B types. |
| packages/plugin-webmcp/tests/tsconfig.json | Adds a no-emit TS config for type-focused tests. |
| packages/plugin-webmcp/tests/runtime.test.tsx | Ensures runtime UI does not mount in unsupported environments. |
| packages/plugin-webmcp/tests/register.test.ts | Unit tests for tool registration forwarding and failure handling. |
| packages/plugin-webmcp/tests/plugin.test.ts | Unit tests for plugin config behavior (SSG-MD enabling/validation, options immutability). |
| packages/plugin-webmcp/tests/builtins.test.ts | Unit tests for built-in current-page/search/navigate tool behaviors and validation. |
| packages/plugin-webmcp/src/runtime/WebMcpRuntime.tsx | Implements runtime mounting of built-in tools with awaited navigation + search integration. |
| packages/plugin-webmcp/src/runtime/useWebMcpTool.ts | React hook for tool lifecycle registration with re-registration rules. |
| packages/plugin-webmcp/src/runtime/types.ts | Public, locally owned schema/tool types exported by the runtime. |
| packages/plugin-webmcp/src/runtime/register.ts | Low-level registration helpers around document.modelContext. |
| packages/plugin-webmcp/src/runtime/index.ts | Exposes runtime API surface (registerWebMcpTool, useWebMcpTool, types). |
| packages/plugin-webmcp/src/runtime/builtins.ts | Implements built-in tool descriptors + internal-route resolution/validation. |
| packages/plugin-webmcp/src/options.ts | Defines plugin options + normalization for runtime options. |
| packages/plugin-webmcp/src/index.ts | Plugin entry: config normalization, SSG-MD enforcement, global UI wiring. |
| packages/plugin-webmcp/src/env.d.ts | Adds rslib type references for the new package. |
| packages/plugin-webmcp/rslib.config.ts | rslib build configuration for package + runtime outputs. |
| packages/plugin-webmcp/README.md | Package README pointing to hosted documentation. |
| packages/plugin-webmcp/package.json | New package manifest, exports, scripts, and peer deps. |
| packages/plugin-webmcp/LICENSE | New package license file. |
| packages/core/src/theme/logic/useFullTextSearch.ts | Reworks local search hook to re-init on language/version changes. |
| packages/core/src/theme/components/Link/useLinkNavigate.ts | Adds optional abort signal support and improves navigation preloading lifecycle. |
| packages/core/src/node/runtimeModule/siteData/createSiteData.ts | Preserves search: false and prevents leaking searchHooks in site data. |
| packages/core/src/node/runtimeModule/siteData/createSiteData.test.ts | Unit coverage for the adjusted site data search serialization behavior. |
| packages/core/src/node/runtimeModule/pageData/rsbuildPlugin.ts | Refreshes page/search index generation to support HMR-driven updates. |
| packages/core/src/node/PluginDriver.ts | Defers defaulting llms until after plugin config hooks run. |
| packages/core/src/node/PluginDriver.test.ts | Adds tests validating the new llms defaulting order vs plugin hooks. |
| package.json | Updates root test to include recursive type tests via test:type. |
| e2e/fixtures/plugin-webmcp/webmcpTestUtils.ts | Playwright helpers for listing/executing WebMCP tools. |
| e2e/fixtures/plugin-webmcp/src/polyfill.ts | Fixture pre-entry to load the WebMCP polyfill for browsers without native support. |
| e2e/fixtures/plugin-webmcp/src/PageScopedTool.tsx | Fixture React tool registered only while a page is mounted. |
| e2e/fixtures/plugin-webmcp/src/CounterTools.tsx | Fixture tools demonstrating hook-based + imperative registration APIs. |
| e2e/fixtures/plugin-webmcp/rspress.config.ts | Fixture site configuration exercising locales, versions, search, and WebMCP plugin. |
| e2e/fixtures/plugin-webmcp/package.json | Fixture package manifest with polyfill and workspace deps. |
| e2e/fixtures/plugin-webmcp/index.test.ts | Playwright suite covering preview + dev/HMR WebMCP behavior. |
| e2e/fixtures/plugin-webmcp/doc/v2/zh/index.mdx | Fixture content for versioned + locale-specific search (v2/zh). |
| e2e/fixtures/plugin-webmcp/doc/v2/en/index.mdx | Fixture content for versioned local search (v2/en). |
| e2e/fixtures/plugin-webmcp/doc/v1/zh/index.mdx | Fixture content for locale switch search refresh (v1/zh). |
| e2e/fixtures/plugin-webmcp/doc/v1/en/index.mdx | Fixture home content used by WebMCP tool assertions (v1/en). |
| e2e/fixtures/plugin-webmcp/doc/v1/en/guide.mdx | Fixture guide page used for navigation + page-scoped tool assertions. |
| e2e/fixtures/plugin-webmcp/doc/v1/en/failure.mdx | Fixture route used to exercise failed lazy-route navigation behavior. |
| .changeset/tidy-tools-webmcp.md | Changeset for the new plugin and core updates. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7cb9b96025
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
RFC: Native WebMCP support for RspressStatus: Implemented and validated in this PR. SummaryAdd import { pluginWebMcp } from "@rspress/plugin-webmcp";
export default defineConfig({
plugins: [
pluginWebMcp({
exposedTo: ["https://agent.example"],
}),
],
});
Built-in tools
Read tools are marked read-only and untrusted-content aware. Navigation is non-read-only and also marks its documentation-derived result as untrusted.
{
"routePath": "/guide?source=agent#install",
"page": {
"title": "Guide",
"description": "Learn the fundamentals.",
"lang": "en",
"version": "v2"
},
"sections": [
{
"title": "Install",
"depth": 2,
"routePath": "/guide?source=agent#install"
}
],
"previousPage": { "title": "Introduction", "routePath": "/intro" },
"nextPage": { "title": "Configuration", "routePath": "/config" }
}The agent can then call This follows Chrome's guidance to finish UI updates before resolving a tool. Unlike full-document navigation, whose result is discarded by the native API, Rspress navigation stays within its SPA and can return post-render context. Prior art
No established Docusaurus or VitePress WebMCP adapter surfaced in the audit. Custom toolsThe runtime entry exports:
Unsupported browsers and SSR builds safely no-op. React hook exampleMount the component from a theme or import { useWebMcpTool } from "@rspress/plugin-webmcp/runtime";
type Weather = {
location: string;
temperatureC: number;
conditions: string;
};
export function WeatherTool({
loadWeather,
}: {
loadWeather(location: string): Promise<Weather>;
}) {
const { status, error } = useWebMcpTool<{ location: string }, Weather>({
name: "get_weather",
description: "Get the current weather for a location.",
inputSchema: {
type: "object",
properties: {
location: { type: "string", minLength: 1 },
},
required: ["location"],
additionalProperties: false,
},
annotations: { readOnlyHint: true },
execute: ({ location }) => loadWeather(location),
});
return <span title={error?.message}>WebMCP: {status}</span>;
}An agent host discovers and invokes that registered tool through the browser: const tools = await document.modelContext.getTools();
const weatherTool = tools.find((tool) => tool.name === "get_weather");
if (!weatherTool) {
throw new Error("get_weather is unavailable");
}
const result = await document.modelContext.executeTool(
weatherTool,
JSON.stringify({ location: "London" }),
);In an AI conversation, the same call looks like this: The browser agent normally performs discovery and invocation; the JavaScript above is the deterministic/manual equivalent for testing an individual tool. Rspress integration
ValidationCoverage includes registration, runtime input validation, schemas, annotations, site discovery, page listing, arbitrary-page retrieval, search, route rejection, navigation, custom tools, cleanup, native result normalization, SSR, production builds, and routed/imported-content HMR behavior. Final verification passed: core/plugin/fixture and website builds, unit and type tests, 15 Playwright tests, lint, macOS/Windows CI, Cloudflare deployment, and Socket checks. Non-goalsThis PR does not add prompts, resources, remote transports, server bridging, or unfinished declarative-form APIs. Its scope is the current imperative WebMCP tool API. |
|
Thanks for putting together this prototype. This is a great feature. I'll review the implementation and build on it with any changes needed to get it ready for merging. |
Rsdoctor Bundle Diff AnalysisFound 5 projects in monorepo, 5 projects with changes. 📊 Quick Summary
📋 Detailed Reports (Click to expand)📁 website_htmlPath:
📦 Download Diff Report: website_html Bundle Diff 📁 website_jsPath:
📦 Download Diff Report: website_js Bundle Diff 📁 website_mdPath:
📦 Download Diff Report: website_md Bundle Diff 📁 auto_nav_sidebar_htmlPath:
📦 Download Diff Report: auto_nav_sidebar_html Bundle Diff 📁 auto_nav_sidebar_jsPath:
📦 Download Diff Report: auto_nav_sidebar_js Bundle Diff Generated by Rsdoctor GitHub Action |
# Conflicts: # pnpm-lock.yaml
# Conflicts: # pnpm-lock.yaml
# Conflicts: # packages/plugin-algolia/src/runtime/Search.tsx # website/package.json
# Conflicts: # packages/plugin-algolia/package.json # pnpm-lock.yaml
|
@SoonIter Thanks again for taking a look. I’ve updated the branch to current |
|
Thanks for the update! After another look, the main blocker is the scope of this PR. It currently includes several core fixes and new capabilities alongside the WebMCP plugin, which makes it difficult to review as a single unit. I suggest splitting out the following prerequisite PRs:
This PR can then stay focused on the WebMCP plugin, documentation, and integration tests. The fastest path forward is to land these prerequisite PRs first. Once they are merged, this PR can be rebased and reduced to the plugin-specific changes. |
Summary
@rspress/plugin-webmcppackage using the nativedocument.modelContextbrowser APISplit PRs
To reduce the scope of this PR, its Core prerequisites were extracted into independently reviewable PRs:
After these prerequisites land, this PR can be rebased and narrowed to the WebMCP plugin, documentation, and integration coverage.
Related Issue
N/A
Verification
pnpm test:typepnpm lintpnpm buildThe repository-wide
pnpm testrun passed all type checks and 326 unit tests. One existingplugin-llmsE2E assertion remains reproducibly failing because the generatedzh/llms.txtis empty. The same failure reproduces after restoring all core files changed by this branch toHEAD, so it is unrelated to this PR.Checklist
🤖 Generated with Claude Code