Model Context Protocol server for DebtStack.ai credit data API. Enables Claude Desktop, Cursor, and other MCP clients to access corporate debt data.
The server has 2 tools with clear, well-structured descriptions and comprehensive input schemas. Both tools follow verb_noun naming convention (search_companies, search_bonds) with detailed parameter documentation and enum constraints. However, there are critical gaps in output schema documentation, error handling guidance, and parameter validation instructions. The descriptions, while detailed (215-230 chars), lack dependency hints and recovery guidance. Parameters like 'limit' are present but lack explicit min/max constraints. No evidence of audit logging, permission gates, or security validation patterns. The server is competent but incomplete for production agent deployment.
Search bonds by ticker, seniority, yield, spread, and maturity. Use for yield hunting, finding high-yield opportunities, or analyzing maturity walls. Example: 'Find senior unsecured bonds yielding above 8%'
Search companies by ticker, sector, leverage ratio, and risk flags. Use to find companies with specific characteristics, compare leverage across peers, or screen for structural subordination risk. Example: 'Find tech companies with leverage above 4x'
Output schemas not documented. LLM cannot plan follow-up actions (e.g., after search_companies returns results, which fields identify a company for downstream bond queries?). Users cannot understand what data they will receive.
No error handling guidance. API calls in mcp_server.py use response.raise_for_status() which will throw HTTPStatusError, but tool descriptions provide no recovery hints ('If no results found, try broadening filters'). LLM receives bare errors with no next-step advice.
Numeric parameters lack explicit constraints. 'limit' parameter has no min/max documented (description says 'default 10' but no upper bound stated). LLM could pass limit=10000, causing timeouts or API rejection. min_leverage, max_leverage, min_ytm lack range documentation.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 59 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 27 | - | v1 |
Parameter relationships undocumented. search_companies has min_leverage and max_leverage, but the tool description does not warn: 'If min_leverage > max_leverage, the query will return no results.' Similar relationship exists for search_bonds (min_ytm without max_ytm).
No chaining field documentation. If an LLM calls search_companies and then wants to search bonds for those companies, what field should it pass to search_bonds? Does search_companies return 'ticker' and does search_bonds accept 'ticker'? Output schema is missing, so chaining intent cannot be verified.
Ticker parameter ambiguity. search_companies accepts 'ticker' as 'Comma-separated tickers (e.g., AAPL,MSFT,GOOGL)' but search_bonds accepts 'ticker' as 'Company ticker(s)' without clarifying format (single or comma-separated?). LLM may format multi-ticker requests incorrectly.
No input validation error messages. If LLM passes invalid seniority to search_bonds (e.g., 'senior'), the httpx call will likely return a 400, but the error response gives no guidance on valid options. Tool definition shows enum ['senior_secured', 'senior_unsecured', 'subordinated'] but API error handling is missing.
No pagination guidance in descriptions. Both tools accept 'limit' but do not state whether results are paginated, whether there is a total_count or next_cursor in output, or how to retrieve additional results. Large result sets could exceed context window without user awareness.