{"record":{"id":"1c572a347524abe7","repo":"microsoft/playwright","slug":"webmcp-is-not-available-on-this-page","errorCode":null,"errorMessage":"WebMCP is not available on this page","messagePattern":"WebMCP is not available on this page","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/tools/backend/webmcp.ts","lineNumber":128,"sourceCode":"      title: tool.title || undefined,\n      description: tool.description ?? '',\n      inputSchema,\n      // The JS surface uses the `*Hint` names, the CDP WebMCP domain uses the short ones.\n      annotations: annotations ? {\n        readOnly: annotations.readOnlyHint ?? annotations.readOnly,\n        untrustedContent: annotations.untrustedContentHint ?? annotations.untrustedContent,\n        consequential: annotations.consequentialHint ?? annotations.consequential,\n      } : undefined,\n      origin: tool.origin,\n    };\n  }));\n}\n\nfunction callToolInPage(params: { name: string, inputJson: string }) {\n  const modelContext = (document as DocumentWithModelContext).modelContext\n      ?? (navigator as NavigatorWithModelContext).modelContext;\n  if (!modelContext)\n    throw new Error('WebMCP is not available on this page');\n  const stringify = (result: unknown) => result === undefined ? 'null' : JSON.stringify(result);\n  if (modelContext.executeTool) {\n    // Chromium: executeTool(registeredTool, inputJsonString) resolves to a JSON string.\n    return Promise.resolve(modelContext.getTools!()).then(tools => {\n      const tool = tools.filter(t => !('window' in t) || t.window === window).find(t => t.name === params.name);\n      if (!tool)\n        throw new Error(`WebMCP tool \"${params.name}\" is not registered in this frame`);\n      return modelContext.executeTool!(tool, params.inputJson);\n    }).then(result => typeof result === 'string' ? result : stringify(result));\n  }\n  // Firefox: invokeTool(name, inputObject) resolves to the value itself.\n  return Promise.resolve(modelContext.invokeTool!(params.name, JSON.parse(params.inputJson))).then(stringify);\n}\n\nconst kTimedOut = Symbol('timedOut');\n\nasync function withTimeout<T>(promise: Promise<T>, timeout: number): Promise<T | typeof kTimedOut> {\n  let timer: NodeJS.Timeout | undefined;","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/microsoft/playwright/blob/f1d33b5029be8bbc1095fe88e559117fa3a6243b/packages/playwright-core/src/tools/backend/webmcp.ts#L110-L146","documentation":"This error is thrown inside an injected page-side function: neither document.modelContext nor navigator.modelContext is present, meaning the page does not expose the WebMCP model-context API. Only pages that registered a WebMCP ModelContext can have tools invoked in them.","triggerScenarios":"Invoking a WebMCP tool call (via the webmcp backend callToolInPage) against a frame whose document/navigator lack a modelContext — e.g. an about:blank page, a non-MCP-enabled site, or a browser build without WebMCP support.","commonSituations":"Pointing the WebMCP CLI/tooling at the wrong tab or frame; testing on a page before its WebMCP polyfill/script has loaded; running against an older browser that has not shipped the modelContext API.","solutions":["Navigate to a page that actually registers a WebMCP modelContext before calling tools.","Verify document.modelContext or navigator.modelContext exists in the target frame (evaluate a probe expression).","Ensure the browser build supports WebMCP and that the page's MCP registration script has finished loading."],"exampleFix":"// before\nawait client.callTool('webmcp-call', { params: { tool: 'get_weather', inputJson: '{}' } }); // page has no modelContext\n// after\nawait page.goto('https://example.com/webmcp-enabled');\nawait page.waitForFunction(() => 'modelContext' in navigator || 'modelContext' in document);\nawait client.callTool('webmcp-call', { params: { tool: 'get_weather', inputJson: '{}' } });","handlingStrategy":"validation","validationCode":"const hasWebMcp = await page.evaluate(() => 'modelContext' in navigator || 'modelContext' in document);\nif (!hasWebMcp) throw new Error('This page does not expose WebMCP modelContext');","typeGuard":"function pageHasModelContext(doc: Document): doc is Document & { modelContext: object } {\n  return 'modelContext' in doc || 'modelContext' in navigator;\n}","tryCatchPattern":"try {\n  return await webmcpCall(frame, tool, inputJson);\n} catch (e) {\n  if (e.message.includes('WebMCP is not available')) throw new Error(`Frame ${frame.url()} has no WebMCP modelContext`);\n  throw e;\n}","preventionTips":["Probe for modelContext before dispatching tool calls.","Verify the page's MCP registration script has loaded (wait for the global).","Confirm the browser build supports WebMCP."],"tags":["webmcp","browser","feature-detection"],"backgroundTag":"feature-not-enabled","analyzedSha":"f1d33b5029be8bbc1095fe88e559117fa3a6243b","analyzedAt":"2026-09-15T07:37:15.003Z","contentChangedAt":"2026-09-15T07:37:15.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}