Production-ready MCP server template with example tools, TypeScript, and best practices
The server provides well-named tools with clear, action-verb prefixes and comprehensive descriptions. All four tools have documented schemas with typed parameters. However, several tools lack critical information: output schemas are not formally documented, parameter descriptions sometimes lack constraint details (ranges, formats), and error handling guidance is minimal. The tools follow a sensible composition pattern (read-only, focused responsibilities), but descriptions could better explain WHEN to use each tool vs alternatives. Average tool description length is ~180 chars, which is within baseline (194 chars p50), but some parameter descriptions are thin. No tool exposes secrets, which is correct. Tools are idempotent and chain-friendly (read_file → transform_data is a natural flow).
Fetch the content of a URL and return it as text. Supports HTTP and HTTPS. Returns the response body, status code, and content type. Binary content (images, PDFs, etc.) is rejected — text and JSON only.
List files and directories. Paths are relative to the configured root. Set recursive=true to list all nested files.
Read a file from the filesystem. Paths are relative to the configured root directory. Path traversal (../) is blocked. Use encoding=base64 for binary files.
Convert data between formats: JSON, CSV, TSV, Markdown table, and plain text summary. Useful for reformatting API responses, preparing data for display, or normalising spreadsheet exports.
Output schemas are not formally documented. Tool response structures (fields, types, nullable fields) are inferred from code implementation, not declared in schema metadata. LLMs cannot reliably plan downstream tool calls without knowing what fields will be present.
Numeric constraints (ranges, min/max) are documented in descriptions but not enforced in JSON Schema. timeout_ms (100 - 30000), max_bytes (1MB - 10MB), max_depth (3 - 10), max_entries (10000) are mentioned as prose but lack minValue/maxValue in schema, forcing LLMs to parse English text to understand constraints.
Error handling lacks recovery guidance. Tools return isError=true with a code and message, but descriptions do not explain what the LLM should do next. Example: if read_file returns 'path traversal blocked', should the LLM retry with a different path, or ask the user? Are errors retryable or permanent?
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 59 | <=2025-11-25 | v2 |
| 2026-03-09 | C | 62 | - | v1 |
Parameter relationships and edge cases are undocumented. Example: list_directory's recursive flag interaction with max_depth is not explained. transform_data's 'options' object properties (pretty, include_header, delimiter) don't clarify which apply to which format conversions.
No rate limits or result caps documented. list_directory accepts max_entries=10000 but description doesn't warn about context window impact. transform_data doesn't cap input size or rows_processed, malformed or huge CSV could blow response size.