Contributions are welcome. Keep changes focused and the scope small. Stability guarantees are documented in STABILITY.md.
git clone https://github.com/P4ST4S/mcp-audit
cd mcp-audit
go build ./...
go test ./...go build ./...passesgo vet ./...passesgo test -race ./...passesgofmthas been run on changed Go files- Changes are scoped to one concern per PR
These conventions are recommended, not strictly enforced by CI. The PR template at .github/pull_request_template.md prompts for the right sections automatically.
One PR addresses one concern. If a change touches storage and adds a new policy feature, split it into two PRs. A clean diff is easier to review, easier to revert if something breaks, and easier to credit if part of it lands.
If the issue you're addressing has multiple parts (see #4117 on modelcontextprotocol/servers as an example), open a comment on the issue first describing how you intend to split the work. This avoids two contributors stepping on each other.
Suggested format: type/short-description-issue (the issue number is optional).
feat/policy-engine-15
fix/storage-race-42
docs/cursor-example-19
refactor/storage-tests
chore/release-1.0.0
Use the same type you'd use in your commit message. The hyphen-separated description should be enough that someone scanning your fork's branch list can tell what you were working on.
Follow Conventional Commits. The type is required, the scope is optional but encouraged when it disambiguates.
| Type | Use for |
|---|---|
feat |
New user-visible feature (added config key, new flag, new metric, etc.) |
fix |
Bug fix (also use for security fixes; mention CVE if any) |
docs |
Documentation only (README, CHANGELOG, this file, etc.) |
test |
Test additions or improvements with no production code change |
refactor |
Internal restructuring with no behavior change |
chore |
Release prep, dependency bumps, repo housekeeping |
build |
Build pipeline, CI, GoReleaser, Dockerfile changes |
perf |
Performance improvement with no behavior change |
Examples from the project history:
fix(memory): default persistence path to user data directory
feat: add HTTP upstream retry metrics and logging
test(storage): add unit tests for storage backends
chore: release v1.0.0
The commit message body is encouraged for non-trivial changes: explain the why, link the issue, and call out any risk. The CHANGELOG entry is a separate concern.
Update CHANGELOG.md under [Unreleased] when your change is user-visible. Internal refactors, tests, and CI changes do not require a changelog entry.
Categories:
### Addedfor new features### Changedfor changes in existing behavior### Fixedfor bug fixes### Deprecatedfor soon-to-be-removed features (must announce at least one MINOR release ahead, per STABILITY.md)### Removedfor removed features (requires MAJOR bump)### Securityfor vulnerabilities
If you're not sure whether your change needs an entry, ask in the PR. Easier to add one than to debate later.
Anything in the stable surface (config keys, CLI flags, audit JSON schema, signed field set, Prometheus metric names, OTLP mcp_audit.* attributes, dashboard API endpoints, JSON-RPC error codes) is contract-stable per STABILITY.md.
If your PR touches any of these:
- Call it out in the PR description under "Stability impact"
- Additive changes (new fields, new flags, new metrics) are MINOR-compatible
- Removals, renames, or behavior changes need a deprecation cycle and eventually a MAJOR version bump
When in doubt, flag it in the PR description and the reviewer will help triage.
PRs are merged with a merge commit, not squashed. This preserves your individual commits in the history, which makes it easier to credit step-by-step work and to bisect later if something breaks.
Consequently: keep your commits clean before requesting review. If you ended up with a wip, fix typo, oops, and then actually fix it sequence, rebase them into meaningful commits before pushing the final round.
- Tag the maintainer (
@P4ST4S) once when the PR is ready for review. Avoid re-pinging within 7 days; review backlog moves slowly on solo-maintained projects. - If a reviewer requests changes, address each point or explain why you disagree. "Why" is welcome — silent dismissal isn't.
- If your PR depends on another open PR, say so in the description and link it. PR 2 of a sequence shouldn't be opened before PR 1 is reviewed.
- Allow edits from maintainers (the checkbox on the PR creation form). Lets the reviewer fix a typo or rebase without ping-pong.
Check issues labeled good first issue
for approachable starting points.
For a narrative view of how these packages fit together at runtime, read ARCHITECTURE.md.
cmd/mcp-audit/- CLI entry point and config loadinginternal/proxy/- stdio and HTTP MCP proxiesinternal/audit/- entry types, signing, JSONL and SQLite storage backendsinternal/policy/- synchronous allow/deny policy engineinternal/middleware/- rate limiting and PII redactioninternal/metrics/- Prometheus metrics recorder and endpointinternal/otel/- OTLP/HTTP JSON trace exporterinternal/dashboard/- read-only HTTP dashboard and JSON API
- Zero accidental message drop - the proxy must not drop or modify JSON-RPC messages because auditing or interception failed. If inspection fails, forward as-is and log the error separately. Intentional policy enforcement, such as rate limiting, must return a proper JSON-RPC error.
- Minimal dependencies - prefer stdlib over new packages.
- Errors with context - wrap errors:
fmt.Errorf("component: action: %w", err) - Thread safety - all storage writes must be safe for concurrent use.
For bugs, include Go version, OS, transport mode (stdio/http), and the minimal config to reproduce. For features, check the existing issues first.
For open-ended questions, design conversations, or "would it make sense to..." ideas, prefer Discussions over Issues.
Please do not open public issues for security vulnerabilities. Follow the private reporting process in SECURITY.md.
By contributing you agree your changes are licensed under Apache-2.0.