Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
The server has 30 tools covering a complete YouGile project management API surface. Tool naming follows verb_noun patterns consistently (get_*, create_*, update_*). All tools have descriptions (10-150 chars), and parameter schemas are present with type declarations. However, descriptions are often generic or lack actionable context for LLMs. Several parameters lack clear formatting constraints, and output schemas are undocumented. Error handling is minimal. The tools show idempotency support (idempotencyKey params) and composition chains (e.g., get_task → send_task_message), which are strengths. Overall execution is competent but lacks the polish of production-grade agent tools.
Output schemas undocumented. No visible return type definitions for any of the 30 tools. LLMs cannot plan downstream tool calls or extract fields without knowing the response structure.
Document return types for all 30 tools. Create a response schema section in the source (src/tools/index.ts or a schema file) that explicitly defines what fields each tool returns. Example: get_board returns {id: string, title: string, description?: string, projectId: string}. This enables LLMs to plan multi-tool sequences.
Expand tool descriptions to 100-200 characters. For each tool, add context: (1) What does it do? (2) When use it instead of a similar tool? (3) What does it return? Example: 'Get a specific board by ID. Returns board title, description, and project ID. Use this after search_boards() when you have a board ID. For all boards, call get_boards() instead.'
Add per-tool error handling guidance. In descriptions, note common failure modes and recovery steps. Example for create_project: 'Creates a new project. Returns the project ID. If title is already taken, YouGile returns a 409 error, try a different name or call get_projects() to see existing titles.'
Specify bounds for numeric parameters. For 'limit' in get_boards, get_columns, get_tasks, add: 'Limit number of items returned (1 - 100, default 20)'. For 'offset', add: 'Zero-indexed offset for pagination.'
Add tool annotations to the server.ts registerTools() call. For destructive tools (delete_user, update_task with archived=true), add tool.destructiveHint = true. For read-only tools, add tool.readOnlyHint = true. For create_* tools with idempotencyKey, add tool.idempotentHint = true. This guides agent planning and safety.
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Score history
Overall score trend
↑ 32 points across a rubric change (v1 → v2)
69/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-22
C
69
<=2025-11-25
v2
2026-03-09
F
37
-
v1
read onlyauthsource verified78/100
Get all boards in the company
get_columnread onlyauthsource verified81/100
Get a specific column by ID
get_columnsread onlyauthsource verified78/100
Get all columns in a board
get_meread onlyauthsource verified80/100
Get the current authenticated user (the user the API key belongs to)
Get messages for a specific task (alternative method)
get_tasksread onlyauthsource verified82/100
Get tasks list. IMPORTANT: YouGile API does NOT support projectId filter! Use columnId or assignedTo instead. For complete user task list, use get_user_tasks.
get_userread onlyauthsource verified81/100
Get a specific user by ID
get_user_tasksread onlyauthsource verified82/100
Get ALL tasks assigned to a user. Uses assignedTo filter which works correctly for all projects.
get_usersread onlyauthsource verified78/100
Get all users in the company
send_task_filewriteauthsource verified78/100
Upload a file and send it to task chat in one step. Handles the /root/#file: prefix automatically.
send_task_messagewriteauthsource verified78/100
Send a message to a specific task's chat. For images/files, upload first then use text='/root/#file:/user-data/.../file.jpg'
update_boardwriteauthsource verified75/100
Update an existing board
update_columnwriteauthsource verified75/100
Update an existing column
update_projectwriteauthsource verified73/100
Update an existing project
update_taskwriteauthsource verified78/100
Update an existing task
update_userwriteauthsource verified78/100
Update an existing user
upload_filewriteauthsource verified72/100
Upload a file to YouGile and get its URL
Descriptions lack actionable context. Most descriptions are 10-80 characters and do not explain when to use each tool vs. similar ones, or what the LLM receives back. E.g., 'Get a specific board by ID' does not distinguish get_board from get_boards or explain pagination.
No error handling or recovery guidance. Tools lack descriptions of failure modes, retryability, or actionable error messages. E.g., no guidance on what happens if a board ID is invalid or a user email already exists.
Parameter constraints not documented. Numeric params (limit, offset) lack min/max bounds. String params lack format/length constraints. E.g., 'limit' for get_boards and get_columns is type 'number' but no range specified.
Tool chaining broken: output schemas not documented. E.g., send_task_message needs a taskId parameter, but get_tasks does not document that it returns taskId. Agents cannot infer the field mapping.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). Tools like delete_user and create_task have Risk labels in the spec but no corresponding MCP tool annotations to guide agent planning.
Resource identifier flexibility limited. Some tools force system IDs (e.g., delete_user takes 'id' only, not email). Users say 'remove [email protected]', but LLM must first call get_users to find the ID.
delete_userget_userupdate_user
Support natural identifiers for user lookups. Modify get_user, update_user, delete_user to accept either user_id or user_email parameters (not just 'id'). Inside the tool, resolve email → ID if needed. This matches how users think: 'remove [email protected]' rather than 'remove U12345'.
Document pagination behavior. For tools returning lists (get_boards, get_tasks, get_users), clarify: does the API return a total count? Is there a next_cursor? What happens if offset exceeds the total? This lets LLMs know when to stop iterating.
Add a get_tasks_by_project helper or clarify the API limitation. The tool description already notes 'YouGile API does NOT support projectId filter!', good. Consider adding a wrapper tool or detailed guidance on the workaround (get_project → get_boards → get_columns → get_tasks), or provide a batch tool that does this internally.
Formalize idempotency guarantees. For tools with idempotencyKey (create_board, create_column, create_project, create_task), document: 'Retrying with the same key returns the already-created resource instead of duplicating it. Use a deterministic key (e.g., hash of user input) to safely retry on network errors.'
Add examples to parameter descriptions for complex types. For the 'stickers' parameter in create_task (type: record), add: 'Map of sticker ID to state ID, e.g. {"sticker-123": "state-456"}. Call get_string_stickers() first to find available stickers and states.'
Document file upload flow. For upload_file and send_task_file, clarify: does upload_file return a public URL or a backend path? For send_task_message with '/root/#file:...' syntax, explain: 'First call upload_file(filePath), then pass the returned path to send_task_message() or send_task_file().'
Add batch variants where agents use loops. If agents often call send_task_message in a loop, offer send_task_messages (plural) taking an array of {taskId, text}. This reduces token overhead and latency.
Validate and sanitize all user input. Even though parameters have types, add server-side validation that rejects invalid IDs, oversized strings, and SQL-injection-like payloads. Return clear errors: 'Invalid project ID format: must be a UUID' instead of a generic 500.
Return human-readable field names in responses. If the API returns camelCase (boardId, projectId), that is fine, but ensure response schemas match parameter names (e.g., if a tool takes boardId, the response should also use boardId, not 'board_id'). This prevents LLM mapping errors.