NestJS-based AI-powered research and knowledge management platform with Model Context Protocol (MCP) integration for tool execution
The server defines 6 tools with basic schemas and descriptions visible in src/mcp/mcp-tools.registry.ts. All tools have names starting with action verbs (search, get, add, create, list, get), descriptions, and parameter definitions. However, the implementation has significant gaps: parameter types are declared but lack constraints (enums, ranges, patterns); descriptions are generic and lack context about when to use each tool or what happens on error; output schemas are entirely undocumented; and there is no evidence of error handling guidance or recovery steps. The tools are reasonably well-composed (searchDocs, getDocument, addNote, createTask, listTasks, getUserStats cover distinct concerns), but lack the depth needed for reliable LLM reasoning. Average tool score: 58.
Add a note to a document or create a standalone note
Create a new task
Get a specific document by ID
Get user statistics (documents, notes, tasks)
List tasks with optional filters
Search for documents by query and tags
Output schemas completely undocumented. No tool declares what fields it returns, their types, or whether results are paginated. LLMs cannot plan multi-step chains or extract the right data for downstream calls.
Enum values declared in prose descriptions rather than as formal enum constraints. E.g. 'priority' parameter describes 'LOW, MEDIUM, HIGH, URGENT' in text, should be a JSON Schema enum array. This prevents LLM tools from validating options and increases hallucinated invalid values.
Descriptions are generic and lack LLM reasoning context. Most descriptions (18 - 58 chars) are too short to explain when to call the tool instead of similar ones, what happens on error, or what gets returned. Example: 'Get a specific document by ID' doesn't say whether the response is full text or metadata-only.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 62 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 34 | - | v1 |
No pagination guidance for list operations. searchDocs and listTasks accept a 'limit' parameter but don't document max limits, default values, or whether a 'next_cursor'/'offset' is provided in responses. Large result sets could blow the context window.
No error handling guidance. None of the tools document what to do if the operation fails (e.g., 'document not found', 'invalid priority', 'task creation failed'). Errors should guide the LLM toward recovery (retry, call search first, validate input).
No idempotency or mutation guidance. Tools like addNote and createTask modify state, but descriptions don't clarify whether repeated calls with the same input produce the same result or duplicate entries. This is critical for agent retry logic.
Numeric parameter ranges undefined. 'limit' in searchDocs and listTasks have no min/max guidance. An LLM could pass limit=1000000, causing performance issues. Should specify e.g. 'limit: 1 - 100 (default 20)'.
Field naming inconsistency: 'docId' uses camelCase while other params use snake_case-style descriptions. If downstream APIs expect 'doc_id', the response field names must match, or LLMs will fail to chain tools. Not visible in provided code whether responses follow consistent naming.