The VBA MCP server has 8 tools with acceptable naming conventions and basic parameter schemas, but suffers from significant gaps in description quality, output schema documentation, and error handling. Tool names follow verb_noun patterns (vba_list_modules, vba_read_module, vba_write_module, vba_delete_module, vba_backup, vba_list_workbooks) which is good, but descriptions are minimal (10-20 chars average) and lack actionable context for LLM tool selection. Parameter descriptions exist but are sparse (e.g., 'Path to the Excel file' repeated 6 times). Output schemas are completely undocumented, tools return JSON strings or plain text without declaring structure. Error handling is present but returns raw JSON error messages without recovery guidance. No idempotency hints, no rate limiting guidance, and no permission gates on destructive operations (delete_module). The server lacks security patterns like audit trails or secrets handling guidance.
Tools (8)
vba_backupread onlysource verified57/100
Backup all VBA modules to text files.
vba_create_modulewritesource verified60/100
Create a new VBA module.
vba_delete_moduledestructivesource verified57/100
Delete a VBA module (Sheet/ThisWorkbook modules cannot be deleted, only cleared).
vba_list_modulesread onlysource verified60/100
List all VBA modules in an .xlsm file.
vba_list_workbooksread onlysource verified53/100
List .xlsm files in a directory.
vba_read_allread onlysource verified57/100
Read ALL VBA modules at once. Useful for full codebase review.
Output schemas are completely undocumented. Tools return JSON strings or plain text without declaring the structure of the returned data. LLMs cannot plan downstream tool calls or extract specific fields without guessing at the response format.
Destructive tool (vba_delete_module) lacks confirmation or dry-run capability. No mention of a confirmation flow or recovery mechanism. Agents can accidentally delete modules without safeguards.
Error responses lack recovery guidance. When a module is not found, the tool returns a JSON error with available_modules list, but does not guide the LLM on next steps (e.g., 'Try vba_list_modules first to see available modules').
vba_read_modulevba_write_module
Recommendations
Document the output schema for each tool. For vba_list_modules, explicitly declare: 'Returns JSON array of module objects: [{name: string, type: string, type_id: number, line_count: number}, ...]'. For vba_read_module, declare: 'Returns string of VBA source code with a header comment.' This enables LLMs to plan downstream calls.
Expand tool descriptions to 50-150 characters with context. Example for vba_read_module: 'Read the complete VBA source code from a named module in an Excel workbook. Requires Excel 2013+ with VBA trust enabled. Use vba_list_modules first to discover available module names.'
Parameterize and document file_path constraints. Add to description: 'Absolute or relative path to a .xlsm, .xlsb, .xls, .xla, or .xlam file. File must exist and Excel must have VBA trust enabled (File > Options > Trust Center > Macro Settings).'
Add enum constraint to module_type in vba_create_module. Change schema to: {"type": "string", "enum": ["standard", "class"], "description": "Type of module: 'standard' (default) for code modules, or 'class' for class modules."}
Add recovery guidance to error messages. Example: 'Module "MyModule" not found. Available modules: ["Module1", "Module2"]. Did you mean one of these? Or call vba_list_modules to see all modules.'
Add idempotency declarations to write tools. For vba_write_module: 'IDEMPOTENT: Safe to retry. Calling twice with the same code overwrites the module identically; no duplicates created.' For vba_create_module: 'NOT IDEMPOTENT: Calling twice with the same module_name will fail on the second call because the module already exists (unless create_if_missing is false). Recommend checking with vba_list_modules before creating.'
Score history
Overall score trend
First recorded score · v2 rubric
50/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-23
D
50
2026-07-28+
v2
source verified
60/100
Write/replace VBA module code. Auto-saves the workbook.
Tool descriptions are too short (10-20 characters) and lack context. Descriptions like 'List all VBA modules in an .xlsm file' do not explain WHEN to use the tool vs. alternatives, what data structure is returned, or prerequisites (e.g., 'requires Excel trust for VBA access').
Parameter descriptions are generic and repeated. 'Path to the Excel file' appears 6 times without clarifying file format requirements (.xlsm vs .xlsb vs .xls), expected format (absolute vs relative path), or validation rules.
No idempotency hints on write/create operations. vba_write_module and vba_create_module do not declare whether they are safe to retry. Agents need to know if a retry will duplicate module creation or overwrite silently.
No permission gates or security audit trails. There is no mention of user authentication, permission checks, or logging of who called which tool and when. Critical for compliance and security.
Parameter enums and constraints are missing. module_type in vba_create_module accepts 'standard' or 'class' but this is documented only in the description, not as a JSON Schema enum. LLMs may hallucinate other values.
No pagination or result limits declared. vba_list_modules and vba_read_all could return very large codebases without any pagination or limit guidance. A large VBA project could blow the context window.
No error classification (retryable vs. user-fixable vs. fatal). Errors are returned but the LLM cannot determine if it should retry, ask the user, or give up. For example, FileNotFoundError vs. PermissionError require different agent responses.
Add permission gates and audit logging guidance. Example: 'This tool modifies Excel files. Verify user has write access to the target file path. Log call details (user, file, module, timestamp) for compliance.'
Declare result limits and pagination. For vba_read_all: 'Returns all module code concatenated. Large codebases (>1000 lines total) may exceed context limits. Consider calling vba_read_module individually for specific modules instead.'
Add error classification hints. Example for FileNotFoundError: 'File not found. USER-FIXABLE: Verify the file path is correct and the file exists. RETRYABLE: No, unless the file is being created concurrently.' For PermissionError: 'Permission denied. USER-FIXABLE: Ensure the file is not locked by another process and you have write access.'
Add confirmation or dry-run support to vba_delete_module. Example: Add parameter 'dry_run: bool = true' (default safe), and return '{"success": false, "would_delete": "ModuleName", "message": "Dry-run: no module deleted. Set dry_run=false to confirm deletion."}' on first call.
Document timeout and rate limiting. Example: 'This tool opens Excel via COM, which can be slow on large files (up to 30 seconds). No rate limit, but concurrent calls to the same Excel instance will serialize. Recommended: <5 calls/minute to avoid Excel COM thrashing.'
Add batch tool variants. Consider vba_read_modules (plural) accepting an array of module names and returning an array of {name, code} to reduce round-trips for common patterns like 'read all modules starting with Utilities_'.