Output schemas undocumented. Tools return data but visible code does not declare response shape, field names, or types. LLMs cannot infer result structure or plan downstream tool calls reliably.
Document output schemas for all 31 tools. For each tool, publish a TypeScript or JSON schema showing response structure, field names, types, and which fields are always present vs. optional. Example: extract_emissions_data should declare output as {scope_1: number, scope_2: number, scope_3: number, year: integer, source: string, confidence: number}.
Add explicit min/max and enum constraints to parameter descriptions. Replace 'Number of results to return (default: 10)' with 'Number of results to return (1 - 100, default: 10)'. Replace 'content_type optional' with 'content_type optional, must be one of: text, table'.
Provide human-friendly identifier alternatives. For tools accepting gridfs_id or document_id, add descriptions: 'gridfs_id: MongoDB GridFS ID of the PDF (or pass company_name + year to auto-resolve)'. Implement optional parameters like company_name, report_year as alternatives to opaque IDs.
Add error handling guidance to tool descriptions. For download_regulation, add: 'Returns 404 if regulation not found, ensure identifier is a valid CELEX number or short name (CSRD, CSDDD, ESRS). Available regulations can be fetched via list_regulations().' Similar guidance for crawl_company_website, download_pdf, and process_pdf_full_pipeline.
Document batch item schemas explicitly. For batch_extract_metrics, clarify: 'metric_categories is a list of strings, each one of: emissions, energy, water, waste, social, governance. Default: all categories.' For upsert_document_chunks, publish chunk item schema: {content: string (required), embedding: float[384] (required), chunk_index: int (required), page_number: int (optional), content_type: 'text'|'table' (optional)}.
Opaque identifier parameters without human-friendly alternatives. Tools use gridfs_id (MongoDB GridFS) and document_id (integer) but descriptions don't explain what users should pass or whether they can use file names, URLs, or company names instead.
No error handling guidance. Tool descriptions do not indicate what errors are retryable, what user input causes failures, or what recovery steps are available. Error messages will not guide LLM self-correction.
Batch operation schemas unclear. batch_extract_metrics and upsert_document_chunks accept array parameters (metric_categories, chunks) but neither the tool descriptions nor visible code document the schema of array items (structure, required fields, constraints).
Composition hints missing for multi-step workflows. Extraction and embedding workflows (download_pdf → process_pdf_full_pipeline → similarity_search) lack explicit documentation of dependencies and what data flows between steps.
Identifier naming inconsistency. Some tools use document_id (integer), others use gridfs_id (string). Parameter docs don't clarify relationship or whether these are interchangeable. Inconsistent naming increases LLM confusion.
Optional parameters with unclear defaults. target_year (optional for extract_* tools), use_tables (boolean, default: true), include_omnibus (boolean, default: true) lack documentation of what happens when omitted or what behavior changes.
No pagination guidance for list tools. list_documents and list_regulations accept limit/offset but descriptions don't state max limits, what happens when offset exceeds total results, or how to detect end-of-list.
list_documentslist_regulations
Add composition hints and workflow documentation. Create a 'workflows' section in server README showing: (1) PDF ingestion workflow: download_pdf → process_pdf_full_pipeline → returns document_id. (2) Query workflow: answer_esg_query accepts document_id (output from step 1). (3) Search workflow: generate_embeddings → upsert_document_chunks → similarity_search. Show which tools' outputs feed into which tools' inputs.
Standardize identifier naming across tool families. Choose one approach: (A) use document_id everywhere and resolve gridfs_id internally, or (B) provide both gridfs_id and document_id in every response so tools can chain seamlessly. Document the mapping clearly.
Clarify optional parameter behavior. For target_year (optional in extract_* tools), state: 'If omitted, extracts the most recent year present in the document. If specified, returns only that year's metrics or null if not found.' For use_tables, clarify: 'If true (default), prioritizes extraction from tables; if false, uses text patterns only.'
Add pagination hints to list tools. For list_documents, state: 'Maximum limit is 100. Returns total_count in response. If total_count > limit + offset, more results exist, increment offset by limit and call again. Returns empty array when offset >= total_count.'
Document which tools are idempotent vs. non-idempotent. Mark cache_query_response, upsert_document_chunks, and batch_extract_metrics as 'idempotent: passing identical inputs produces identical results' so LLMs know they're safe to retry. Mark download_pdf, download_regulation, download_all_regulations as 'non-idempotent: repeated calls may overwrite or duplicate data.'
Add required vs. optional field clarification for complex parameters. For similarity_search, clarify: 'query_embedding (required), k (optional, default 5), all filter parameters (optional). If query_embedding is missing, returns 400 with message: Required parameter missing: query_embedding (float array of length 384).'
Create a parameter glossary document. Define 'document_id' (auto-increment integer from MongoDB upon PDF ingestion), 'gridfs_id' (24-char MongoDB ObjectId string), 'company_name' (free text used for filtering/searching), 'report_year' (4-digit integer), so LLMs know what to pass and when to use lookup tools.