@withpica/mcp-server
Version:
MCP Server for withPICA — enables AI assistants to interact with your withPICA music catalog
44 lines • 2.43 kB
TypeScript
/**
* Typed tool-error envelope for executors that catch internally.
*
* An executor that swallows a throw and returns
* `formatAsText({ error: "Failed to …" })` produces a result with no
* `isError`, so the dispatcher and the client both read it as a SUCCESS whose
* payload happens to contain the word "error", and the prose sentence sits in
* the field a machine reads as a code.
*
* `typedError` gives an internal catch the `{ error, message }` + `isError`
* shape the dispatcher's own catch emits via `formatError`
* (mcp-server-shared/mcp-utils/src/errors.ts).
*
* ⚠️ What the `error` code actually buys, and only this:
* `ToolRegistry.execute` (`./index.ts`) passes an `isError` RESULT to
* `extractErrorAttribution` (`./index.ts`, exported), which reads
* `envelope.error_code ?? envelope.error` off the first text block and writes
* it to `mcp_audit_log.error_code`. Without a JSON envelope that column is
* NULL and the ops_issues pipeline, which groups on the code, cannot see the
* failure. Pinned by `src/__tests__/tools/extract-error-attribution.test.ts`
* ("accepts the formatError shape (`error` + `message` keys)").
*
* ⚠️ It does NOT reach `getRecoveryHint`. That has exactly one call site —
* `ToolRegistry.execute`'s `catch` — so hints attach to THROWN errors only. A
* returned `isError` result, however well typed, gets no `suggestion` or
* `next_tool`. Making a hint fire means letting the error throw, not naming
* its code here.
*
* Enforced by the `typed error envelopes` describe blocks in
* `src/__tests__/tools/{notifications,telegram,credits,import}.test.ts` — they
* assert `isError === true` and a SCREAMING_SNAKE `error` for every executor
* that uses this helper. Nothing stops a NEW executor from hand-rolling the
* old shape; those tests cover the executors listed, not the whole surface.
*/
import type { ToolResult } from "./index.js";
/**
* @param code SCREAMING_SNAKE machine code — no spaces.
* @param message Human-readable cause, safe to show the user.
* @param extra Optional additional body fields (e.g. `sent: false`). Spread
* FIRST so it can never overwrite `error` or `message` — the
* two fields `extractErrorAttribution` reads.
*/
export declare function typedError(code: string, message: string, extra?: Record<string, unknown>): ToolResult;
//# sourceMappingURL=error-envelope.d.ts.map