function errorTaxonomyFigure(host) { ensureStyles(); var protocolCodes = [ { code: '-32601', name: 'Method not found' }, { code: '-32602', name: 'Invalid params (unknown tool)' }, { code: '-32020', name: 'HeaderMismatch' }, { code: '-32021', name: 'MissingRequiredClientCapability' }, { code: '-32022', name: 'UnsupportedProtocolVersion' } ]; var rowH = 32; var gap = 6; var startY = 40; var left = ''; var i; var y; for (i = 0; i < protocolCodes.length; i++) { y = startY + i * (rowH + gap); left += ''; left += '' + protocolCodes[i].code + ''; left += '' + protocolCodes[i].name + ''; } var shell = document.createElement('div'); shell.className = 'mf-shell'; shell.innerHTML = [ '
Two Ways for a Request to Fail a protocol error travels as a JSON-RPC error object; a tool problem travels as a normal result with isError true
', '
', '', '', 'two channels answer a failed request; only one of them is content the model reads', 'protocol error -> JSON-RPC error', 'tool problem -> isError: true', '', left, '', 'isError: true', 'API failures', 'input validation errors', 'business logic refusals', 'expired server-minted handles', '', 'content the model reads,', 'then retries with a fix', '', 'forbidden: -32000 to -32019 legacy, -32002 and -32042 retired', 'a 2026-07-28 server must refuse to put any of these on the wire', '', '
', '
A protocol error is a JSON-RPC error object the client handles itself. A tool problem is a normal result with isError true, content the model can read and act on. Both are legitimate channels; a code from the forbidden band below is never legitimate, whichever channel would carry it.
' ].join(''); host.appendChild(shell); } // register as: mcpa-18-error-taxonomy