Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
The RAG MCP Server defines 7 tools with mostly complete Zod schemas and descriptions in Japanese. However, there are critical gaps: descriptions lack English translations (limiting LLM utility in English-dominant systems), several tools lack error recovery guidance, destructive operations (delete_index, delete_document) lack confirmation or dry-run support, and output schemas are undocumented. Parameter schemas are well-formed with enums and constraints, but the server conflates multiple concerns (duplicate detection, chunking strategy, AI decision-making) into single tools rather than splitting responsibilities. Overall composition is reasonable but lacks polish for production use.
All tool descriptions are in Japanese only ('インデックス作成ツール', 'ドキュメント追加ツール'). LLMs trained primarily on English struggle with non-English descriptions and cannot infer tool intent without translation. This severely limits usability in English-speaking agent deployments.
Destructive operations (delete_index, delete_document) lack confirmation, dry-run, or undo support. Agents can accidentally delete entire indexes or documents without a recovery path. Pattern recommends confirmation_request for irreversible actions.
Output schemas are completely undocumented. All tools return { content: [{ type: 'text'; text: string }] } but LLMs cannot parse or chain results without knowing what fields to expect. The add_document tool returns complex nested structures (duplicateCheck.isDuplicate, duplicateCheck.similarDocuments, duplicateCheck.decision) that are not formally documented.
Recommendations
Provide bilingual (English + Japanese) descriptions for all tools. English description should be 50 - 200 characters, explaining WHAT the tool does, WHEN to use it, and any prerequisites. Example: 'create_index: Create a new vector index for RAG document storage. Use this before adding documents. Optionally specify embedding dimension (default: 384).'
Add a confirm_delete flow for delete_index and delete_document. One approach: add a 'dry_run' parameter (bool, optional, default=false) to preview what would be deleted. Alternatively, require a confirmation token returned by a separate list/describe call. Prevents accidental mass deletion.
Document output schemas formally. Define what every tool returns as a JSON Schema or table. Example for add_document: '{document_id: string, index_name: string, action: "added" | "rejected" | "merged", duplicate_check?: {is_duplicate: boolean, similar_count: number, ai_decision?: {action: string, reason: string, confidence: number}}}'.
Split add_document into two tools: (1) add_document(content, metadata, chunkingOptions, indexName), core insertion with basic duplicate rejection. (2) check_document_duplicates(content, indexName, options), optional separate call to preview duplicates and AI decisions before committing. This allows agents to reason about duplicates without side effects.
Improve error messages to include recovery guidance. Example: 'Failed to create index: index "my-index" already exists. Available indexes: [index1, index2]. Call delete_index("my-index") first if you want to replace it, or use a different name.' Include error classification: 'ERROR_ALREADY_EXISTS (retryable: no, fixable: yes)'.
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
add_document conflates three separate concerns: document insertion, duplicate detection with AI decision-making, and chunking strategy selection. This violates the single-responsibility principle. The tool accepts duplicateCheck.allowAIDecision and decision.reason fields that suggest AI-assisted validation, but the mechanism is opaque. Should split into add_document (core) and optionally separate check_document_duplicates (discovery) tools.
Error handling is generic. All tools catch errors and return '{{error}} に失敗しました: {{message}}' (failed to {{action}}: {{message}}). Errors do NOT classify as retryable, user-fixable, or fatal; do NOT suggest recovery actions; and do NOT return available alternatives. Example: 'インデックス作成に失敗しました: Index already exists' tells the agent nothing actionable.
add_document's chunkingOptions parameter and duplicateCheck parameter are complex nested objects but lack guidance on interdependencies. For example, what happens if extractMetadata=true but the document is binary? What if duplicateCheck.strategy='semantic' but no embedding model is configured? Undocumented dependencies cause silent misuse.
search_documents accepts optional filter parameter (object type) but does not document its schema, valid field names, or operators. LLMs cannot construct valid filters without examples or a formal schema. Should provide: 'filter: {title?: string, category?: string, author?: string, tags?: string[], created_after?: string}, all fields optional, supports partial string matching and array contains.'
No pagination support in list_indexes or search_documents. list_indexes returns all indexes as a joined string ('Index1, Index2, ...') with no structure. search_documents accepts topK parameter but provides no cursor, offset, or total_count in response. If an index contains 10,000 documents and topK=5, the agent cannot iterate through results.
Tool responses use unstructured text formatting (newline-separated key-value pairs). LLMs must parse prose to extract structured data (documentId, action, score). Should return JSON/structured objects. Example: add_document returns 'ドキュメントID: {{id}}\n実行されたアクション: {{action}}' instead of {document_id: string, action: string}.
add_documentupdate_document
Document chunkingOptions and duplicateCheck interdependencies in parameter descriptions. Add notes like: 'strategy="semantic" requires an embedding model to be configured (set RAG_EMBEDDING_MODEL env var). If not set, defaults to "metadata" strategy.' Explain constraints: 'threshold must be 0.0 - 1.0; typical values 0.8 - 0.95.'
For search_documents, document the filter schema. Example: 'filter: object with optional fields {title: string (partial match), category: string (exact match), author: string (exact match), tags: string[] (any match), created_after: ISO 8601 date string}. Example: {category: "tutorial", tags: ["python"], created_after: "2024-01-01"}.'
Add pagination to list_indexes and search_documents. list_indexes should return {indexes: [{name: string, dimension?: number}], total_count: number} instead of a joined string. search_documents should return {results: [{id, content, metadata, score}], total_count: number, has_more: boolean, next_cursor?: string}.
Return structured JSON from all tools instead of prose. Example: Instead of 'インデックス "my-index" を正常に作成しました。次元数: 384', return {success: true, index_name: "my-index", dimension: 384, message: "Index created successfully."}. LLMs can reliably extract fields and chain them to subsequent tools.
Add an 'idempotent' hint to create_index (if it's safe to retry and idempotent behavior is desired). If the index already exists and the dimensions match, return success instead of error. Document this: 'create_index is idempotent: if the index already exists with the same dimension, it returns success. If dimensions differ, it returns an error.'
For add_document, clarify the action field in responses. Document: 'action: "added" if document was inserted; "merged" if a near-duplicate was found and consolidated; "rejected" if duplicate similarity exceeded threshold and allowAIDecision=false.' This helps agents reason about whether a document was actually stored.
Add examples to parameter descriptions for complex types. Example for chunkingOptions.strategy: 'Use "markdown" for .md files, "html" for web content, "token" for code. Default: "recursive" (works for mixed content).' Examples make constraints concrete without forcing the LLM to guess.