An MCP server for lead generation and enrichment that integrates web crawling, email discovery, and company data enrichment from multiple external sources
LeadGenServer exhibits critical deficiencies across naming, descriptions, and schema quality. While all three tools are explicitly registered via @mcp.tool() decorators in lead_server.py, the implementation shows poor LLM-readiness. Tool names lack clear action verbs (lead_generation is vague; lead_maintenance is a non-standard pattern). Descriptions are minimal (15-28 chars), below the 34-char p10 baseline for production tools. Parameter descriptions are either missing or trivial. Input schemas are present but minimal, only search_terms, lead_id, and empty params for maintenance. Output schemas are not documented. Error handling is basic (ValueError for missing terms/lead, but no recovery guidance). Security is severely compromised: API keys (HUNTER_API_KEY, CLEARBIT_API_KEY, LINKEDIN_COOKIE) are exposed as module-level constants in source code, creating a credential leak risk if the server is ever version-controlled or containerized. The lead_maintenance tool is DESTRUCTIVE (deletes records) but lacks any confirmation or dry-run mechanism. The server is STDIO-only, which is a hard cap at 50 for protocol readiness but also means it cannot work with remote agents, no real-world deployment model.
Full enrichment pipeline with external services
Generate lead with proper ID and storage
Clean up old leads and cache
API credentials hardcoded in source code (HUNTER_API_KEY, CLEARBIT_API_KEY, LINKEDIN_COOKIE as module constants). Credentials must never be tool parameters OR exposed in source; use environment variables and secret injection.
Destructive tool (lead_maintenance) lacks any confirmation, dry-run, or permission check. Deletes records older than 7 days with no recovery path. Missing confirmation-request pattern.
Tool descriptions are critically short (10 - 28 chars, well below 34-char p10 baseline). Descriptions must state WHAT the tool does, WHEN to use it, and any state-modifying side effects. Examples: 'Generate lead with proper ID and storage' (28 chars) lacks context for LLM selection; 'Clean up old leads and cache' (27 chars) is incomplete, doesn't say 'deletes records older than 7 days'.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 33 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 30 | - | v1 |
Tool naming lacks clear action verbs. 'lead_generation' is vague (generate what? in what form?). 'lead_maintenance' is non-standard and ambiguous (cleanup? refresh? validate?). Best practice: create_lead, update_lead_enrichment, delete_expired_leads.
Parameter descriptions are missing or trivial. 'lead_id' lacks context (unique identifier of what? lead record ID? external reference?). lead_maintenance accepts zero parameters but manipulates internal state, LLM cannot control what gets deleted.
Output schemas are not documented. Callers do not know what fields to expect in responses. Example: lead_generation returns {'lead_id': ..., 'status': 'created'}, but downstream tools expect a 'lead' object with nested fields. Undocumented responses break tool chaining.
Error handling is minimal. ValueError exceptions are raised but no recovery guidance is provided. 'Lead not found' should suggest calling lead_generation or searching existing leads. Missing error-classification and recovery-guide patterns.
lead_generation accepts a free-form 'search_terms' string with no constraints, validation, or examples. Should enforce: non-empty, max length, character restrictions (e.g., alphanumeric + space/hyphen only). LLM-provided search terms could be malicious or nonsensical.
lead_maintenance deletes records without user/agent confirmation or audit trail. No way to undo or recover deleted leads. Missing permission-gate and audit-trail patterns.
Tool composition is unclear. lead_generation creates a lead but does not enrich it. data_enrichment requires a lead_id but does not document what happens if enrichment fails partway (hunter succeeds, clearbit fails, linkedin times out). No compensation tools to undo partial failures.