Thank you for your interest in contributing to Sbroenne.ExcelMcp! This project is designed to be extended by the community, especially to support coding agents like GitHub Copilot.
ExcelMcp aims to be the go-to command-line tool for coding agents to interact with Microsoft Excel files. We prioritize:
- Simplicity - Clear, predictable commands
- Reliability - Robust COM automation
- Extensibility - Easy to add new features
- Agent-Friendly - Designed for AI coding assistants
-
Prerequisites:
- Windows OS (required for Excel COM)
- Visual Studio 2022 or VS Code
- .NET 10 SDK
- Microsoft Excel installed
-
Setup:
git clone https://github.com/sbroenne/mcp-server-excel.git cd mcp-server-excel dotnet restore dotnet build
-
Test your setup (surgical — don't run the full integration suite, it takes 45+ minutes):
dotnet test --filter "Feature=Sheet&RunType!=OnDemand"
All changes must be made through Pull Requests (PRs). Direct commits to main are prohibited.
Merge Strategy: Squash Merge — All PRs are merged via squash merge (single commit to main). This keeps the history clean.
- Create feature branch:
git checkout -b feature/your-feature - Make changes: Code, tests, documentation
- Run the pre-commit hook: install it once with
Copy-Item scripts\pre-commit.ps1 .git\hooks\pre-commit, then let it run on every commit — it enforces 14 automated gates (COM leak detection, MCP/CLI coverage parity, Release build, packaging deliverables, smoke tests, and more). Never bypass it with--no-verify. - Push branch:
git push origin feature/your-feature - Create PR: Use GitHub's PR template
- Address review: Make requested changes, including any automated review comments (Copilot, GitHub Advanced Security)
- Merge: After approval and CI checks pass — GitHub will squash commits automatically
- Verify the final commit message accurately describes the changes
- After merge, your feature branch can be safely deleted
📋 Detailed workflow: See DEVELOPMENT.md for complete instructions.
- C# 12 features encouraged (file-scoped namespaces, records, pattern matching)
- Nullable reference types enabled - handle nulls properly
- No warnings - project must build with zero warnings
- XML documentation for public APIs (these docs are extracted into MCP tool descriptions and shown to LLMs — keep them accurate)
- Consistent naming - follow established patterns
ExcelMcp has two equal entry points — an MCP Server and a CLI — sharing one Core layer:
MCP Server ──► In-process ExcelMcpService ──► Core Commands ──► Excel COM
CLI ─────────► CLI Daemon (named pipe) ─────► Core Commands ──► Excel COM
ExcelMcp.ComInterop- Reusable COM automation primitives (STA threading, session/batch management)ExcelMcp.Core- Excel business logic (Power Query, VBA, worksheets, PivotTables, etc.)ExcelMcp.Service- Excel session management and command routingExcelMcp.CLI- Command-line interface (session-based:excelcli session open, then operate on the session, thenexcelcli session close --save)ExcelMcp.McpServer- Model Context Protocol tools for AI assistantsExcelMcp.Generators*- Source generators that produce CLI commands and MCP tools directly from Core interfaces — you do not hand-write CLI verb registration or MCP tool schemas
Core Commands use the batch API and let exceptions propagate — never wrap batch.Execute() in a try-catch that returns an error result:
public DataType MyOperation(IExcelBatch batch, string arg1)
{
return batch.Execute((ctx, ct) =>
{
dynamic? item = null;
try
{
item = ctx.Book.SomeObject;
// ... operation logic ...
return someData;
}
finally
{
ComUtilities.Release(ref item!); // COM cleanup only — no catch block here
}
});
// batch.Execute() catches exceptions via TaskCompletionSource and
// returns OperationResult { Success = false, ErrorMessage } automatically
}- Always use the batch API - Never manage Excel lifecycle manually
- Excel uses 1-based indexing -
collection.Item(1)is the first element - Never suppress exceptions with a catch block that returns
Success = false— letbatch.Execute()handle it Success = truemust never coexist with a non-emptyErrorMessage- COM objects are released only in
finallyblocks, never swallowed in emptycatchblocks
- Late binding with dynamic types for COM interop
- Proper error handling - Catch
COMExceptionwhere specific handling is needed; otherwise let exceptions propagate - Resource cleanup - Batch API handles COM object lifecycle automatically; release ad-hoc
dynamicCOM objects yourself infinally - Input validation - Check file existence and argument validity early
ExcelMcp uses integration tests only — no unit tests, since COM interop bugs (STA threading, leaks, type conversion) only manifest against a real Excel instance. Follow TDD: write a failing test first, watch it fail, then implement.
# Surgical, feature-scoped testing (2-5 minutes) — always prefer this over the full suite
dotnet test --filter "Feature=PowerQuery&RunType!=OnDemand"
# Full non-VBA suite (10-15 minutes) — only when you need broad confidence
dotnet test --filter "Category=Integration&RunType!=OnDemand&Feature!=VBA&Feature!=VBATrust"
# Session/batch changes require the slower OnDemand suite too
dotnet test --filter "RunType=OnDemand"Before submitting a PR:
- Tests pass for the feature(s) you changed
- Excel process cleanup verified - no
excel.exeremains after tests finish - Error conditions tested (missing files, invalid arguments, etc.)
- Build has zero warnings
- Pre-commit hook passes (all 14 gates)
New operations are added to the Core interface/implementation; CLI commands and MCP tool schemas are then generated automatically — you don't hand-write CLI arg parsing or MCP tool registration.
- Add the method to the relevant Core interface (e.g.
Commands/Sheet/ISheetCommands.cs), with XML doc comments (these become the MCP tool/parameter descriptions). - Implement it in the corresponding partial class (e.g.
SheetCommands.Lifecycle.cs), following the batch-API pattern above. - Build the solution - the source generators (
ExcelMcp.Generators,ExcelMcp.Generators.CLI) produce the CLI verb and MCP tool automatically from the interface. - Add integration tests for the new operation (TDD: write them first).
- Update
FEATURES.mdwith the new operation and its updated operation count —scripts/check-doc-counts.ps1enforces that documented counts match the code.
- Code builds with zero warnings
- Feature-scoped tests pass (
dotnet test --filter "Feature=<name>&RunType!=OnDemand") - Excel processes clean up properly
- Added appropriate error handling (no suppressed exceptions)
- Updated
FEATURES.md/ relevant docs if the operation count or behavior changed - Pre-commit hook passes locally
## Summary
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
- [ ] Tested manually with Excel files
- [ ] Verified Excel process cleanup
- [ ] Tested error conditions
- [ ] VBA script execution tested (if applicable)
- [ ] No build warnings
## Checklist
- [ ] Code follows project conventions
- [ ] Self-review completed
- [ ] Updated documentation as needed// Success (green checkmark)
AnsiConsole.MarkupLine($"[green]✓[/] Operation succeeded");
// Error (red)
AnsiConsole.MarkupLine($"[red]Error:[/] {message.EscapeMarkup()}");
// Warning (yellow)
AnsiConsole.MarkupLine($"[yellow]Note:[/] {message}");
// Info/debug (dim)
AnsiConsole.MarkupLine($"[dim]{message}[/]");
// Headers (cyan)
AnsiConsole.MarkupLine($"[cyan]{title}[/]");- Tables for structured data (query lists, sheet lists)
- Panels for code blocks (M code display)
- Progress indicators for long operations
- Clear error messages with actionable guidance
When reporting bugs, please include:
- Excel version and Windows version
- Command used and arguments
- Expected behavior vs actual behavior
- Sample Excel file (if possible)
- Error messages (full text)
Great feature requests include:
- Use case description - Why is this needed?
- Proposed command syntax - How should it work?
- Excel operations involved - What APIs would be used?
- Target users - Coding agents? Direct users?
- Excel VBA Object Model Reference
- Power Query M Language Reference
- Spectre.Console Documentation
- .NET COM Interop Guide
- NuGet Publishing Guide - Complete guide for publishing all packages with OIDC trusted publishing
bug- Something isn't workingenhancement- New feature or improvementdocumentation- Documentation improvementsgood first issue- Good for newcomershelp wanted- Extra attention neededexcel-com- Excel COM automation issuespower-query- Power Query specificcoding-agent- Coding agent related
Thank you for contributing to Sbroenne.ExcelMcp! Together we're making Excel automation more accessible to coding agents and developers worldwide. 🚀