Static source inference · medium confidence · evidence: structured output
No deprecated protocol patterns detected
Summary
This server has 10 tools with explicit schemas and descriptions. Naming is consistent and clear (verb_noun pattern observed across all tools). However, there are notable gaps in description depth, missing output schema documentation, and no error handling guidance. Descriptions average ~60 chars, below the 194-char baseline for A+ tools. All tools have input schemas with proper types and enums, but output structures are not formally documented. The server uses Zod for validation but does not expose error messages in a way that guides LLM recovery. Parameter descriptions are present but terse, many lack context on when to use values or what constraints apply beyond basic type info. The tools themselves are well-composed (each does one thing), but the definitions lack the depth and LLM-optimization needed for 70+.
Output schemas are not documented. While input schemas are well-defined with types and enums, the server does not specify what fields are returned by any tool. LLMs cannot infer downstream tool dependencies or plan multi-step workflows without knowing the response structure.
Descriptions lack LLM-optimization depth. Average description is ~60 chars; baseline for A+ tools is 194 chars. Descriptions should answer WHAT the tool does, WHEN to use it vs similar tools, and WHAT it returns. Current descriptions are mechanical and lack context. E.g., 'Send a friend request with an optional note' does not explain failure modes, rate limits, or whether the note should be personalized.
send_friend_requestadd_labeladd_tagget_crm_stats
Recommendations
Document output schemas for all 10 tools. For each tool, specify the response structure as JSON Schema with field types and descriptions. For example, search_leads should return {leads: [{id: string, name: string, profileUrl: string, ...}], total: integer, hasMore: boolean}. This enables LLMs to chain tools and plan workflows.
Expand tool descriptions to 100-200 chars following the WHAT/WHEN/WHAT pattern. Example for send_friend_request: 'Send a Facebook friend request to a profile. Use this after identifying leads to build relationships. Note: Rate-limited to 5/min; will fail if already connected. Returns success status and request ID for tracking.'
Add error handling to tool responses. Catch validation errors (invalid URL format, invalid label), API errors (rate limit, already connected), and partial failures (broadcast succeeded for N/M contacts). Return a structured error response with code, message, and recovery hint. For send_broadcast: 'Broadcast partially failed: 47/100 contacts delivered. Contacts without messenger: [list]. Retry with send_broadcast or add_messaging_contact for missing ones.'
Enhance parameter descriptions with constraints and examples. For 'label': 'A category label (1-50 chars, alphanumeric + hyphen, case-insensitive). E.g., warm-lead, vip-founder, follow-up-april.' For 'contactId': 'The Feather CRM contact ID (format: contact_NNN, e.g., contact_001).'
Add a send_broadcast_batch tool or extend send_broadcast to accept an optional contact_ids parameter: 'send_broadcast({label: "warm", message: "...", contact_ids?: ["contact_001", "contact_002"], dryRun?: true})'. This avoids creating temporary labels for targeted sends.
Score history
Overall score trend
↑ 11 points across a rubric change (v1 → v2)
52/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-22
D
52
2025-06-18+
v2
2026-03-09
F
41
-
v1
73/100
Search for potential leads by keywords, groups, or interests.
No error handling guidance. Tools return no actionable error messages. If send_friend_request fails (e.g., already connected, rate limited, invalid URL), the LLM receives no hint on what went wrong or what to try next. Error responses should categorize issues as retryable, user-fixable, or fatal, and suggest recovery steps.
Missing dry-run support for destructive operations. send_broadcast modifies CRM state by delivering messages. The dryRun parameter exists, but there is no documentation of its behavior or recovery guidance if broadcast partially fails (e.g., 50 of 100 contacts receive the message).
Parameter descriptions lack actionable constraints. Many parameters (e.g., 'contactId', 'label', 'tag') are described only by type, not by format, length, or example. The description for 'label' says 'Label to apply' but does not explain valid characters, max length, or whether labels are case-sensitive.
Tool composition could be optimized. send_broadcast requires a label (send to all contacts with that label) but does not accept a list of contact IDs or a search query. If the agent wants to send to a subset of labeled contacts, it must construct a new label, which is inefficient and error-prone.
send_broadcast
Implement input validation in tools with clear error messages. For example, if profileUrl is not a valid Facebook URL, return 'Invalid profile URL. Must be https://facebook.com/<name> or https://www.facebook.com/<id>. Got: <url>'.
Add a 'note' field to get_request_status and list_contacts responses to surface the personalized note sent with each request/contact. This helps agents understand conversation history and personalize follow-up messages.
Implement pagination for search_leads and list_contacts to handle large result sets. Add offset/limit parameters and return a cursor for the next page. Current max results (50 for search_leads, 100 for list_contacts) is reasonable, but should be documented in tool descriptions.
Add idempotent hints to tool definitions. Clarify that add_label and add_tag are idempotent (applying the same label/tag twice is a no-op), so agents can safely retry. Document that send_friend_request is NOT idempotent if already connected.
Create a usage guide or FAQ in the server documentation addressing common patterns: 'To nurture warm leads, call search_leads(query, source="groups"), then add_label(warm), then send_broadcast(label="warm", message=..., dryRun=true) to preview before sending.' This helps agents understand the intended composition.