mcp-context-budget 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. mcp_context_budget-0.4.0/LICENSE +21 -0
  2. mcp_context_budget-0.4.0/PKG-INFO +290 -0
  3. mcp_context_budget-0.4.0/README.md +276 -0
  4. mcp_context_budget-0.4.0/mcp_context_budget/__init__.py +5 -0
  5. mcp_context_budget-0.4.0/mcp_context_budget/__main__.py +6 -0
  6. mcp_context_budget-0.4.0/mcp_context_budget/budget.py +110 -0
  7. mcp_context_budget-0.4.0/mcp_context_budget/cli.py +512 -0
  8. mcp_context_budget-0.4.0/mcp_context_budget/compress.py +156 -0
  9. mcp_context_budget-0.4.0/mcp_context_budget/config_audit.py +173 -0
  10. mcp_context_budget-0.4.0/mcp_context_budget/config_edit.py +564 -0
  11. mcp_context_budget-0.4.0/mcp_context_budget/demo.py +119 -0
  12. mcp_context_budget-0.4.0/mcp_context_budget/live_stdio.py +623 -0
  13. mcp_context_budget-0.4.0/mcp_context_budget/loaders.py +189 -0
  14. mcp_context_budget-0.4.0/mcp_context_budget/models.py +67 -0
  15. mcp_context_budget-0.4.0/mcp_context_budget/reporting.py +71 -0
  16. mcp_context_budget-0.4.0/mcp_context_budget/selector.py +68 -0
  17. mcp_context_budget-0.4.0/mcp_context_budget/semantic.py +314 -0
  18. mcp_context_budget-0.4.0/mcp_context_budget/tokens.py +12 -0
  19. mcp_context_budget-0.4.0/mcp_context_budget.egg-info/PKG-INFO +290 -0
  20. mcp_context_budget-0.4.0/mcp_context_budget.egg-info/SOURCES.txt +32 -0
  21. mcp_context_budget-0.4.0/mcp_context_budget.egg-info/dependency_links.txt +1 -0
  22. mcp_context_budget-0.4.0/mcp_context_budget.egg-info/entry_points.txt +2 -0
  23. mcp_context_budget-0.4.0/mcp_context_budget.egg-info/requires.txt +4 -0
  24. mcp_context_budget-0.4.0/mcp_context_budget.egg-info/top_level.txt +1 -0
  25. mcp_context_budget-0.4.0/pyproject.toml +37 -0
  26. mcp_context_budget-0.4.0/setup.cfg +4 -0
  27. mcp_context_budget-0.4.0/tests/test_cli.py +95 -0
  28. mcp_context_budget-0.4.0/tests/test_compress.py +98 -0
  29. mcp_context_budget-0.4.0/tests/test_config_audit.py +117 -0
  30. mcp_context_budget-0.4.0/tests/test_config_contract.py +239 -0
  31. mcp_context_budget-0.4.0/tests/test_config_edit.py +140 -0
  32. mcp_context_budget-0.4.0/tests/test_core.py +104 -0
  33. mcp_context_budget-0.4.0/tests/test_live_stdio.py +181 -0
  34. mcp_context_budget-0.4.0/tests/test_semantic.py +338 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dan Mercede
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,290 @@
1
+ Metadata-Version: 2.4
2
+ Name: mcp-context-budget
3
+ Version: 0.4.0
4
+ Summary: Local-first MCP context budget and tool-selection verifier
5
+ Author-email: Dan Mercede <dan@danmercede.com>
6
+ License: MIT
7
+ Requires-Python: >=3.11
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Provides-Extra: dev
11
+ Requires-Dist: pytest>=8.0; extra == "dev"
12
+ Requires-Dist: ruff>=0.6; extra == "dev"
13
+ Dynamic: license-file
14
+
15
+ # mcp-context-budget
16
+
17
+ Local-first MCP context budget and tool-selection verifier for agentic coding
18
+ environments.
19
+
20
+ MCP servers can load enough tool schema and response data to burn a large
21
+ fraction of an agent context window before useful work starts. This tool gives
22
+ developers a repeatable budget gate:
23
+
24
+ - scan MCP config or `tools/list` fixtures
25
+ - estimate schema and response-token cost
26
+ - select a smaller task-relevant tool set with deterministic SQLite FTS5/BM25
27
+ - optionally prove semantic tool selection from fixture or Ollama embeddings
28
+ - write a lockfile for CI
29
+ - fail builds when schema or response budgets regress
30
+ - compress recorded response fixtures under a response budget
31
+ - apply selected-tool locks back to caller-owned MCP config files
32
+ - opt into local stdio `tools/list` introspection for command-discovered servers
33
+ - audit MCP configs for plaintext secret exposure without printing values
34
+ - prove the spine with a Docker demo
35
+
36
+ No private Orion services are required. The core CLI has no external runtime
37
+ service dependency. Semantic selection can optionally call Ollama only when the
38
+ `--embedding-backend ollama` flag is explicitly selected. Live stdio
39
+ introspection can optionally start a caller-owned local MCP command only when
40
+ `--allow-start` is explicitly selected.
41
+
42
+ ## Install
43
+
44
+ ```bash
45
+ python3.11 -m venv .venv
46
+ . .venv/bin/activate
47
+ pip install -e '.[dev]'
48
+ ```
49
+
50
+ ## Quick Demo
51
+
52
+ ```bash
53
+ mcp-context-budget demo \
54
+ --task "triage a GitHub issue and update one ticket" \
55
+ --max-tools 8 \
56
+ --max-schema-tokens 6000 \
57
+ --max-response-tokens 4000
58
+ ```
59
+
60
+ Expected spine proof:
61
+
62
+ ```text
63
+ DEMO_CATALOG_SERVERS=5
64
+ DEMO_CATALOG_TOOLS=120
65
+ BEFORE_SCHEMA_TOKENS=<large>
66
+ SELECTED_TOOLS=<8-or-less>
67
+ AFTER_SCHEMA_TOKENS=<cap-or-less>
68
+ OVERSIZED_RESPONSE_FIXTURE=flagged
69
+ BUDGET_STATUS=PASS
70
+ ```
71
+
72
+ ## Commands
73
+
74
+ ```bash
75
+ mcp-context-budget scan --tool-list fixtures/demo-tools.json --out mcp-budget.report.md --lock-out mcp-budget.lock.json
76
+ mcp-context-budget select --tool-list fixtures/demo-tools.json --task "triage a GitHub issue" --max-tools 8 --max-schema-tokens 6000 --out-lock mcp-budget.lock.json
77
+ mcp-context-budget semantic-select --tool-list fixtures/demo-tools.json --task "triage a GitHub issue" --embedding-backend fixture --embedding-file embeddings.json --out-lock mcp-budget.lock.json
78
+ mcp-context-budget check --lock mcp-budget.lock.json --max-schema-tokens 6000 --max-response-tokens 4000
79
+ mcp-context-budget compress-responses --fixtures responses/ --max-response-tokens 4000 --out-dir compressed-responses --report compression-report.json
80
+ mcp-context-budget config-apply --config mcp.json --lock mcp-budget.lock.json --dry-run --patch-out mcp-config.patch.json
81
+ mcp-context-budget config-audit --config mcp.json --json-out mcp-config-audit.json --fail-on high
82
+ mcp-context-budget export --lock mcp-budget.lock.json --format sarif --out mcp-budget.sarif
83
+ ```
84
+
85
+ `scan --config` supports Claude/Cursor/Codex-style JSON with an `mcpServers`
86
+ object. Server entries may include `toolsListPath` to point at a recorded
87
+ `tools/list` JSON fixture. Server entries may also include `stdioFraming`
88
+ (`auto`, `json-lines`, or `content-length`) when a local stdio server needs a
89
+ fixed transport framing. Environment values are redacted in reports.
90
+
91
+ `--allow-start` is intentionally conservative. It is never implied by default,
92
+ never required for static `toolsListPath` or inline-tool configs, and never
93
+ starts a hosted service. When explicitly selected, the tool starts the
94
+ caller-owned local stdio command as argv with `shell=False`, sends MCP
95
+ `initialize` and `tools/list`, enforces timeout and stdio-byte caps, redacts env
96
+ metadata, and exits the process after listing tools. The default
97
+ `--stdio-framing auto` prefers the current MCP SDK JSON-lines stdio transport
98
+ and falls back to the legacy `Content-Length` fixture transport; pass
99
+ `--stdio-framing json-lines` or `--stdio-framing content-length` to force one.
100
+
101
+ For command-discovered servers that need to become enforceable by
102
+ `config-apply`, combine `--allow-start` with `--materialize-tools-list`:
103
+
104
+ ```bash
105
+ mcp-context-budget config-apply \
106
+ --config mcp.json \
107
+ --lock mcp-budget.lock.json \
108
+ --write \
109
+ --allow-start \
110
+ --start-timeout-seconds 2 \
111
+ --max-stdio-bytes 65536 \
112
+ --stdio-framing auto \
113
+ --materialize-tools-list materialized-tools/
114
+ ```
115
+
116
+ This writes a local `toolsListPath` sidecar for the discovered tools, applies
117
+ the selected-tool lock there, and leaves later `scan`/`select` runs static again.
118
+
119
+ ### Semantic Selection
120
+
121
+ `semantic-select` keeps the v0.1 lockfile shape but ranks tools by embedding
122
+ similarity before applying `--max-tools` and `--max-schema-tokens`.
123
+
124
+ Fixture mode is deterministic and requires no service:
125
+
126
+ ```bash
127
+ mcp-context-budget semantic-select \
128
+ --tool-list tools.json \
129
+ --task "diagnose bug report" \
130
+ --embedding-backend fixture \
131
+ --embedding-file embeddings.json \
132
+ --out-lock semantic.lock.json
133
+ ```
134
+
135
+ The fixture file must contain:
136
+
137
+ ```json
138
+ {
139
+ "queries": {"diagnose bug report": [1.0, 0.0]},
140
+ "tools": {"github/get_issue": [1.0, 0.0]}
141
+ }
142
+ ```
143
+
144
+ Ollama mode uses stdlib HTTP and adds no Python package dependency:
145
+
146
+ ```bash
147
+ mcp-context-budget semantic-select \
148
+ --tool-list tools.json \
149
+ --task "diagnose bug report" \
150
+ --embedding-backend ollama \
151
+ --ollama-url http://localhost:11434 \
152
+ --ollama-model nomic-embed-text
153
+ ```
154
+
155
+ ### Response Fixture Compression
156
+
157
+ `compress-responses` reads one response fixture or a directory of `*.json`
158
+ fixtures, writes compressed copies, and emits a JSON report.
159
+
160
+ ```bash
161
+ mcp-context-budget compress-responses \
162
+ --fixtures responses/ \
163
+ --max-response-tokens 4000 \
164
+ --out-dir compressed-responses \
165
+ --report compression-report.json
166
+ ```
167
+
168
+ The v0.2 strategy is deterministic extractive compression. It preserves common
169
+ identifier fields and writes a `summary` when large body fields need to be cut.
170
+
171
+ ### Config Apply
172
+
173
+ `config-apply` turns a selected-tool lock into a safe local MCP config patch.
174
+ Dry-run is the default posture; `--write` is required before the config file is
175
+ changed, and write mode creates a backup.
176
+
177
+ ```bash
178
+ mcp-context-budget config-apply \
179
+ --config mcp.json \
180
+ --lock mcp-budget.lock.json \
181
+ --mode disable-unselected \
182
+ --dry-run \
183
+ --patch-out mcp-config.patch.json
184
+
185
+ mcp-context-budget config-apply \
186
+ --config mcp.json \
187
+ --lock mcp-budget.lock.json \
188
+ --mode disable-unselected \
189
+ --write \
190
+ --backup-dir backups/
191
+ ```
192
+
193
+ Reports redact environment values.
194
+
195
+ The apply contract is enforced, not advisory:
196
+
197
+ - **Inline and `toolsListPath` tools are both patched.** A server whose tools
198
+ live in an external `tools/list` JSON has that file patched (and backed up)
199
+ too — not silently skipped.
200
+ - **The lock is bound to the config.** Each lock records a `config_fingerprint`
201
+ of its tool universe; `config-apply` refuses a lock whose fingerprint does not
202
+ match the target config (a foreign/stale lock would otherwise disable every
203
+ tool and still report success). Override with `--allow-fingerprint-mismatch`.
204
+ - **Honest status, never a false PASS.** A command-discovered server (no inline
205
+ `tools`, no `toolsListPath`) cannot be enforced without live startup, so it is
206
+ reported under `not_patchable` and the status is `PARTIAL`, not `PASS`.
207
+ - **Opt-in materialization closes the PARTIAL gap.** With `--allow-start` and
208
+ `--materialize-tools-list`, command-discovered tools are listed through local
209
+ stdio, saved to a caller-owned sidecar, and enforced as a normal
210
+ `toolsListPath` catalog.
211
+ - **Disabling takes effect.** The loader honors `enabled: false`, so a disabled
212
+ tool (or server) drops out of the budget on the next `scan`/`select`.
213
+
214
+ ### Config Secret Audit
215
+
216
+ `config-audit` is a read-only hygiene check for MCP config files. It flags
217
+ high-confidence literal secrets in env values, args, and nested config fields,
218
+ while treating `${TOKEN}` references, `op://...` references, and redacted
219
+ placeholders as safe references.
220
+
221
+ ```bash
222
+ mcp-context-budget config-audit \
223
+ --config mcp.json \
224
+ --json-out mcp-config-audit.json \
225
+ --fail-on high
226
+ ```
227
+
228
+ Reports include the config path, finding path, severity, secret class, length
229
+ bucket, and a short fingerprint. Literal secret values are never printed.
230
+
231
+ ## Docker
232
+
233
+ ```bash
234
+ docker build -t mcp-context-budget:local .
235
+ docker run --rm mcp-context-budget:local demo \
236
+ --task "triage a GitHub issue and update one ticket" \
237
+ --max-tools 8 \
238
+ --max-schema-tokens 6000 \
239
+ --max-response-tokens 4000
240
+ ```
241
+
242
+ The image exposes no service port.
243
+
244
+ v0.2 also includes independent Docker proof commands for the new capabilities:
245
+
246
+ ```bash
247
+ docker run --rm mcp-context-budget:local semantic-demo \
248
+ --task "diagnose bug report" \
249
+ --max-tools 3 \
250
+ --max-schema-tokens 3000
251
+ docker run --rm mcp-context-budget:local compress-demo --max-response-tokens 4000
252
+ docker run --rm mcp-context-budget:local config-demo
253
+ docker run --rm mcp-context-budget:local allow-start-demo --start-timeout-seconds 2 --max-stdio-bytes 65536 --stdio-framing auto
254
+ docker run --rm mcp-context-budget:local semantic-demo --task "diagnose bug report" --max-tools 3 --max-schema-tokens 3000 --embedding-backend fixture
255
+ docker run --rm mcp-context-budget:local prove-parallel-ollama-demo
256
+ docker run --rm mcp-context-budget:local config-audit-demo
257
+ docker run --rm mcp-context-budget:local config-multiserver-demo
258
+ ```
259
+
260
+ Expected v0.3 proof lines:
261
+
262
+ ```text
263
+ LIVE_INTROSPECTION_STATUS=PASS
264
+ AFTER_CONFIG_NOT_PATCHABLE=0
265
+ CONFIG_AUDIT_STATUS=PASS
266
+ CONFIG_AUDIT_SECRET_VALUES_REDACTED=true
267
+ CONFIG_MULTISERVER_STATUS=PASS
268
+ ```
269
+
270
+ ## Out of v0.3
271
+
272
+ ### Locked Out
273
+
274
+ - Live runtime MCP proxy/gateway that intercepts and routes actual tool calls.
275
+ - Browser UI.
276
+ - Organization-wide background scanner.
277
+ - Vendor-specific hosted dashboards.
278
+
279
+ These are not v0.4 commitments; they break the local-first CLI verifier shape.
280
+
281
+ ### Shipped in v0.4
282
+
283
+ - Parallelized Ollama embeddings for `semantic-select` when
284
+ `--embedding-backend ollama` is explicitly selected (fixture backend remains
285
+ the default for CI/docker).
286
+
287
+ ### Deferred to v0.5
288
+
289
+ - Automatic response compression for arbitrary live MCP servers.
290
+ - Broader CLI polish.
@@ -0,0 +1,276 @@
1
+ # mcp-context-budget
2
+
3
+ Local-first MCP context budget and tool-selection verifier for agentic coding
4
+ environments.
5
+
6
+ MCP servers can load enough tool schema and response data to burn a large
7
+ fraction of an agent context window before useful work starts. This tool gives
8
+ developers a repeatable budget gate:
9
+
10
+ - scan MCP config or `tools/list` fixtures
11
+ - estimate schema and response-token cost
12
+ - select a smaller task-relevant tool set with deterministic SQLite FTS5/BM25
13
+ - optionally prove semantic tool selection from fixture or Ollama embeddings
14
+ - write a lockfile for CI
15
+ - fail builds when schema or response budgets regress
16
+ - compress recorded response fixtures under a response budget
17
+ - apply selected-tool locks back to caller-owned MCP config files
18
+ - opt into local stdio `tools/list` introspection for command-discovered servers
19
+ - audit MCP configs for plaintext secret exposure without printing values
20
+ - prove the spine with a Docker demo
21
+
22
+ No private Orion services are required. The core CLI has no external runtime
23
+ service dependency. Semantic selection can optionally call Ollama only when the
24
+ `--embedding-backend ollama` flag is explicitly selected. Live stdio
25
+ introspection can optionally start a caller-owned local MCP command only when
26
+ `--allow-start` is explicitly selected.
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ python3.11 -m venv .venv
32
+ . .venv/bin/activate
33
+ pip install -e '.[dev]'
34
+ ```
35
+
36
+ ## Quick Demo
37
+
38
+ ```bash
39
+ mcp-context-budget demo \
40
+ --task "triage a GitHub issue and update one ticket" \
41
+ --max-tools 8 \
42
+ --max-schema-tokens 6000 \
43
+ --max-response-tokens 4000
44
+ ```
45
+
46
+ Expected spine proof:
47
+
48
+ ```text
49
+ DEMO_CATALOG_SERVERS=5
50
+ DEMO_CATALOG_TOOLS=120
51
+ BEFORE_SCHEMA_TOKENS=<large>
52
+ SELECTED_TOOLS=<8-or-less>
53
+ AFTER_SCHEMA_TOKENS=<cap-or-less>
54
+ OVERSIZED_RESPONSE_FIXTURE=flagged
55
+ BUDGET_STATUS=PASS
56
+ ```
57
+
58
+ ## Commands
59
+
60
+ ```bash
61
+ mcp-context-budget scan --tool-list fixtures/demo-tools.json --out mcp-budget.report.md --lock-out mcp-budget.lock.json
62
+ mcp-context-budget select --tool-list fixtures/demo-tools.json --task "triage a GitHub issue" --max-tools 8 --max-schema-tokens 6000 --out-lock mcp-budget.lock.json
63
+ mcp-context-budget semantic-select --tool-list fixtures/demo-tools.json --task "triage a GitHub issue" --embedding-backend fixture --embedding-file embeddings.json --out-lock mcp-budget.lock.json
64
+ mcp-context-budget check --lock mcp-budget.lock.json --max-schema-tokens 6000 --max-response-tokens 4000
65
+ mcp-context-budget compress-responses --fixtures responses/ --max-response-tokens 4000 --out-dir compressed-responses --report compression-report.json
66
+ mcp-context-budget config-apply --config mcp.json --lock mcp-budget.lock.json --dry-run --patch-out mcp-config.patch.json
67
+ mcp-context-budget config-audit --config mcp.json --json-out mcp-config-audit.json --fail-on high
68
+ mcp-context-budget export --lock mcp-budget.lock.json --format sarif --out mcp-budget.sarif
69
+ ```
70
+
71
+ `scan --config` supports Claude/Cursor/Codex-style JSON with an `mcpServers`
72
+ object. Server entries may include `toolsListPath` to point at a recorded
73
+ `tools/list` JSON fixture. Server entries may also include `stdioFraming`
74
+ (`auto`, `json-lines`, or `content-length`) when a local stdio server needs a
75
+ fixed transport framing. Environment values are redacted in reports.
76
+
77
+ `--allow-start` is intentionally conservative. It is never implied by default,
78
+ never required for static `toolsListPath` or inline-tool configs, and never
79
+ starts a hosted service. When explicitly selected, the tool starts the
80
+ caller-owned local stdio command as argv with `shell=False`, sends MCP
81
+ `initialize` and `tools/list`, enforces timeout and stdio-byte caps, redacts env
82
+ metadata, and exits the process after listing tools. The default
83
+ `--stdio-framing auto` prefers the current MCP SDK JSON-lines stdio transport
84
+ and falls back to the legacy `Content-Length` fixture transport; pass
85
+ `--stdio-framing json-lines` or `--stdio-framing content-length` to force one.
86
+
87
+ For command-discovered servers that need to become enforceable by
88
+ `config-apply`, combine `--allow-start` with `--materialize-tools-list`:
89
+
90
+ ```bash
91
+ mcp-context-budget config-apply \
92
+ --config mcp.json \
93
+ --lock mcp-budget.lock.json \
94
+ --write \
95
+ --allow-start \
96
+ --start-timeout-seconds 2 \
97
+ --max-stdio-bytes 65536 \
98
+ --stdio-framing auto \
99
+ --materialize-tools-list materialized-tools/
100
+ ```
101
+
102
+ This writes a local `toolsListPath` sidecar for the discovered tools, applies
103
+ the selected-tool lock there, and leaves later `scan`/`select` runs static again.
104
+
105
+ ### Semantic Selection
106
+
107
+ `semantic-select` keeps the v0.1 lockfile shape but ranks tools by embedding
108
+ similarity before applying `--max-tools` and `--max-schema-tokens`.
109
+
110
+ Fixture mode is deterministic and requires no service:
111
+
112
+ ```bash
113
+ mcp-context-budget semantic-select \
114
+ --tool-list tools.json \
115
+ --task "diagnose bug report" \
116
+ --embedding-backend fixture \
117
+ --embedding-file embeddings.json \
118
+ --out-lock semantic.lock.json
119
+ ```
120
+
121
+ The fixture file must contain:
122
+
123
+ ```json
124
+ {
125
+ "queries": {"diagnose bug report": [1.0, 0.0]},
126
+ "tools": {"github/get_issue": [1.0, 0.0]}
127
+ }
128
+ ```
129
+
130
+ Ollama mode uses stdlib HTTP and adds no Python package dependency:
131
+
132
+ ```bash
133
+ mcp-context-budget semantic-select \
134
+ --tool-list tools.json \
135
+ --task "diagnose bug report" \
136
+ --embedding-backend ollama \
137
+ --ollama-url http://localhost:11434 \
138
+ --ollama-model nomic-embed-text
139
+ ```
140
+
141
+ ### Response Fixture Compression
142
+
143
+ `compress-responses` reads one response fixture or a directory of `*.json`
144
+ fixtures, writes compressed copies, and emits a JSON report.
145
+
146
+ ```bash
147
+ mcp-context-budget compress-responses \
148
+ --fixtures responses/ \
149
+ --max-response-tokens 4000 \
150
+ --out-dir compressed-responses \
151
+ --report compression-report.json
152
+ ```
153
+
154
+ The v0.2 strategy is deterministic extractive compression. It preserves common
155
+ identifier fields and writes a `summary` when large body fields need to be cut.
156
+
157
+ ### Config Apply
158
+
159
+ `config-apply` turns a selected-tool lock into a safe local MCP config patch.
160
+ Dry-run is the default posture; `--write` is required before the config file is
161
+ changed, and write mode creates a backup.
162
+
163
+ ```bash
164
+ mcp-context-budget config-apply \
165
+ --config mcp.json \
166
+ --lock mcp-budget.lock.json \
167
+ --mode disable-unselected \
168
+ --dry-run \
169
+ --patch-out mcp-config.patch.json
170
+
171
+ mcp-context-budget config-apply \
172
+ --config mcp.json \
173
+ --lock mcp-budget.lock.json \
174
+ --mode disable-unselected \
175
+ --write \
176
+ --backup-dir backups/
177
+ ```
178
+
179
+ Reports redact environment values.
180
+
181
+ The apply contract is enforced, not advisory:
182
+
183
+ - **Inline and `toolsListPath` tools are both patched.** A server whose tools
184
+ live in an external `tools/list` JSON has that file patched (and backed up)
185
+ too — not silently skipped.
186
+ - **The lock is bound to the config.** Each lock records a `config_fingerprint`
187
+ of its tool universe; `config-apply` refuses a lock whose fingerprint does not
188
+ match the target config (a foreign/stale lock would otherwise disable every
189
+ tool and still report success). Override with `--allow-fingerprint-mismatch`.
190
+ - **Honest status, never a false PASS.** A command-discovered server (no inline
191
+ `tools`, no `toolsListPath`) cannot be enforced without live startup, so it is
192
+ reported under `not_patchable` and the status is `PARTIAL`, not `PASS`.
193
+ - **Opt-in materialization closes the PARTIAL gap.** With `--allow-start` and
194
+ `--materialize-tools-list`, command-discovered tools are listed through local
195
+ stdio, saved to a caller-owned sidecar, and enforced as a normal
196
+ `toolsListPath` catalog.
197
+ - **Disabling takes effect.** The loader honors `enabled: false`, so a disabled
198
+ tool (or server) drops out of the budget on the next `scan`/`select`.
199
+
200
+ ### Config Secret Audit
201
+
202
+ `config-audit` is a read-only hygiene check for MCP config files. It flags
203
+ high-confidence literal secrets in env values, args, and nested config fields,
204
+ while treating `${TOKEN}` references, `op://...` references, and redacted
205
+ placeholders as safe references.
206
+
207
+ ```bash
208
+ mcp-context-budget config-audit \
209
+ --config mcp.json \
210
+ --json-out mcp-config-audit.json \
211
+ --fail-on high
212
+ ```
213
+
214
+ Reports include the config path, finding path, severity, secret class, length
215
+ bucket, and a short fingerprint. Literal secret values are never printed.
216
+
217
+ ## Docker
218
+
219
+ ```bash
220
+ docker build -t mcp-context-budget:local .
221
+ docker run --rm mcp-context-budget:local demo \
222
+ --task "triage a GitHub issue and update one ticket" \
223
+ --max-tools 8 \
224
+ --max-schema-tokens 6000 \
225
+ --max-response-tokens 4000
226
+ ```
227
+
228
+ The image exposes no service port.
229
+
230
+ v0.2 also includes independent Docker proof commands for the new capabilities:
231
+
232
+ ```bash
233
+ docker run --rm mcp-context-budget:local semantic-demo \
234
+ --task "diagnose bug report" \
235
+ --max-tools 3 \
236
+ --max-schema-tokens 3000
237
+ docker run --rm mcp-context-budget:local compress-demo --max-response-tokens 4000
238
+ docker run --rm mcp-context-budget:local config-demo
239
+ docker run --rm mcp-context-budget:local allow-start-demo --start-timeout-seconds 2 --max-stdio-bytes 65536 --stdio-framing auto
240
+ docker run --rm mcp-context-budget:local semantic-demo --task "diagnose bug report" --max-tools 3 --max-schema-tokens 3000 --embedding-backend fixture
241
+ docker run --rm mcp-context-budget:local prove-parallel-ollama-demo
242
+ docker run --rm mcp-context-budget:local config-audit-demo
243
+ docker run --rm mcp-context-budget:local config-multiserver-demo
244
+ ```
245
+
246
+ Expected v0.3 proof lines:
247
+
248
+ ```text
249
+ LIVE_INTROSPECTION_STATUS=PASS
250
+ AFTER_CONFIG_NOT_PATCHABLE=0
251
+ CONFIG_AUDIT_STATUS=PASS
252
+ CONFIG_AUDIT_SECRET_VALUES_REDACTED=true
253
+ CONFIG_MULTISERVER_STATUS=PASS
254
+ ```
255
+
256
+ ## Out of v0.3
257
+
258
+ ### Locked Out
259
+
260
+ - Live runtime MCP proxy/gateway that intercepts and routes actual tool calls.
261
+ - Browser UI.
262
+ - Organization-wide background scanner.
263
+ - Vendor-specific hosted dashboards.
264
+
265
+ These are not v0.4 commitments; they break the local-first CLI verifier shape.
266
+
267
+ ### Shipped in v0.4
268
+
269
+ - Parallelized Ollama embeddings for `semantic-select` when
270
+ `--embedding-backend ollama` is explicitly selected (fixture backend remains
271
+ the default for CI/docker).
272
+
273
+ ### Deferred to v0.5
274
+
275
+ - Automatic response compression for arbitrary live MCP servers.
276
+ - Broader CLI polish.
@@ -0,0 +1,5 @@
1
+ """MCP context budget verifier."""
2
+
3
+ from __future__ import annotations
4
+
5
+ __version__ = "0.3.0"
@@ -0,0 +1,6 @@
1
+ from __future__ import annotations
2
+
3
+ from mcp_context_budget.cli import main
4
+
5
+ if __name__ == "__main__":
6
+ raise SystemExit(main())