microsoft/playwright-mcp · error · Error

Unknown tool capabilities: ${unknownCapabilities.join(', ')}

Error message

Unknown tool capabilities: ${unknownCapabilities.join(', ')}. Please update the capabilities map in ${path.basename(__filename)}.

What it means

This error is thrown by utils/update-readme.js, the maintenance script that regenerates the README's tool tables from the manifest produced by the MCP server. Every browser tool declares a `capability` field, and the script keeps a hardcoded `capabilities` map (e.g. 'core', 'testing') that must enumerate every possible capability value. When a tool reports a capability not present in that map, the script aborts because it would otherwise silently drop that tool from the generated README.

Source

Thrown at update-readme.js:43

const capabilities = /** @type {Record<string, string>} */ ({
  'core-navigation': 'Core automation',
  'core': 'Core automation',
  'core-tabs': 'Tab management',
  'core-input': 'Core automation',
  'core-install': 'Browser installation',
  'config': 'Configuration',
  'network': 'Network',
  'storage': 'Storage',
  'devtools': 'DevTools',
  'vision': 'Coordinate-based',
  'pdf': 'PDF generation',
  'testing': 'Test assertions',
});

const knownCapabilities = new Set(Object.keys(capabilities));
const unknownCapabilities = [...new Set(tools.browserTools.map(tool => tool.capability))].filter(cap => !knownCapabilities.has(cap));
if (unknownCapabilities.length)
  throw new Error(`Unknown tool capabilities: ${unknownCapabilities.join(', ')}. Please update the capabilities map in ${path.basename(__filename)}.`);

/** @type {Record<string, any[]>} */
const toolsByCapability = {};
for (const capability of Object.keys(capabilities)) {
  const title = capabilityTitle(capability);
  let filteredTools = tools.browserTools.filter(tool => tool.capability === capability && !tool.skillOnly);
  filteredTools = (toolsByCapability[title] || []).concat(filteredTools);
  toolsByCapability[title] = filteredTools;
}
for (const [, tools] of Object.entries(toolsByCapability))
  tools.sort((a, b) => a.schema.name.localeCompare(b.schema.name));

/**
 * @param {string} capability
 * @returns {string}
 */
function capabilityTitle(capability) {
  const title = capabilities[capability];

View on GitHub (pinned to 16cf228d7b)

Solutions

  1. Add the new capability as a key in the `capabilities` map in utils/update-readme.js with a short description, and add a matching entry via `capabilityTitle()` if one is required.
  2. Fix the tool definition: check the `capability` value on the tool named in the manifest and correct typos or casing so it matches an existing key such as 'core' or 'testing'.
  3. If a capability was renamed intentionally, update both the tools and the capabilities map in the same commit, then rerun `node utils/update-readme.js` to confirm it passes.

Example fix

// before (utils/update-readme.js)
const capabilities = {
  'core': 'Core tools',
  'testing': 'Test assertions',
};

// after — new tool declares capability: 'network'
const capabilities = {
  'core': 'Core tools',
  'testing': 'Test assertions',
  'network': 'Network interception',
};
Defensive patterns

Strategy: validation

Validate before calling

// Before running the generator, verify every tool capability is known:
import { createServer } from '../src/index.js';
import fs from 'fs';

const script = fs.readFileSync('utils/update-readme.js', 'utf-8');
const known = [...script.matchAll(/^\s*'([a-z-]+)':/gm)].map(m => m[1]);
const { tools } = await createServer(/* minimal config */).listTools();
const unknown = [...new Set(tools.map(t => t.capability))].filter(c => !known.includes(c));
if (unknown.length) {
  console.error('Update capabilities map first:', unknown.join(', '));
  process.exit(1);
}

Try / catch

try {
  execSync('node utils/update-readme.js', { stdio: 'inherit' });
} catch (e) {
  if (/Unknown tool capabilities/.test(e.message ?? String(e))) {
    // parse the capability list, add them to the capabilities map, rerun
    throw new Error('README generator out of date: add missing capabilities to update-readme.js');
  }
  throw e;
}

Prevention

When it happens

Trigger: Running `node utils/update-readme.js` (or `npm run update-readme`) after adding a new tool to src/tools/*.ts whose `capability` string (e.g. capability: 'network') is not a key in the `capabilities` map at the top of update-readme.js. It also fires if an existing capability is renamed in the tool definition without updating the script, or if a tool's capability has a typo/case mismatch ('Core' vs 'core').

Common situations: Contributing a new browser tool or intercept tool to playwright-mcp; refactoring capability groupings (e.g. splitting 'core' into finer categories); copy-pasting a tool file and editing its capability field. Typically hit in CI or locally right after `npm run build` when regenerating docs.

Related errors


AI-assisted analysis of microsoft/playwright-mcp@16cf228d7b (2026-08-27). Data as JSON: /api/errors/ff61f152fb90c771. Report an issue: GitHub.