Skip to content

Commit 0633910

Browse files
committed
Simplify WebMCP integration: clientModules instead of a plugin
The dedicated plugin only existed to load a client module and smuggle the Algolia credentials to it through an injected window global. Docusaurus already has a top-level clientModules option for the former, and the client module can read themeConfig directly via @generated/docusaurus.config for the latter. One file and one config line now; no window global, no injected script tag.
1 parent 0dac6e9 commit 0633910

3 files changed

Lines changed: 15 additions & 55 deletions

File tree

docusaurus.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ const config: Config = {
3636
async: true,
3737
},
3838
],
39+
// Exposes a WebMCP `search_docs` tool to in-browser AI agents (#2556).
40+
clientModules: ['./src/clientModules/webmcp.ts'],
3941
plugins: [
4042
"docusaurus-plugin-sass",
4143
[
@@ -83,7 +85,6 @@ const config: Config = {
8385
],
8486
'./src/plugins/route-export/index.ts',
8587
'./src/plugins/analytics-module/index.ts',
86-
'./src/plugins/webmcp/index.ts',
8788
'docusaurus-markdown-source-plugin',
8889
[
8990
"docusaurus-plugin-llms",
Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,22 @@
33
// per-page browser tooling — client-side JS, not a network MCP server. The
44
// API only exists behind an experimental flag (Chrome EPP / W3C draft), so in
55
// every other browser this module must be a silent no-op.
6+
//
7+
// Loaded via the top-level `clientModules` option in docusaurus.config.ts.
8+
9+
import siteConfig from '@generated/docusaurus.config';
610

711
type AlgoliaCredentials = {
812
appId: string;
913
apiKey: string;
1014
indexName: string;
1115
};
1216

13-
type WebMcpWindow = Window & {
14-
// Injected by the plugin (src/plugins/webmcp/index.ts) from themeConfig.
15-
__webMcpAlgolia?: AlgoliaCredentials;
16-
};
17+
// The same search-only Algolia credentials every DocSearch request already
18+
// ships to the browser — nothing here is secret.
19+
const algolia = siteConfig.themeConfig.algolia as
20+
| AlgoliaCredentials
21+
| undefined;
1722

1823
type AlgoliaHit = {
1924
hierarchy?: Record<string, string | null>;
@@ -61,7 +66,7 @@ function stripMarkup(value: string): string {
6166

6267
async function searchDocs(
6368
query: string,
64-
algolia: AlgoliaCredentials,
69+
credentials: AlgoliaCredentials,
6570
): Promise<string> {
6671
// Same contextual facets DocSearch uses on this site: English records from
6772
// the docs plugin plus untagged (default) pages, excluding blog-index noise.
@@ -81,13 +86,13 @@ async function searchDocs(
8186
});
8287

8388
const response = await fetch(
84-
`https://${algolia.appId}-dsn.algolia.net/1/indexes/${encodeURIComponent(algolia.indexName)}/query`,
89+
`https://${credentials.appId}-dsn.algolia.net/1/indexes/${encodeURIComponent(credentials.indexName)}/query`,
8590
{
8691
method: 'POST',
8792
headers: {
8893
'Content-Type': 'application/json',
89-
'X-Algolia-Application-Id': algolia.appId,
90-
'X-Algolia-API-Key': algolia.apiKey,
94+
'X-Algolia-Application-Id': credentials.appId,
95+
'X-Algolia-API-Key': credentials.apiKey,
9196
},
9297
body: JSON.stringify({ params: params.toString() }),
9398
},
@@ -138,7 +143,6 @@ const searchDocsTool: ModelContextTool = {
138143
if (!query) {
139144
return textResult('Error: `query` must be a non-empty string.');
140145
}
141-
const algolia = (window as WebMcpWindow).__webMcpAlgolia;
142146
if (!algolia) {
143147
return textResult('Error: search is not configured on this page.');
144148
}

src/plugins/webmcp/index.ts

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)