Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
This server provides two read-only file-access tools with basic but incomplete documentation. Both tools have clear, action-oriented names (read_file_content, search) and explicit schemas derived from serde/schemars JsonSchema. However, descriptions are minimal (under 100 chars each), lack context about when to use each tool, and provide no recovery guidance. Parameter descriptions are sparse. Output schemas are not formally documented. Error handling is present but returns generic messages without guidance on next steps. The tool annotations are correctly applied (read_only, idempotent), which is a positive. Overall the implementation is functional but falls short of production-grade tool design.
Tools (2)
read_file_contentread onlysource verified68/100
Read the content of a file from the specified path
searchread onlysource verified63/100
Search for keywords in text files within the specified directory
Minimal tool descriptions (both under 100 chars). 'Search for keywords in text files within the specified directory' lacks context: what file types are supported? What is the search scope (recursive?)? When should an agent use this vs read_file_content?
Output schemas not formally documented. Neither tool defines what fields are returned or their types. LLMs cannot plan downstream calls or extract the right data without knowing the response structure. read_file_content returns a String, search returns a String, but what is the format? Structured vs unstructured? Are there metadata fields?
Parameter 'file_path' description is minimal ('Path to the file to read'). Does not clarify: absolute vs relative paths? Symlinks allowed? Hidden files? Max length? These details matter for LLM input validation and error prediction.
read_file_content
Recommendations
Expand tool descriptions to 150 - 250 chars. For search: 'Search for keywords in text files (e.g., .txt, .md, .json) within a directory. Returns up to 20 matches with file paths and line numbers. Use this to discover files, then call read_file_content to view full contents. Supports literal keywords only (not regex). Search is case-sensitive and recursive through subdirectories.' For read_file_content: 'Read the full content of a text file. Accepts absolute or relative file paths. Returns file contents as plain text. If the file is binary, returns an error, use search() to locate text files first. Fails if file does not exist or lacks read permission.'
Document output schemas explicitly. For search, define: {type: 'object', properties: {matches: {type: 'array', items: {file_path: string, line_number: number, preview: string}}, total_count: number, limited: boolean}}. For read_file_content, define: {type: 'string', description: 'Full file contents as UTF-8 text.'} Include these in the server's tool metadata or JSDoc.
Add parameter constraints. file_path: 'Absolute or relative filesystem path (max 4096 chars). Symlinks allowed. Hidden files (starting with .) supported.' directory: 'Absolute or relative filesystem path (max 4096 chars). Search is recursive through all subdirectories.' keyword: 'Literal search string (max 256 chars, case-sensitive, supports spaces). Regex not supported.'
Enhance error messages with recovery guidance. When file not found: 'File not found at [path]. Verify the path is correct (absolute or relative) and the file exists. To locate files, try search() first.' When binary file: 'File [path] appears to be binary. Use search() to find and preview text files instead, or try a different file.'
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Parameter 'directory' and 'keyword' descriptions lack constraints. Is the directory search recursive? Does keyword support regex or only literal strings? Casesensitive? Max keyword length? These gaps force LLMs to guess behavior.
Error responses in read_file_content return plain strings like 'The specified path does not exist' and 'The file appears to be a binary file'. These lack recovery guidance. Per pattern, errors should state WHAT TO DO NEXT: 'File not found. Verify the path is absolute and the file exists.' or 'Binary file detected. Use search() to find text files in the directory instead.'
Search tool lacks output pagination or result limit guidance. Tantivy search on large directories could return hundreds of hits. Current implementation does not expose these controls.
No tool composition guidance. Both tools operate on the file system, but documentation does not explain when to use search vs read_file_content. An LLM might call search first to find files, then read_file_content, but there is no hint that search returns file paths in a format read_file_content accepts. Per pattern, tool outputs must contain IDs/references downstream tools need.
No bounds documented for input parameters. 'file_path' and 'directory' accept arbitrary strings. What is the max path length? Are paths on Windows (backslash) supported? Absolute paths only or relative? Without constraints, LLMs may pass invalid inputs that the tool rejects with cryptic errors.
read_file_contentsearch
Add pagination to search results. Accept optional parameters: limit (default 20, max 100) and offset (default 0). Return {matches: [...], total_count: N, offset: 0, limit: 20, has_more: boolean}. Cap results at 100 by default to avoid overwhelming LLM context.
Clarify tool composition in server instructions. Add to ServerInfo.instructions: 'Use search() to discover files matching a keyword, then call read_file_content() with a file path to view full contents.'
Document file type support explicitly. In search description, list supported file types: '.txt, .md, .rs, .py, .json, .yaml, .toml, .xml, .html, .csv, .log'. Exclude binary file types (.bin, .exe, .pdf, .jpeg, .png). Return error if directory contains no searchable text files.
Add a file_size limit check. Reject files over 10 MB in read_file_content. Return error: 'File [path] is [size] MB, exceeding the 10 MB limit. Use search() to find smaller files or split large files manually.' This prevents memory overload and clarifies constraints to LLMs.