Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
This Rust/rmcp MCP server implements 18 Coda API integration tools with solid naming conventions and comprehensive parameter schemas. All tools start with action verbs (list_, get_, create_, delete_, search_, add_, update_). Descriptions are present and clear (90-250 chars, within the 10-1024 target). Input schemas are well-defined with proper JSON Schema types and parameter descriptions. However, output schemas are not documented, tools return CallToolResult with text content, but the structure of that content (JSON fields, arrays, pagination info) is not formally specified. Error handling is basic (McpError wrapping with generic messages). No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk profiles (READ_ONLY, WRITE, DESTRUCTIVE). Parameter descriptions generally meet the 'why/when' bar but could be more explicit about constraints and downstream usage. The server follows tool-chaining principles (e.g., list_docs returns doc IDs that get_doc/delete_doc consume), but no explicit documentation of these chains.
Tools (18)
add_rowwriteauthsource verified82/100
Add a new row to a table with specified cell values.
create_docwriteauthsource verified85/100
Create a new Coda document. Optionally specify a folder, source document (template), or timezone.
delete_docdestructiveauthsource verified82/100
Delete a Coda document. This action is permanent and cannot be undone.
delete_rowdestructiveauthsource verified82/100
Delete a row from a table.
get_docread onlyauthsource verified85/100
Get detailed information about a specific Coda document.
Output schemas not documented. Tools return CallToolResult::success() with text content, but the structure of returned JSON fields, pagination, and downstream chaining info is not formally specified in tool descriptions or documentation.
Tool annotations missing. No readOnlyHint, destructiveHint, or idempotentHint are present in tool definitions, despite clear risk profiles (READ_ONLY, WRITE, DESTRUCTIVE marked in source). Agents cannot infer which tools are safe to retry or call multiple times without side effects.
Document output schemas for every tool. Add a 'Returns' or 'Output' section to each tool description specifying the structure of returned JSON: field names, types, whether results are paginated, what IDs/references are included for chaining. Example: 'list_docs returns {items: [{id, name, ...}], totalCount: int, hasMore: bool}'.
Add tool annotations via rmcp. Update tool registration to include readOnlyHint=true for all list_*/get_* tools, destructiveHint=true for delete_* tools, and idempotentHint=true for read-only operations. This enables agents to reason about retry safety and side effects.
Enhance error handling with recovery guidance. Catch API errors (auth, not found, rate limit, invalid input, network) and return specific error messages: 'Doc not found (doc_id=xyz). Valid doc IDs can be retrieved via list_docs().' or 'Rate limited. Retry in 60 seconds.' or 'Invalid query syntax: expected Coda formula, got: ...'. Categorize errors as retryable vs. user-fixable.
Implement confirmation for destructive operations. Add an optional 'confirm' boolean parameter to delete_doc and delete_row. If false (default), return a success response that includes the resource details and asks for confirmation. If true, proceed with deletion. Example: 'Confirm: Delete document "My Report" (doc_id=abc123)? Call delete_doc() again with confirm=true to proceed.'
Declare parameter constraints in schemas. Add minItems, maxItems, pattern, enum, minimum, maximum to JSON Schema where applicable. For list_docs, specify limit: {type: 'integer', minimum: 1, maximum: 1000, default: 50}. For query parameters, document the expected syntax (free-form, regex, Coda formula, etc.).
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Score history
Overall score trend
↑ 62 points across a rubric change (v1 → v2)
62/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-22
C
62
<=2025-11-25
v2
2026-03-09
F
0
-
v1
Get a specific page's content in HTML format.
get_rowread onlyauthsource verified83/100
Get a specific row's data.
get_rowsread onlyauthsource verified83/100
Get rows from a table, with optional filtering and pagination.
get_tableread onlyauthsource verified83/100
Get a specific table's metadata and schema.
list_columnsread onlyauthsource verified85/100
List all columns in a table.
list_controlsread onlyauthsource verified85/100
List all controls in a document.
list_docsread onlyauthsource verified87/100
List available Coda documents. Returns doc IDs, names, and metadata.
Error handling lacks recovery guidance. Error responses wrap exceptions in McpError with generic messages (e.g., 'internal_error') but do not indicate whether the error is retryable, user-fixable, or fatal, nor what the LLM should do next.
Destructive operations (delete_doc, delete_row) lack confirmation or dry-run capability. An agent can permanently delete a document or row on first invocation with no safety gate, reversal path, or human confirmation step.
Parameter constraints not fully explicit. The 'limit' parameter in list_docs has a default (50) and a cap (1000), but these are enforced in code (params.limit.unwrap_or(50).min(1000)), not declared in the schema. Parameter descriptions do not state min/max, enums, format patterns, or examples.
Pagination not documented for list tools. list_docs, list_pages, list_tables, list_columns, list_formulas, and list_controls all accept a 'limit' parameter but no offset, cursor, or next_token. No indication of how to retrieve results beyond the limit or how pagination works.
Parameter descriptions lack context about expected format and constraints. E.g., 'query' parameter in search_docs/list_docs is described as 'Search query' but does not clarify what query syntax is expected (free-form text, Coda formula syntax, regex, etc.).
Cells parameter in add_row/update_row accepts generic object with no schema for field names or types. Description says 'key-value pairs (column name -> value)' but does not specify how values should be formatted (strings, numbers, dates, objects, nested structures, Coda formula syntax).
add_rowupdate_row
Document pagination strategy. For list_docs, list_pages, list_tables, list_columns, list_formulas, list_controls: clarify whether results are complete if under limit, whether a 'next' token or offset is available, and how to retrieve subsequent pages. Update descriptions to say 'Limit defaults to 50. Returns all available items if fewer than limit; otherwise, call again with limit to retrieve additional results.'
Clarify query parameter format and syntax. Update search_docs, list_docs, and get_rows descriptions to specify query language: e.g., 'query supports free-form text search' (search_docs/list_docs) vs. 'query uses Coda formula syntax (e.g., {Name} = "John")' (get_rows).
Define cell value format for add_row/update_row. Document how to represent different data types in the 'cells' object: strings, numbers, booleans, dates (ISO 8601?), arrays (for lookup fields), nested objects (for relationships). Include examples: 'cells: {"Name": "John", "Age": 30, "Start Date": "2024-01-15", "Tags": ["urgent", "review"]}'.
Add tool-chaining documentation. Document which tool outputs can feed into which tool inputs. E.g., 'list_docs returns doc_id values that get_doc, create_doc (source_doc), and delete_doc accept.' This guides agents and reduces discovery overhead.
Consider batch operations for common patterns. Add tools like add_rows (plural) or update_rows to accept arrays of row updates, reducing the overhead of sequential calls when agents need to update multiple rows.