OCR (Optical Character Recognition) server for extracting text from images using Tesseract and ONNX models
This MCP server has significant definition quality gaps. While the tool names follow a verb-noun pattern (ocr_request, ocr_close), the descriptions are adequate but not optimized for LLM selection. More critically, the parameter schemas contain a structural issue: they use 'optional': true as a non-standard JSON Schema annotation rather than omitting fields from 'required'. Output schemas are documented but overly complex with a deeply nested oneOf structure. The server operates on a non-standard command/response protocol that couples tool invocation to asynchronous UI events, which is architecturally problematic for agent composition. Error handling guidance is minimal, no recovery paths or retry classification provided. The tools handle interactive popup windows, which creates inherent stateful dependencies that conflict with stateless MCP design principles.
Close the OCR window programmatically after receiving result or error
Perform OCR on images using the OCR extension. This is an ASYNCHRONOUS operation that opens a popup window. The agent MUST keep the connection open and wait for user interaction or OCR completion.
Non-standard JSON Schema: Parameters use 'optional': true instead of excluding from 'required' array. This violates JSON Schema conventions and may confuse strict schema validators. Example: 'image' field has 'optional': true but is not in the 'required' array, the field itself should be omitted from 'properties' if truly optional.
Descriptions lack LLM-optimized guidance. 'ocr_request' description (218 chars) focuses on technical asynchrony ('This is an ASYNCHRONOUS operation that opens a popup window') rather than WHEN to use it or recovery steps. 'ocr_close' description (94 chars) is below baseline (194 chars) and provides no context about side effects or when the user should call it.
Stateful asynchronous protocol creates agent composition hazards. The tool description states 'The agent MUST keep the connection open and wait for user interaction or OCR completion.' This violates the stateless request model and makes it impossible for agents to parallelize or compose multiple OCR requests. The output schema includes 'report', 'result', 'disconnected' messages, essentially a custom state machine layered on top of MCP.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 50 | 2025-06-18+ | v2 |
No error recovery guidance. Error responses in outputSchema contain only an 'error' string (e.g., 'Human-readable error message describing what went wrong'). Per the rubric, errors must answer: 'What should the LLM do next?' Is this retryable? Should it ask the user? Provide actionable remediation, not just a description.
Parameter descriptions contain prescriptive but incomplete guidance. Example: 'selector' parameter says 'Do NOT use with proceed: true' but the schema has no way to enforce this constraint. LLMs cannot read constraint prose, they will pass both parameters and expect the tool to accept them. Use explicit JSON Schema constraints (e.g., if/then rules) or split into separate tools.
Output schema for ocr_request is overly complex (oneOf with 4 branches, deeply nested properties). While documented, the structure forces agents to parse multiple response formats. A single consistent response format would be clearer: { success: bool, data?: OCRResult, status: string, error?: string }.
Missing parameter descriptions for ocr_close. The 'cmd' parameter has a description ('Must be "close"'), but the inputSchema object itself lacks documentation on what ocr_close does beyond the tool-level description. Agents need per-parameter guidance.
Tool naming ambiguity: 'ocr_request' conflates two operations: (1) open an OCR window, (2) wait for OCR result. A more precise pair would be 'open_ocr_window' + 'get_ocr_result', or better yet, a single 'perform_ocr' that handles the full lifecycle internally without exposing async state.