This MCP server demonstrates severe quality gaps across naming, descriptions, schemas, and error handling. Only 3 tools are exposed, two of which are financial trading operations (buyorder, sellorder) with critical security and validation gaps. The add tool is trivial. Descriptions are minimal (under 50 chars). Parameter descriptions are entirely absent. No output schema documentation. No error handling guidance. The server exposes irreversible financial operations without confirmation patterns, dry-run modes, or permission gates. Critical credentials (api_key, api_secret, request_id) are hardcoded in index.py with empty placeholders, representing a severe security vulnerability. The codebase references external CSV files for symbol lookup but does not validate inputs or handle missing files gracefully.
Irreversible financial operations (buyorder, sellorder) lack confirmation patterns, dry-run support, or permission gates. An LLM can trigger real trades without user acknowledgment, causing irreversible financial loss.
Parameters in buyorder and sellorder lack individual descriptions. The LLM cannot infer the meaning of symbolname, qty, limit_price, or exchange constraints from the parameter names alone. No enum constraint on exchange despite only NSE and BSE being valid.
Credentials (api_key, api_secret, request_id, settings_file path) are hardcoded with empty placeholders in index.py. This is a severe security vulnerability, credentials must use server-side secret injection via environment variables or a vault, never exposed in source or as tool parameters.
buyordersellorder
Recommendations
Add per-parameter descriptions for buyorder and sellorder. Example: 'symbolname: Name of the security to trade (e.g., HDFCBANK). Must match an instrument in the configured CSV file.' 'qty: Quantity to trade. Must be a positive integer.' 'limit_price: Maximum price per unit (for buy) or minimum price per unit (for sell). Must be a positive number.' 'exchange: Stock exchange code. Valid values: NSE, BSE.'
Declare exchange as an enum: {"type": "string", "enum": ["NSE", "BSE"], "description": "Exchange code..."}
Rename buyorder → place_buy_order and sellorder → place_sell_order to follow verb_noun naming convention.
Implement a confirmation pattern for trading operations. Add a dry_run parameter (boolean, default false) or return a confirmation structure (order_preview with estimated cost/proceeds) that requires explicit confirmation before execution. Example: dry_run=true returns 'Order would buy 100 HDFCBANK at ₹1800.50 = ₹180,050 total. Call again with order_id=<preview_id> to confirm.'
Implement proper error handling. Catch exceptions and return structured error objects: {"status": "error", "code": "SYMBOL_NOT_FOUND", "message": "Symbol 'INVALID' with exchange 'NSE' not found in instruments CSV.", "suggestion": "Available symbols: HDFCBANK, RELIANCE, INFY. Try searching the available list."}. Include error classification (retryable, user-fixable, fatal).
No output schema documentation. buyorder and sellorder return the raw API response (via placebuyorder/placesellorder), but the structure, fields, and types are not documented. The LLM cannot plan downstream actions or extract order IDs for confirmation or cancellation.
Error handling is absent. Functions catch exceptions but only print to stdout ('print(f"Error...")') and return None. The LLM receives no guidance: is the error retryable? Should it ask the user? Is the operation already committed?
External CSV file dependency (instruments.csv) is unchecked. The path is hardcoded with an empty placeholder. If the file is missing or path is wrong, the tool silently returns None. No retry guidance or fallback.
Tool naming 'buyorder' and 'sellorder' lacks a verb prefix. Following Agentic Tool Patterns, names should start with an action verb (create_, place_, send_, submit_). 'buyorder' is ambiguous, is it a noun (a buy order object) or a verb (place a buy order)?
No input validation. Parameters (qty, limit_price) are integers/floats but have no min/max constraints or validation. An LLM could pass qty=0 or limit_price=-100. No constraint documentation or runtime guards.
exchange parameter accepts free-form strings but only NSE and BSE are valid. Should be an enum constraint. The code checks and rejects invalid exchanges but does not guide the LLM about valid options in the description.
buyordersellorder
Move credentials from index.py to environment variables. Use os.getenv('NUVAMA_API_KEY'), os.getenv('NUVAMA_API_SECRET'), etc. Never hardcode or expose as tool parameters.
Validate and handle the CSV file path. Load it at server startup; fail fast if missing. Return clear errors if the symbol is not found.
Document output schemas. Specify what place_buy_order returns: {"order_id": string, "status": string (pending|confirmed|rejected), "symbol": string, "quantity": integer, "limit_price": number, "estimated_cost": number, "exchange": string}. Include IDs needed for downstream operations (cancel_order, get_order_status).
Add permission checks. Verify the calling user/agent has authorization to trade before executing. Log the user, timestamp, parameters, and result for audit trails.
Provide recovery guidance in error messages. Example: 'CSV file not found at /path/to/instruments.csv. Ensure the path is configured correctly in the environment or server setup. Retry after configuration is fixed.'
Consider offering separate read-only tools: get_symbol_info, list_available_symbols, get_current_price. This lets LLMs safely explore before committing to trades.