Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
This server provides 6 tools for interacting with a Basilisp nREPL bridge. While tool names follow verb_noun conventions and descriptions are present, there are critical gaps in schema completeness, parameter validation, error handling guidance, and output documentation. The source code shows tool definitions via FastMCP decorators, but input schemas are minimal (only 'code' or 'symbol' params with basic descriptions). Output schemas are completely undocumented, LLMs have no visibility into what fields to expect. Error messages are generic ('Error: ...') without recovery guidance. The server lacks idempotency information, permission declarations, rate limiting, and structured output guidance. This is a typical community server with working basics but significant production gaps.
Tools (6)
check_connectionread onlysource verified53/100
Check if the nREPL server is running and responding.
eval_coderead onlysource verified62/100
Evaluate Basilisp code in nREPL.
execute_basilispread onlysource verified55/100
Execute Basilisp code in nREPL (alias for eval_code).
Output schemas completely undocumented. Tools return plain strings without documenting structure (e.g., what fields parse_bencode_response extracts, whether results include metadata, error format). LLMs cannot plan downstream tool calls or extract structured data without visibility into response schema.
Error messages lack recovery guidance. Errors like 'Error: nREPL connection refused' or 'Error: Could not create nREPL session' do not tell the LLM what to do next (retry, check server, call different tool, etc.). This violates recovery-guide pattern.
Tool composition broken: eval_code and execute_basilisp are duplicates (execute_basilisp just calls eval_code). This violates single-responsibility principle and wastes LLM reasoning cycles deciding between identical tools.
Recommendations
Document output schemas for all tools. Specify: for eval_code, does it return {result: string, type: string, error?: string} or just plain text? For list_namespaces, does it return {namespaces: [string], total: number} or a list? Provide structured responses so LLMs know what fields to extract.
Enhance error messages with recovery guidance. Replace 'Error: nREPL connection refused' with 'Error: nREPL connection refused. The nREPL server at 127.0.0.1:36915 is not running. Ensure it is started before retrying, or use check_connection to verify.' Apply error-classification pattern: categorize as retryable (connection timeout), user-fixable (bad code syntax), or fatal (nREPL crashed).
Remove execute_basilisp or make it distinct. Currently it is a pure alias for eval_code, violating single-responsibility. Either delete it, or give it a distinct purpose (e.g., eval_code for read-only, execute_basilisp for side-effects with confirmation).
Add parameter format constraints. For 'code' param, document expected syntax (Basilisp BNF link), max length (e.g., 10KB), and examples. For 'symbol', explain namespace resolution (e.g., 'unqualified symbols search current namespace'). For 'namespace', enumerate common namespaces or link to discovery mechanism.
Implement input validation and early error returns. Check code is non-empty, symbol matches expected pattern, namespace exists (or hint alternatives). Return structured error: {error: 'Invalid symbol format', expected_pattern: '...', received: '...'}. This lets LLMs self-correct in one retry.
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Parameter descriptions are minimal and lack format/constraint information. 'code' is described as 'Basilisp code to evaluate' with no mention of syntax requirements, max length, or what constitutes valid input. 'symbol' lacks specification of namespace resolution rules. 'namespace' lacks examples or enumeration of available namespaces.
No input validation or error classification. Tools accept any string input without validation (e.g., code could be empty, symbol could be malformed). When errors occur, they are not categorized as retryable vs. user-fixable vs. fatal, leaving LLM unable to decide next action.
No idempotency guarantees. eval_code creates a new nREPL session per call with no deduplication. If an LLM retries on failure, side effects (code executed multiple times) may occur. No idempotent-operation pattern applied.
No pagination support for potentially large results. list_namespaces and find_namespace_vars could return hundreds or thousands of items, but no limit or pagination parameters are offered.
No permission gates or scope declarations. Tools have no mechanism to verify caller authority or declare required permissions (e.g., 'read:repl', 'execute:code'). This violates permission-gate and scope-declaration patterns.
No rate limiting. Agents calling eval_code in a retry loop could generate hundreds of nREPL requests per minute without guards, overwhelming the server or resource. Rate limiting pattern not implemented.
No audit trail. Tools have logging via ctx.info/ctx.error, but no structured audit log of who called what tool, with which parameters, and what happened. This violates audit-trail pattern required for compliance.
Add idempotency tokens or deduplication. Assign a unique request_id per LLM call. When eval_code retries, send the same request_id; server reuses cached result instead of re-executing. Or document in description: 'Repeated calls with identical code may execute multiple times; use check_connection first to verify server state.'
Add pagination to list_namespaces and find_namespace_vars. Accept optional limit (default 20, max 100) and offset parameters. Return {items: [...], total: number, has_more: boolean, next_offset?: number}.
Declare scope requirements. Add to tool description: 'Requires: read:repl'. Implement permission check in tool body: if not user.has_permission('read:repl'): raise PermissionError(...).
Implement rate limiting. Track calls per client/agent. Return 429 Too Many Requests if limit exceeded: 'Rate limit exceeded: 100 calls per minute. Retry after 30 seconds.' Let LLMs backoff intelligently.
Add structured audit logging. Log to stderr in JSON format: {timestamp, agent_id, tool_name, params_hash, result_status, execution_time_ms}. Omit sensitive values (code content). This enables incident investigation.
Wrap eval_code to support dry-run / preview mode. Add optional 'dry_run: bool' parameter. When true, parse code syntax without executing; return warnings but no side effects. This prevents LLM from accidentally running destructive code.
Add discover-style tool or enrich results. For find_namespace_vars, if namespace not found, return error with list of available namespaces: 'Namespace not found. Available: clojure.core, user, myapp.core'. This enables LLM to self-correct without extra round-trip.
Enhance get_docs to return structured output. Return {symbol, namespace, docstring, signature, examples: [...], see_also: [...]} instead of plain text. LLMs can then format for user or chain to related symbols.