The agent's data reader: any JSON/JSONL blob becomes its shape and the slice you asked for, not the whole thing.
Prism demonstrates strong naming (verb_noun pattern: prism_shape, prism_read, prism_find, prism_diff) and comprehensive descriptions (150-300 chars each, well above the 34-char p10 baseline). All four tools have complete input schemas with proper JSON Schema types and descriptions. Parameters are well-constrained (enums for format, integer bounds for depth/keys/tokens). However, output schemas are not explicitly documented in the tool definitions, the code shows shape/read/find/diff functions exist but their return structures are not declared in inputSchema or a separate outputSchema field. Error handling is present in the code (PrismError class, path-not-found reporting) but not surfaced in tool descriptions. No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite all four being read-only operations.
Compare TWO blobs — JSON, JSONL, CSV, or TSV — and get back the PATHS that changed — added, removed, or a scalar that moved — with a summary count of each. It walks the structure (objects by key, arrays by index; a value that changed type counts as changed), NOT a line diff of the pretty-printed text, so a reordered or reformatted-but-equal document reads as identical. Node- and hit-bounded. Use it to see what differs between two API responses, two configs, or a before and after.
Find where a key or value lives inside a JSON, JSONL, CSV, or TSV blob — returns the PATHS (the input to prism_read), breadth-first so the shallowest matches come first. Matches key names by substring and scalar values (strings by substring, numbers/bools exactly, so "1" does not match "1000"). Node- and hit-bounded: on a huge document it stops and tells you the result may be partial.
Read the value at a PATH inside a JSON, JSONL, CSV, or TSV blob, token-budgeted. Paths look like data.users[0].email or items[*].id ([*] maps over an array); a half-open slice items[0:10] (or [:10] / [100:]) takes just a window of a big array — bounds clamp, so [0:10] on a short array is fine. An index or slice bound may be NEGATIVE to count from the end: logs[-1] is the last element, logs[-20:] the last twenty. If the value fits the budget you get it verbatim; if it is too big you get its shape plus the honest size, so you can narrow the path — a slice or an index — and read again, never a silent truncation. A wrong path is reported (where it fell off, and the type actually there), not thrown.
Get the SHAPE of a JSON, JSONL, CSV, or TSV blob — keys→types, array lengths, nesting — instead of the whole thing. The skeleton of a 500 KB API response is a few hundred tokens. int vs float are distinguished, a key not present in every array element is marked optional, and deep/wide structures are depth- and key-bounded so the shape stays small. Start here, then prism_read the paths you care about.
Output schemas not documented. Tool definitions declare inputSchema but omit return type documentation. LLMs cannot plan downstream operations without knowing what fields to expect (e.g., does prism_shape return {type, length, fields} or {shape, size, depth}?).
Tool annotations missing. All four tools are read-only (no side effects, safe to retry), but readOnlyHint is not set in tool definitions. This forces LLMs to infer safety from descriptions rather than machine-readable hints.
Error recovery guidance not in tool descriptions. Code handles PrismError (path-not-found, oversized input, parse failures) but descriptions do not explain what to do if a path is invalid or data exceeds max_bytes. LLMs need explicit recovery hints.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 69 | 2026-07-28+ | v2 |
prism_diff parameter naming inconsistency. Uses 'left' and 'right' (positional, unclear semantics) instead of 'before' and 'after' or 'old' and 'new'. Description says 'first (before)' and 'second (after)' but parameter names do not reflect this.
No pagination or result-limiting guidance for prism_find and prism_diff. Both accept 'k' (max hits) but descriptions do not explain what happens when results exceed k or how to iterate. Large datasets could return truncated results silently.