A local MCP server that breaks on demand. Test your client against auth failures, disappearing tools, flaky responses, and token expiry.
This server demonstrates solid definition quality with consistent schema structures, detailed descriptions, and proper naming conventions across 14 tools. Tool names follow verb-first patterns (echo, add, get-time, list-contacts, etc.), descriptions are substantive and exceed the 20-char minimum, and input schemas use Zod validation with type declarations and parameter descriptions. However, there are notable gaps: (1) Output schemas are NOT explicitly documented, the code shows tools return textResult() but the schema structure is not formalized in tool registration; (2) No pagination support despite contact list tools that could return unbounded results; (3) Tool descriptions lack dependency hints and don't clearly distinguish between similar tools (two 'echo' and two 'add' variants); (4) Error handling guidance is minimal, no actionable recovery messages; (5) No tool annotations (readOnlyHint, destructiveHint) despite clear WRITE and DESTRUCTIVE risk classifications available. The contact CRUD tools (create-contact, update-contact, delete-contact) have good per-field descriptions but lack confirmation/dry-run patterns for irreversible operations. Overall, the foundation is strong but production readiness gaps prevent a higher grade.
Returns the sum of two numbers.
Returns the sum of an array of numbers. An empty array returns 0.
Creates a new contact and returns the created record with its auto-generated ID and timestamp. Requires name and email. Company and notes are optional.
Deletes a contact by ID. Returns a success message if the contact was deleted, or an error message if the ID did not exist.
Echoes back the provided message verbatim as plain text.
Echoes back the provided message in the chosen format: 'plain' returns it unchanged, 'json' wraps it as {"echo": "..."}, 'uppercase' converts to uppercase.
Returns a single contact by exact email address as a JSON object. The match is exact (case-sensitive). Returns an error message if no contact with the given email exists.
Output schemas not documented in tool definitions. Tools return structured text responses (JSON for contacts, ISO 8601 for time, etc.) but the response format is not formally declared in the ToolDef interface or MCP registration. LLMs cannot plan downstream operations without knowing the exact structure.
No pagination for list-contacts. Tool can return unbounded contact arrays, risking context window exhaustion. No limit, offset, or page parameters documented; no total_count or next_cursor in response.
Two tools named 'echo' and two named 'add' without clear version distinction visible at tool selection time. LLMs must disambiguate on description alone. Descriptions do not explicitly recommend WHEN to choose v1 vs v2 (e.g., 'Use v2 if format conversion needed, v1 for plain echo').
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-21 | B | 70 | <=2025-11-25 | v2 |
| 2026-03-09 | B | 70 | - | v1 |
Returns a single contact by its numeric ID as a JSON object. Returns an error message if no contact with the given ID exists.
Returns the current server time as an ISO 8601 string (e.g. '2025-01-30T14:30:00.000Z').
Returns all contacts from the database as a JSON array, ordered by ID. Each contact has id, name, email, company, notes, and created_at fields. Returns an empty array if no contacts exist.
Generates a cryptographically non-secure pseudo-random integer within the specified inclusive range [min, max]. Both bounds must be integers. The result is uniformly distributed across all integers from min to max, inclusive of both endpoints. For example, with min=1 and max=6, this simulates a standard six-sided die roll. The random number is generated using Math.random() and Math.floor(), which is suitable for testing purposes but should not be used for security-sensitive applications. This tool is useful for testing MCP tool calls with integer-typed parameters and for verifying that the client correctly validates integer constraints. If min equals max, the result is always that value. If min is greater than max, the behavior is undefined (may return values outside the expected range).
Reverses the characters in the provided input string and returns the result. This tool performs a simple Unicode-aware string reversal by splitting the input into an array of characters, reversing their order, and joining them back into a string. For example, 'hello' becomes 'olleh' and 'abcdef' becomes 'fedcba'. This tool is useful for testing MCP tool invocations where the output is deterministically derived from the input, making it easy to verify correct behavior in automated tests. Unlike echo, the output is always different from the input (unless the string is a palindrome), which makes it straightforward to confirm that the tool actually executed rather than the client returning a cached or passthrough result. Empty strings return an empty string. Multi-byte Unicode characters such as emoji are handled correctly via Array.from() which splits on code points rather than UTF-16 code units.
Searches contacts by a query string. Case-insensitive substring match against name, email, company, and notes fields. Returns a JSON array of matching contacts, or an empty array if none match.
Updates a single field on a contact. Specify the contact ID, which field to change (name, email, company, or notes), and the new value. Returns the full updated contact. To update multiple fields, call this tool once per field.
No tool annotations despite clear risk classifications (WRITE, DESTRUCTIVE). create-contact, update-contact, and delete-contact are marked with WRITE/DESTRUCTIVE risk but tools lack readOnlyHint/destructiveHint metadata that modern MCP clients use for safety warnings.
Irreversible operations (delete-contact, update-contact) do not offer dry-run, confirmation, or multi-round-trip (MRT) confirmation pattern. An agent could delete a contact without a chance to verify the ID first.
Error handling descriptions are generic or absent. Example: 'Returns an error message if no contact with the given ID exists.' This provides no guidance for the LLM on recovery action (e.g., 'Try search-contacts() first' or 'Caller can retry if transient').
Tool descriptions for list-contacts and search-contacts do not explain pagination, result limits, or expected JSON structure. 'Returns all contacts... as a JSON array' lacks detail on fields per contact (id, name, email, company, notes, created_at).