diff --git a/CLAUDE.md b/CLAUDE.md index c4a8382..6c30003 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -102,7 +102,7 @@ The same rule governs the **tool definitions**, which every client loads on ever `pnpm run eval` (`scripts/eval.mjs`, wired into CI) is the gate for response-shape changes: it drives the built server over stdio against `tests/eval/fixtures/` and checks answerability, no duplication, a token budget and golden files. Once per run it also budgets the tool definitions — see [Shaping Tool Definitions](DEVELOPING.md#️-shaping-tool-definitions) — and regenerates both token cost tables in `README.md`, between the `` and `` markers, so any change that moves a published figure fails until the README is regenerated with it. The jest suite cannot do this — `moduleNameMapper` swaps `@toon-format/toon` for a JSON stand-in, so it never sees the real encoding. Re-record goldens with `pnpm run build && pnpm run eval:update` and read the diff. -`outputSchema`/`structuredContent` are deliberately not implemented — the MCP spec asks for the payload to also be serialized into a text block, which would send it twice. Tracked separately. +`outputSchema`/`structuredContent` are not implemented yet, and the reason is cost, not the spec: serializing the payload into a text block beside `structuredContent` is a `SHOULD` for old clients, and the spec's own example pairs a schema with an unrelated text block, so a lean TOON block stays legal. What is unresolved is that `outputSchema` is charged in `tools/list` on every turn, and that a client is free to read `structuredContent` instead of our text block, which would spend the shaping saving. Measure both before implementing — see #66. Anonymous execution (4) accepts multi-line strings containing Apex, saves the resulting debug log to a local file (default: `.apex-log-mcp/` in the project root), and returns a summary with the file path. The `outputDir` parameter overrides the default save location. It supports an optional `debugLevel` parameter to configure trace flag log levels per category or set all categories at once. The response includes the org alias alongside the username when available, plus the detected org type. `apexlog_execute_anonymous` is **always registered** so agents can discover it; authorization happens per call in `src/policy/orgExecutionPolicy.ts`. `src/salesforce/orgClassification.ts` identifies the target org (`sandbox`, `scratch`, `trial`, `developer`, `production`, or `unknown` when it cannot be queried), caching one `Organization` query per org id for the server's lifetime. Non-production orgs run silently. Production and `unknown` orgs need either the `--allow-production-orgs` flag or a per-call user confirmation via MCP elicitation; without either, the call is refused with an `isError` result whose text explains both routes. Authorization runs before any `DebugLevel` or `TraceFlag` record is created, so refused calls leave the org untouched. `--no-apex-execution` refuses every call before contacting Salesforce and marks the tool `[DISABLED on this server]` in its description. The 1.x `--allowed-orgs` flag is accepted but ignored, with a stderr deprecation warning.