An MCP server that provides semantic tools for integrating multiple SaaS platforms (Todoist, Linear, Spotify, Strava) with token-optimized payloads and intelligent query translation.
Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
LinkForge MCP exhibits severe definition quality gaps across all 11 tools. All tools have empty input schemas (type: object with no properties), making parameter validation impossible. Descriptions, while present, are generic and lack actionable detail for LLM-driven tool selection. No parameter documentation exists, tools accept arbitrary arguments with no type constraints, ranges, or validation guidance. Output schemas are completely undocumented. Error handling provides minimal recovery guidance. The server enforces rate limiting (20 requests/60s) but offers no tool-specific hints on retry strategies or error conditions. Tools are read-only and stateless, which is positive, but this does not compensate for the absence of proper schemas and parameter constraints.
All 11 tools have empty input schemas ({"type":"object","properties":{}}). Per HARD SCORING RULES, schema score MUST be 0 for tools with no actual schema. This prevents input validation, parameter type discovery, and LLM reasoning about required vs optional arguments.
No parameter descriptions exist. All tools accept args: any with no type hints, constraints, or documentation. LLMs cannot determine what parameters are valid, what types they should be, or what values are acceptable. Tools like linear_get_blocked_high_priority_issues and strava_get_injury_risk_pattern offer no guidance on filtering or configuration.
get_server_health_summary
Recommendations
Add explicit input schemas to all tools. For tools that currently accept no parameters (e.g., get_server_health_summary, spotify_get_focus_music_playlists), declare this explicitly: {"type": "object", "properties": {}, "required": []}. For tools that accept optional filters (e.g., linear_get_blocked_high_priority_issues could accept 'project_id' or 'limit'), define those properties with types, descriptions, and constraints.
Document output schemas in tool descriptions or via a new 'outputSchema' field. Example for strava_get_injury_risk_pattern: 'Returns {"injury_risk_level": "low"|"medium"|"high", "factors": [...], "recommendation": "..."}'.
Expand tool descriptions to 80-150 characters following the pattern: '[ACTION] [WHEN]. Returns [RETURN TYPE]. Prerequisites: [DEPS]. Example use: [CONTEXT].' Example: 'Get high-priority issues blocked on dependencies. Use when prioritizing work. Returns [{id, title, blocked_by, priority}]. Requires Linear API key configured.'
Add parameter descriptions to the inputSchema for each tool. Example for a hypothetical 'limit' parameter: {"type": "integer", "minimum": 1, "maximum": 100, "description": "Max results to return. Default 20 recommended to avoid context bloat. API enforces 100-item cap."}
Differentiate error responses by type. Update LinkForgeError or CallToolResponse to classify errors as 'retryable', 'user_fixable', or 'fatal'. Include remediation hints. Example: isError: true, errorType: 'rate_limit_exceeded', message: 'Rate limit hit (20 req/60s). Retry after 60 seconds or reduce frequency.', suggestion: 'Batch requests or reduce polling interval.'
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Score history
Overall score trend
First recorded score · v2 rubric
44/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-23
F
44
<=2025-11-25
v2
Retrieves recent runs where pace has dropped indicating potential overtraining.
Output schemas are completely undocumented. Tool handlers return JSON.stringify(result) with no documented field names, types, or structure. LLMs cannot plan downstream operations or extract specific data points. For example, strava_get_injury_risk_pattern returns an inference but the fields are unknown to the agent.
Tool descriptions lack actionable context. Examples: 'Returns strictly blocked, high-priority issues' (linear_get_blocked_high_priority_issues) does not explain what 'blocked' means, what system defines priority, or when to use this vs linear_get_unassigned_urgent_issues. Per pattern:tool-description, descriptions should state WHAT, WHEN, and dependencies.
Rate limiting is enforced server-wide (20 requests per 60s per tool) but not exposed to LLM. No tool description mentions rate limits or retry backoff. An LLM hitting the limit receives a generic LinkForgeError with no guidance to back off or retry differently. Per pattern:recovery-guide, errors must tell the LLM what to do next.
No tool composition guidance. Tools like spotify_get_most_replayed_tracks_last_week and spotify_get_focus_music_playlists both return tracks but their output formats are undocumented. Unclear if an agent can chain results or if additional tool calls are required to use returned data.
No error handling guidance. Tool handlers catch LinkForgeError and return isError: true with a generic message, but do not guide recovery. A user-fixable error (e.g., 'invalid date range') receives the same treatment as a fatal error (e.g., 'authentication failed'). Per pattern:error-classification, errors should be categorized and recoverable errors should offer a path forward.
Document rate limits in tool descriptions. Add a note like 'Rate limit: 20 requests per 60 seconds per tool. Hitting the limit returns a 429-style error; back off and retry.'
Add tool annotations (readOnlyHint: true for all tools, since they are read-only). This signals to clients that these tools are safe to call without user confirmation.
For related tool clusters (e.g., Spotify, Strava, Linear, Todoist), add a 'See also' or 'Related tools' hint in descriptions to guide the LLM toward optimal composition.
Implement per-tool documentation including example invocations and sample outputs. Update README or inline docs to show: get_server_health_summary() -> {"status": "healthy", "uptime_seconds": 3600}, linear_get_blocked_high_priority_issues() -> [{"id": "ENG-123", "title": "...", "blocked_by": [...]}]
Add 'idempotentHint: true' to tool annotations for tools that return deterministic results (e.g., get_server_health_summary, spotify_get_focus_music_playlists) to signal safe retry semantics.