v1.6.0 — agentic supremacy#15
Merged
Merged
Conversation
Make mcpx a measurable, observable, and intelligent control plane between AI agents and MCP servers. Every call is recorded, every schema is cached, every tool is one `mcpx find` away, and an always-on dashboard makes ROI visible. ## Headline features - **mcpx find <query>** — BM25-ranked tool search across every server. ~80 tokens for top candidates vs 5–15K for `list -v`. - **mcpx batch** — NDJSON in/out, parallel by default, single client per server reused across the batch. - **mcpx gain** — premium terminal dashboard for tokens-saved analytics. - **Always-on web dashboard** — auto-spawned, token-protected, single-page UI with live tail and click-to-inspect drawer. - **mcpx doctor** — config + connectivity + secrets + daemon health checks. - **mcpx <server> <tool> --example / --validate-args** — JSON skeleton + type/required check without invoking. - **Default-compact help** — agent-friendly listing; `--full` for verbose. - **Schema cache + result cache** — first call slow, everything else instant; idempotent reads dedupe within TTL. - **Schema normalizer** — handles JSON Schema union types (`type: ["string","null"]`), oneOf/anyOf/allOf, $ref. Closes #14. - **Edit-tool guards** — pre-call warning + post-call Go parse check for `replace_symbol_body` and friends across 9 languages. - **Typo remediation** — Levenshtein-2 "did you mean…" suggestions. - **Structured exit codes** — 0/1/2/3/4/5/6 for granular branching. ## New packages - internal/stats — JSONL writer (async, drop-on-overflow), reader, agg. - internal/schemacache — schema + result caches, idempotence detection. - internal/find — BM25 ranker (snake/camel split, name bonus, stem). - internal/render — Box, Bar, Sparkline, FormatNumber/Duration/Percent. - internal/ui — dashboard daemon (lazy supervisor, HTTP, SSE, embed.FS). ## Configure rewrite `mcpx configure` now generates an agent-grounded MCPX.md (composition + discover + exit codes) and per-server tool-selector tables. The legacy `--format compact` flag is hidden; output is agent-optimized by default. Edit-tool safety guidance is only emitted for servers that expose body-mutation tools. ## Tests - 283 passing across 13 packages. - New: stats, schemacache, find, render, mcp/schema, edit_guard. Closes #14. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
govulncheck reported 5 stdlib vulnerabilities all fixed in Go 1.26.2: - GO-2026-4870 (crypto/tls — KeyUpdate DoS) - GO-2026-4866 (crypto/x509 — name constraint auth bypass) - GO-2026-4865 (html/template — XSS via brace tracking) - two more transitive go mod tidy also promoted golang.org/x/term from indirect → direct (it's imported by internal/cli/term.go). Local govulncheck confirms: "No vulnerabilities found." Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The result cache key was hashed from (server, tool, args) only — so a tool that read a file at T+0, then again at T+10 after an edit, would return the T+0 snapshot inside the 30s TTL window. Stale data is unacceptable for any filesystem-touching tool (find_symbol, read_file, search_for_pattern, ...). Fix: when args carry a path-like key (`relative_path`, `path`, `file`, `file_path`) that resolves to an existing file or directory, fold its mtime into the cache key. Edits change the mtime → key shifts → cache miss → fresh fetch. No on-disk format change; old cache entries simply stop matching the new keys and get pruned by the existing TTL. - internal/schemacache/results.go — ResultKey now accepts variadic extras that participate in the hash. - internal/cli/cache_helpers.go — fileMtimeExtras builds path:mtime-ns strings from args and the project root. - 5 new tests covering the invalidation, missing-file no-op, multiple candidate keys. CHANGELOG / website mirror updated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Caching tool RESPONSES is a correctness footgun we can't make safe without server cooperation: recursive searches, multi-file reads, network-backed tools, and any non-filesystem state can all return stale data inside a TTL. mcpx is the trustworthy intermediary for AI agents; we'd rather make the round-trip than risk acting on stale snapshots. What's gone: - internal/schemacache/results.go (ResultEntry, ResultKey, IsIdempotent, LoadResult, SaveResult, ClearResults, canonicalize) - internal/schemacache/results_test.go - callToolCached + fileMtimeExtras + resolveResultCachePolicy in internal/cli/cache_helpers.go - batch's --cache flag and the BatchResult.Cached field - stats.Record.ResultCacheHit, Summary.ResultHitRate - config CacheConfig fields: ResultTTL, ResultEnabled, ResultHeuristic, ResultIdempotent - "cached" badge from gain TUI and dashboard What stays: - Schema cache (tools/list, prompts/list, resources/list) — correctness-safe; worst case is missing a freshly-added tool for one TTL window - native_baseline_tokens precompute → still drives "tokens saved" metric - mcpx find (reads schema cache, no result caching involved) If a future MCP server adopts `readOnlyHint: true` annotations widely, server-driven result caching becomes safe to add back. Net: -544 lines. 274 tests passing across 13 packages, govulncheck clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`mcpx list`, `mcpx ping`, `mcpx configure`, etc. all printed the dashboard URL on first invocation per shell session — annoying when their stdout is the user-facing data. Invert isQuietCommand: maintain an explicit set of every built-in mcpx command, return true for any of them. Banner now fires only when the invocation pattern is `mcpx <server> <tool>` (i.e. an actual MCP tool call, the only case where the dashboard's analytics are about to grow). Verified end-to-end: - `mcpx list sentry -v` — no banner, prints 22 tools cleanly - `mcpx serena <tool>` — banner once per session on a real terminal Bonus: this run also validated issue #14 against the live `@sentry/mcp-server` with auth — the schema normalizer correctly handles the `["string","null"]` union types Sentry uses, all 22 tools list without unmarshal errors. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Auto-banner on tool calls was noise — once you've seen the URL, it's clutter
on every fresh shell. Removed the banner entirely. The dashboard daemon
still auto-spawns silently; the URL surfaces only when explicitly asked:
- `mcpx gain` prints the URL in its footer (you're already looking
at metrics, so it's relevant)
- `mcpx ui status` prints the URL or "inactive"
- `mcpx ui open` prints the URL alone (use with `open $(...)`)
Removed:
- The notice goroutine + per-PPID marker file dance in startUIIfEnabled
- noticeAlreadyShown / markNoticeShown / noticeMarkerPath helpers
- isQuietCommand (no banner, no need to suppress)
- internal/cli/term.go (only consumer was the banner gating)
Net: -50 lines.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Make mcpx a measurable, observable, and intelligent control plane between AI agents and MCP servers. Every call is recorded, every schema is cached, every tool is one
mcpx findaway, and an always-on dashboard makes ROI visible.Closes #14.
Headline features
Agent superpowers
mcpx find <query>— BM25-ranked tool search across every server. Top candidates in ~80 tokens vs 5–15K forlist -v.mcpx batch— NDJSON in/out, parallel by default, single client per server reused across the entire batch.mcpx <server> <tool> --example— JSON skeleton with placeholder values from the normalized schema.mcpx <server> <tool> --validate-args ...— type/required check without invoking.mcpx <server> --helpis now one-line per tool with required flags surfaced. Add--fullfor descriptions.replace_symbol_bodycalls warned across 9 languages when body starts with a duplicate keyword. For.gofiles, post-edit re-parse withfile:line:colerrors.Operator surfaces
mcpx gain— premium terminal dashboard: hero metric (tokens saved), 7-day sparkline, top tools, top savers, server p95, recent calls.--by,--history,--suggest,--watch,--all,--project,--since,--json./).mcpx ui status|stop|open|disable— dashboard controls.mcpx doctor— config + command path + secrets + daemon + initialize + tools/list checks.--jsonfor machine-readable.Foundation
~/.mcpx/stats.jsonl— every call recorded (timestamp, args, latency, cache hits, exit code, tokens saved). Async writer, never blocks.tools/listcached at~/.mcpx/cache/schemas/<key>.jsonwith TTL. First call slow, everything else instant.native_baseline_tokensprecomputed.get_*/list_*/find_*/search_*/read_*) dedupe withincache.result_ttl(default 30s).type: [\"string\",\"null\"]),oneOf/anyOf/allOf,$ref. Fixes Sentry MCP init (Sentry MCP server fails to initialize: cannot unmarshal JSON Schema array union type into string #14).0ok ·1tool error ·2config ·3connection ·4timeout ·5policy denied ·6tool not found.Configure rewrite
Generates an agent-grounded
MCPX.md(composition + discover + exit codes) plus per-server<SERVER>.mdfiles (tool-selector table + compact reference). The legacy--format compactflag is hidden; output is agent-optimized by default.New packages
internal/stats/— JSONL writer + reader + aggregatorinternal/schemacache/— schema + result caches, idempotence detectioninternal/find/— BM25 rankerinternal/render/— terminal primitives (Box, Bar, Sparkline, FormatNumber)internal/ui/— dashboard daemon (lazy supervisor, HTTP, SSE, embed.FS)Test plan
go vetcleanmcpx versionwarns on+dirtybuildsmcpx find "search code"returns ranked resultsmcpx batch < calls.jsonlruns in parallel; output preserves input ordermcpx gainrenders premium TUI with sparkline + tablesmcpx ui openreturns the URL/api/summary,/api/projects,/api/call/<id>,/api/events(SSE) live--examplereturns valid JSON;--validate-argsreports issuesmcpx doctorruns all checks and exits 0/2 correctlymcpx configureregeneratesMCPX.md+<SERVER>.mdcleanly[\"string\",\"null\"]) initializes successfullytype type Foocorruption pre + post callDocumentation
🤖 Generated with Claude Code