Server defines 5 tools with reasonable naming (verb_noun pattern) and basic descriptions. However, parameter descriptions are present but minimal, schemas lack detail around types/constraints, and output schemas are not documented. Error handling lacks recovery guidance. No tool annotations (readOnlyHint/destructiveHint). The codebase shows stateful session management via global registries (sessions, notebooks) but no evidence of per-request metadata or stateless request handling per current MCP spec.
Tools (5)
edit_filewriteauthsource verified67/100
Edit a file using find-and-replace with multiple matching strategies
execute_codeirreversibleauthsource verified68/100
Execute Python code or bash commands in a persistent Jupyter kernel session
list_filesread onlyauth50/100
List files in a directory within the session
read_fileread onlyauthsource verified68/100
Read the contents of a file from the session directory
Output schemas not documented. Tools return results but LLMs cannot predict response structure, field names, or data types. Critical for tool chaining and context planning.
Parameter type definitions missing or minimal in schema. 'session_id' and 'code' appear as strings but lack minLength, maxLength, or format constraints. 'replace_all' is boolean but has no default specified, risking unintended destructive edits.
No tool annotations (destructiveHint, readOnlyHint, idempotentHint) despite clear semantic differences. execute_code and write_file are IRREVERSIBLE/WRITE; read_file and list_files are READ_ONLY. Agents cannot reason about safety without annotations.
Add tool annotations: mark execute_code and write_file with destructiveHint=true, read_file and list_files with readOnlyHint=true, write_file with idempotentHint if safe, edit_file with destructiveHint.
Document output schemas for all tools. E.g., execute_code returns {result: string, stdout: string, stderr: string, return_code: int}; list_files returns {files: [{name: string, type: 'file'|'dir', size: int}], total_count: int}. Add to server registration or response hints.
Expand parameter descriptions to 50-200 characters. E.g., execute_code.code: 'Python code or bash command to execute in the persistent Jupyter kernel. Code is executed in sequence and state persists across calls with the same session_id. Output captured as stdout/stderr.' Add examples of what happens on error.
Add type constraints to parameters: session_id (pattern: '^[a-zA-Z0-9_-]{1,64}$'), code (minLength: 1, maxLength: 65536), path (pattern for relative paths), contents (minLength: 0, maxLength: 1000000), old_string (minLength: 1).
Add default for replace_all (false recommended for safety, require explicit true to replace all occurrences).
Implement error messages that guide recovery. On 'Session not found', return: 'Session xyz not found. Valid sessions: [list first 5]. Call execute_code with no session_id to create a new session.' On file write failure, return 'Permission denied writing to path/file.txt. Check directory permissions or try a different path.'
Add dry_run or confirmation parameter to execute_code and write_file. For write_file: add dry_run: bool (returns what would be written without actually writing). For execute_code: require explicit confirm: bool when code contains dangerous patterns (os.system, exec, subprocess, rm, etc.).
Error handling lacks recovery guidance. Code references exceptions (ValueError for 'Session not found', 'Notebook not found') but no tool returns actionable error messages. LLMs receive errors with no guidance on retry, user correction, or alternative actions.
Confirmation step missing for irreversible operations. execute_code (arbitrary Python/bash) and write_file accept no dry_run or confirm parameter. Agents can accidentally delete files or execute malicious code without a safety gate.
Parameter descriptions too brief to guide LLM selection. 'code': 'Python code or bash command to execute' does not explain what happens (kernel persists state?), what happens on error (exception output?), or when to use it vs alternatives. Patterns recommend 50-200 char descriptions.
No pagination or result limiting on list_files. If a directory contains thousands of files, the tool returns all of them, bloating context and risking timeout. Pattern recommends limit and offset/cursor parameters.
Session ID resolution ambiguous. 'If not provided, a new session is created' for execute_code, but read_file requires session_id with no auto-creation. Inconsistent behavior invites agent confusion and dangling sessions.
No idempotency contract. execute_code re-runs arbitrary Python each invocation; write_file can be retried safely but edit_file behavior on retry (re-apply same replacement?) is undefined. Agents need to know which operations are safe to retry.
execute_codeedit_file
Add pagination to list_files: parameters limit (1-1000, default 50) and offset (default 0). Return {files: [...], total_count: int, has_more: bool}.
Standardize session_id handling: require session_id for all tools; if not provided, return error 'session_id required. Create one with execute_code(code='print(1)') first.' This prevents dangling sessions and confusion.
Add idempotency keys or operation IDs for write_file and edit_file. For write_file, accept optional operation_id string (uuid). If repeated with same operation_id, return cached result instead of re-writing. Document in description.
Add boundary checks: code parameter maxLength 65536, path maxLength 1024, contents maxLength 1000000. Return actionable errors: 'Code too large (N bytes). Max is 65536 bytes.'
Return field names that match tool parameter names. If edit_file accepts old_string/new_string, any error should reference those exact field names for clarity.
Consider splitting write_file and edit_file into separate operations with clearer names: write_file (overwrites) vs patch_file (find-and-replace). Agents can then reason about intent more clearly.