foretop charter — MCP capability drift scanner
Review every MCP capability before it expands.
Charter turns committed MCP client configuration into a deterministic lock file and shows when a pull request adds a server or expands access.
Available now · Apache-2.0
What it checks
A bounded scanner with explicit evidence and an honest unknown state.
Inventory committed MCP servers
Read project-level Claude Code, Cursor and VS Code configuration, recording transports, commands, endpoints, and argument count without retaining argument text.
Record references, never values
Capture the names and paths of credential-referencing environment variables and headers without opening the secrets behind them.
Enumerate only when asked
Static parsing is the default, and classifies a known server package from a registry that cites its sources. Optional enumeration calls a server's real tools/list: on Linux a stdio server launches inside fail-closed Bubblewrap isolation, while a remote one is contacted over the network and needs no sandbox.
Use it locally or as a CI gate
Start report-only
Add --base origin/main to fail when a server or capability expands relative to the merge base. Without --enumerate, the comparison intentionally detects server-level drift only.
One result, several renderers
Choose table, Markdown, JSON, SARIF, annotations, and triage JSON without changing what the scan concluded.
Annotate the pull request
The public repository includes a composite GitHub Action that emits annotations, maintains one summary comment, and preserves the CLI's exit code.
Trust boundary
What leaves the machine?
Static scans are local. Schema v4 structurally excludes command argument text from locks and reports instead of inspecting or hashing it. --enumerate is an opt-in with two shapes. A stdio server is launched on Linux with a read-only repository, isolated home and temporary storage, a sanitized environment, and no network; Charter refuses to launch when Bubblewrap cannot establish that boundary. A remote server is contacted over the network instead, running nothing locally and sending no credentials, so an endpoint requiring authentication refuses and that refusal is reported rather than hidden.
What is outside today's boundary?
- Only project-level Claude Code, Cursor and VS Code MCP configuration files are scanned, at the repository root.
- Enumerating a stdio server requires Linux and Bubblewrap. Remote servers are contacted over the network instead and need neither.
- OAuth is not implemented, so an endpoint requiring it reports that rather than its tools. A server package outside the bundled registry stays unknown.
- Capability-level drift needs comparable enumeration data on both revisions.
Run it on yours
Install the published package, scan the current directory, and inspect every result before deciding whether to gate CI.