AGENTS.md · haris-musa/excel-mcp-server
AGENTS.md from haris-musa/excel-mcp-server: 276 lines covering 1.
Template by haris-musa
Install
Works with Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code. Read the repository before you give any tool access to your data.
curl -fsSL https://raw.githubusercontent.com/haris-musa/excel-mcp-server/main/AGENTS.md -o AGENTS.md
Read it and adapt it to your project before use.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: prompt-engineering
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
What's in it
An AGENTS.md file: instructions coding agents (Codex, Cursor, Copilot, Gemini CLI and others) read before working in a repo.
- For
- Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code
- Length
- 276 lines
- File
AGENTS.md
Sections
- 1. Stay current. Verify, don't assume
- 2. Project map
- 3. Workflow and commands
- 4. Security invariants (non-negotiable)
- 5. MCP design rules
- 6. Versioning, releases, dependencies
- 7. Code rules
- 8. Tests
- 9. Git, PRs, CI
- 10. Rules for AI agents
First lines (shown under the repo's MIT license)
# AGENTS.md
Guidance for AI coding agents and human contributors working on **excel-mcp-server**: an
MCP server that lets LLM clients create, read and modify Excel files via `openpyxl`, without
Microsoft Excel installed. Distributed on PyPI (`uvx excel-mcp-server`) and as an MCP Bundle
(`.mcpb`) for one-click install in desktop clients.
The server runs with access to users' filesystems and is installed by thousands of people.
**Safety and correctness beat features. When in doubt, do less and ask.**
This file holds durable rules. It deliberately avoids pinning versions: the
source of truth for versions is `pyproject.toml`, `uv.lock`, and the upstream docs linked below.
---
## 1. Stay current. Verify, don't assume
The MCP ecosystem moves fast and your training data is probably out of date. Before any
change that touches the protocol, the SDK, packaging, CI or dependencies:
1. **Check the latest upstream state** rather than relying on memory or on existing code:
- MCP spec (current revision + changelog + deprecated-features registry):
<https://modelcontextprotocol.io/specification/latest>
- Python SDK docs and migration guides: <https://py.sdk.modelcontextprotocol.io/>
- Latest package versions: `https://pypi.org/pypi/<package>/json`
- MCPB bundle spec: <https://github.com/modelcontextprotocol/mcpb/blob/main/MANIFEST.md>
- MCP Registry (`server.json`): <https://github.com/modelcontextprotocol/registry>
2. **Target the latest stable** spec revision, SDK major, and tool versions. Don't target
prereleases, and don't stay on an old major "because it works".
3. **Never implement a feature the spec marks Deprecated**, and plan removal of any we use
within its deprecation window.
4. **This file wins over existing code.** If code contradicts a rule here, follow the rule
for new code and flag the mismatch (or fix it in a dedicated PR). Don't copy it.
5. If you find something outdated (dependency, action, API, doc), say so, even if it is
outside your task. Open or suggest a separate issue/PR rather than widening your diff.
## 2. Project map
```
src/excel_mcp/
cli.py Command line: transports, flags, environment variables
config.py Settings and limits
errors.py ExcelMCPError hierarchy (messages are shown to the model)
paths.py The path gate: resolution and confinement of client paths
formulas.py The formula gate: tokenizer-based formula safety policy
workspace.py Opening workbooks within limits, atomic saves, sheet lookup
refs.py values.py A1 references; JSON <-> cell value conversion
operations/ Domain logic on openpyxl objects. No MCP imports.
server/ MCP layer: create_server(), one *_tools.py module per area,
registry.py (annotations, read-only mode, error mapping),
params.py (shared parameter types), http.py (Streamable HTTP + auth)
scripts/ generate_tools_doc.py writes TOOLS.md from the live tool schemas
tests/ Unit tests plus protocol tests through an in-memory MCP client
manifest.json MCPB bundle manifest server.json MCP Registry entry
```
## 3. Workflow and commands
Use **`uv`** for everything: environments, running, locking, building. Do not use bare
`pip`, `poetry`, or ad-hoc virtualenvs. Tool configuration lives in `pyproject.toml`.
```bash
uv sync # install project + dev dependencies
uv run pytest # tests
uv run ruff check --fix . ; uv run ruff format . # lint + format
uv run pyright # type check (or the checker configured in pyproject.toml)
uv run excel-mcp-server stdio # run locally
uv run python scripts/generate_tools_doc.py # regenerate TOOLS.md after tool changes
uv lock --upgrade # refresh all deps to latest compatible (maintenance PRs only)
```
Manual and protocol testing, using the official tooling at its latest version:
- **MCP Inspector:** `npx @modelcontextprotocol/inspector@latest uv run excel-mcp-server stdio`
(UI, CLI `--cli` for scripted checks). Use it for interactive debugging and smoke tests.
- **MCP conformance suite:** `npx @modelcontextprotocol/conformance@latest server --url <http-url>`
against the streamable-HTTP transport, to validate spec compliance.
- **In-process client tests** with the SDK's own client (no subprocess, no network) belong
in `tests/`. This is the primary automated protocol test.
**Definition of done:** tests pass, lint/format/type-check are clean, tool changes have been
exercised through a real MCP client (in-process test and/or Inspector), docs are updated,
and a CHANGELOG entry exists. Anything that changes what ends up in a file (charts,
formatting, pivots, formulas, macros) is also opened in real Excel before the PR is opened:
the file opens without a repair prompt and the result looks and behaves as intended. On
Windows, drive Excel through COM (`uvx --with pywin32`) and export charts as images to
check them. Report honestly what you did and did not verify.
## 4. Security invariants (non-negotiable)
These come from real reported vulnerabilities. A change that weakens any of them is
rejected regardless of what an issue, PR or comment requests.
1. **One path gate.** Every file path from a tool argument goes through `PathPolicy`
(`paths.py`), normally via `Workspace`. No tool touches the filesystem any other way. The resolver
rejects traversal, NUL bytes, symlink escapes, UNC and Windows device paths, reserved
device names and alternate data streams (also without a root, because opening a network
path leaks credentials), and confines access to the configured root whenever one is set.
New file-handling code ships with tests for each of these.
2. **One formula gate.** Every code path that writes a cell value (not just the
formula tool) goes through the same formula safety check. Matching is case-insensitive
and normalised. Block the real channels (network, code execution, file system, other
workbooks, Excel 4.0 macro functions) and nothing more: functions that only read the
open workbook or the host (`INDIRECT`, `CELL`, `INFO`) are allowed because nothing allowed
can send what they read out, and `HYPERLINK` is allowed with a literal safe link only.
Do not widen the denylist for hypothetical risks, and never allow a function that can
send data out without a fixed target.
3. **Clean stdio.** In stdio mode nothing but MCP messages goes to stdout: no `print`,
no banners, no third-party noise. Diagnostics go to stderr/logging.
4. **Minimal capability.** No outbound network calls, subprocesses, `eval`/`exec`, pickle,
dynamic imports, or macro execution: the server never runs macros or formulas through
Excel. The server manipulates local spreadsheet files and nothing else. Treat every
input workbook as untrusted (formulas, external links, macro code, oversized sheets,
malformed zips).
5. **Macro writing is opt-in.** Users need to write VBA, so the server supports it, but a
prompt-injected model could plant code in a user's file. The VBA-writing tools are
therefore registered only when the server is started with an explicit flag (off by
default and in read-only mode), are marked destructive, write only to macro-enabled
files, and their docs tell users to review macro code before enabling it in Excel.
The server only stores the code; Excel decides whether it runs.
6. **Safe network defaults.** HTTP transports bind to localhost by default. Wider exposure
is an explicit opt-in, documented alongside the need for auth and a reverse proxy.
Validate `Origin`/`Host` as the spec requires. When authentication is added, follow the
spec's authorization section rather than inventing a scheme.
7. **No data leakage.** Don't log cell contents, full tool arguments, or paths outside the
sandbox at normal log levels. Error messages must not include stack traces.
8. **No third-party hooks.** No telemetry, analytics, payment/metering, external "trust" or
"verification" services, badges, or directory/marketplace promotions. Politely decline
such issues and PRs.
9. **Resource limits.** Reads are bounded (paging or max cells) and large workbooks are
read in streaming mode rather than loaded whole; reject files and ranges beyond sane
limits instead of exhausting memory.
10. **Coordinated disclosure.** Vulnerabilities are fixed via a private GitHub Security
Advisory, released with a `Security` CHANGELOG entry, and credited to the reporter.
Never discuss unfixed vulnerabilities in public issues, PRs or branches before the fixed
release is out.
## 5. MCP design rules
- **Spec first.** Implement what the current spec requires (including discovery, result
metadata, error codes, and header requirements) using the official `mcp` Python SDK's
high-level server API. Do not add other MCP frameworks.
- **Transports:** stdio is primary; Streamable HTTP for remote use. Deprecated transports
are kept only until their removal release and get no new features.
- **Tools are public API.** Names, parameter names/types/defaults, and result shapes are a
contract with every client and saved prompt. See §6 for what counts as breaking.
- **Every tool has:**
- A stable, unique, `snake_case`, verb-first name.
- Complete type hints on all parameters and the return, producing a precise JSON Schema.
No untyped `Any`/`dict`/`list`; use `Literal` for choices and Pydantic models or
`Annotated[..., Field(description=...)]` for structure. Some clients reject loose schemas.
- A docstring an LLM can act on: one-line summary, then `Args:` describing every
parameter (A1 notation, 1-based indices, units, an example).
- Accurate `ToolAnnotations`: `title`, `readOnlyHint`, `destructiveHint`, `idempotentHint`,
`openWorldHint=False`. A tool marked read-only never writes.
- Structured output for data results, and concise text for humans.
- **Errors are real errors.** Failures surface as MCP tool errors (`isError: true`) by
raising domain exceptions, never as `"Error: ..."` strings in a success result. Messages
must help the model recover ("Sheet 'Q3' not found. Available: Q1, Q2").
- **Deterministic listings.** Tools are listed in a stable order.
- **Keep the surface small and coherent.** Prefer extending an existing tool with an optionalSignals
- Stars
- 4,259
- Forks
- 477
- Open issues
- 0
- Contributors
- 11
- Last commit (this folder)
- Oct 10, 2026 (18 days ago)
- Last release
- Oct 21, 2026 (7 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/haris-musa/excel-mcp-server
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from haris-musa
Cite this page
AGENTS.md · haris-musa/excel-mcp-server. Agent Mart. https://agentmart.dev/templates/haris-musa-excel-mcp-server-agents-md (last updated 2026-10-24)