Contributing to mcp-methods¶
Development Setup¶
# Clone and set up
git clone https://github.com/kkollsga/mcp-methods.git
cd mcp-methods
python3 -m venv .venv
source .venv/bin/activate
pip install maturin pytest ruff
# Build the Python wheel + install editably into the venv
make dev # cdylib only, no bundled binary on PATH
# OR
make dev-with-bin # also build + bundle the mcp-server binary
# Run tests
make test # Python (pytest)
make test-rust # Rust library only
make test-rust-all # Rust workspace (mcp-methods + mcp-server)
After make dev-with-bin, which mcp-server should resolve to a
binary inside your venv’s bin/ directory.
Project Structure¶
crates/
mcp-methods/ # Pure Rust library — zero pyo3 in dep tree
src/
lib.rs # Public module list
cache.rs, compact.rs, files.rs, github.rs, grep/, html.rs,
json_grep.rs, list_dir.rs # primitives (always available)
server/ # MCP server framework (feature = "server")
manifest.rs # YAML manifest parser + Manifest::to_json
workspace.rs # github + local workspace, watch hook
server.rs # McpServer, ServerOptions
env.rs, runtime.rs, source.rs, watch.rs
tests/
deployed_manifests.rs # regression suite — production YAML shapes
mcp-methods-py/ # PyO3 binding crate — builds the Python wheel
src/lib.rs # #[pymodule] re-exporting the surface
mcp-server/ # standalone CLI binary
src/main.rs # clap + tokio + McpServer::serve
python/mcp_methods/ # Python package
__init__.py # imports from _mcp_methods (the cdylib)
_cli.py # console-script launcher for mcp-server
fastmcp/ # FastMCP helper module
_bin/ # bundled binary (gitignored, built by wheel)
tests/ # Python tests (pytest)
docs/ # Sphinx docs site (Read the Docs)
examples/ # Runnable example consumers
CHANGELOG.md # release notes — high quality, please match
Cargo.toml # workspace root (virtual manifest)
pyproject.toml # maturin config + Python packaging
The pre-commit hook¶
Every commit runs four checks (see .git/hooks/pre-commit):
cargo fmt— must be cleancargo clippy --workspace -- -D warnings— no clippy warningsruff format --check— Python formatruff check— Python lints
If a commit fails the hook, fix the issue and recommit. Don’t use
--no-verify — the hook catches real problems.
Tests¶
Layer |
Command |
What it covers |
|---|---|---|
Rust library |
|
The framework, primitives, manifest parser |
Rust binary |
|
The CLI argument-handling smoke tests |
Python wheel |
|
The pyo3 surface end-to-end |
Deployed manifests |
|
The 5 production YAML shapes still parse |
Total: ~107 Rust tests, ~176 Python tests. All must pass for any PR.
When adding a manifest field¶
The Manifest::to_json() shape is pinned by the
to_json_shape_is_stable test in crates/mcp-methods/src/server/manifest.rs.
If you add a field:
Add the field to the
Manifeststruct.Add the parser logic to
build()/build_*in the same file.Add it to
Manifest::to_json().Update
ALLOWED_TOP_KEYS(or the relevant sub-list).Update the snapshot test literal.
Add a fixture to
deployed_manifests.rsif the field shows up in a production YAML.
This sequence is non-negotiable. The snapshot test is the JSON contract for downstream FFI consumers (kglite, etc.) — silently dropping a field is a worse failure mode than a noisy test failure.
Release cadence¶
We ship patch releases (0.3.X) liberally — additive changes are
non-breaking and downstream consumers handle them transparently.
Bump |
When |
|---|---|
Patch (0.3.30 → 0.3.31) |
Bug fixes, new advisory trust gates, additive manifest fields, JSON-shape field additions |
Minor (0.3.X → 0.4.0) |
Breaking changes to the Rust API, manifest field renames or removals, breaking JSON shape changes |
Major (0.3 → 1.0) |
API frozen, breaking changes telegraphed in advance |
CHANGELOG entries are required. Match the prose quality of recent entries — explain the why, not just the what. Multi-day arcs (0.3.26 through 0.3.30) get cross-referenced so readers can follow the architectural evolution.
Distribution¶
Three artifacts ship from this repo:
pip install mcp-methods— Python library + bundledmcp-serverCLI on PATH (3 abi3 wheels per OS).cargo add mcp-methods— pure-Rust library, zero pyo3 in the dep tree.crates/mcp-server/source — workspace member, NOT published to crates.io. Downstream Rust users who want the binary without pip runcargo install --git https://github.com/kkollsga/mcp-methods mcp-server.
The Python wheel and the Rust library publish in lockstep (same
version number, same release commit). The version is the
single source of truth in crates/mcp-methods/Cargo.toml.
Commit messages¶
Use this format:
type(scope): short description
Optional longer explanation.
Co-Authored-By: …
Type |
When |
|---|---|
|
New feature or capability |
|
Bug fix |
|
Restructure without behavior change |
|
Documentation only |
|
Build, CI, dependency updates |
|
Adding/updating tests |
Scope is the affected crate or area (mcp-server, manifest,
workspace, docs, etc.). Examples:
feat(0.3.29): add trust.allow_query_preprocessor advisory gate
fix(workspace): set_root_dir no longer clobbers active_repo_path
refactor(0.3.26): split into pure-Rust library + PyO3 bindings
Issues and PRs¶
File issues at https://github.com/kkollsga/mcp-methods/issues
Open PRs against
mainOne concept per PR — easier to review and revert
For downstream coordination (kglite + similar consumers), the inbox/
directory at the repo root tracks per-day correspondence threads. If
your change affects a downstream consumer, drop a note there.
License¶
MIT. Contributions are accepted under the same license.