pubdev_context 0.4.0-rc.4
pubdev_context: ^0.4.0-rc.4 copied to clipboard
Model Context Protocol (MCP) server for pub.flutter-io.cn. Gives AI agents structured access to search, compare, evaluate, and inspect Dart and Flutter packages.
pubdev_context #
pubdev_context is an archived proof of concept retained in this repository as
reference code.
The original package documentation was moved to
../../archive/poc/pubdev_context/packages/pubdev_context/README.md.
The associated ADRs, changelog, generated docs, and decision history were
archived under ../../archive/poc/pubdev_context/.
These materials are intentionally historical and outdated. They are available for reference, but they should not be treated as active constraints on the real product.
Wire Trace #
The Wire Trace is an opt-in, human-readable diagnostic log of everything
crossing the server's two boundaries — the LLM boundary (the tool calls and
resource reads the agent makes, and the results it gets back) and the pub.flutter-io.cn
boundary (the HTTP requests the server sends upstream and the responses it
receives). It is written for "open it and understand," not for machine parsing.
It is a separate subsystem from the MCP log() / --log-level channel, which is
left completely untouched.
Enabling it #
Add --wire-trace to the server invocation in your MCP client config (or set
the environment variable). It is off by default — installing the server
never writes files to disk unless you opt in.
{
"mcpServers": {
"pubdev_context": {
"command": "pubdev_context",
"args": ["--wire-trace"]
}
}
}
Equivalently: pubdev_context_WIRE_TRACE=1.
Configuring it #
For each knob a CLI flag wins over its environment variable, which wins over the default:
| Flag | Environment variable | Default | Purpose |
|---|---|---|---|
--wire-trace |
pubdev_context_WIRE_TRACE |
off | Enable the trace. |
--wire-trace-dir <path> |
pubdev_context_WIRE_TRACE_DIR |
<cache-dir>/wire-trace |
Directory the per-session files are written to. |
--wire-trace-max-preview <bytes> |
pubdev_context_WIRE_TRACE_MAX_PREVIEW |
2048 |
Cap on each logged body preview. 0 = metadata-only (no bodies). |
<cache-dir> is the tarball cache directory (--cache-dir), which itself
defaults to $XDG_CACHE_HOME/pubdev_context or ~/.cache/pubdev_context. So
with no other configuration the trace lands in ~/.cache/pubdev_context/wire-trace/.
Locating the files #
Each server run writes its own file, named by timestamp and process id:
wire-trace-20260709-140310-981-pid48213.log
Because the name sorts chronologically, the trace for the run you just did is
simply the newest file. Per-run files also keep concurrent server instances
from interleaving into one log. Old files are pruned automatically — the last
10 are kept and the oldest beyond that are deleted. Lines are flushed as they
are written, so tail -f shows activity live and a crash preserves the last
line.
Tracing is strictly best-effort and never crashes the server: an unwritable directory produces a single stderr warning and then runs with tracing disabled.
Reading it #
Every file opens with a session header recording the server version, pid, start
time, and effective config, followed by chronological event lines. Every line
carries a Correlation Id (#001, #002, …, a per-session counter) so you
can follow — or grep — one LLM request and all the pub.flutter-io.cn calls it triggered
as a single story, even when concurrent requests interleave.
════════════════════════════════════════════════════════════════════════
Wire Trace — pubdev_context 0.4.0-rc.3
session started 2026-07-09 14:03:10.981 pid 48213
config: max-preview=2048B concurrency=5 cache=~/.cache/pubdev_context
════════════════════════════════════════════════════════════════════════
14:03:11.204 #001 ← LLM tools/call search_packages
args: {"query":"http client","limit":5}
14:03:11.205 #001 → pub GET /api/search?q=http+client [cache miss]
14:03:11.517 #001 ← pub 200 /api/search (312 ms, 4.1 KB JSON)
body: {"packages":[{"package":"http"},{"package":"dio"},… (truncated, 4.1 KB total)
14:03:11.518 #001 → pub GET /api/packages/http [cache miss]
14:03:11.860 #001 ← pub 200 /api/packages/http (342 ms, 8.7 KB JSON)
14:03:12.010 #001 → LLM result search_packages ok (5 results, 806 ms, 6.2 KB)
body: [{"name":"http","likes":1234,… (truncated, 6.2 KB total)
14:05:02.100 #002 ← LLM tools/call get_package
args: {"name":"htp"}
14:05:02.420 #002 ← pub 404 /api/packages/htp (319 ms)
14:05:02.421 #002 → LLM result get_package ERROR PACKAGE_NOT_FOUND (321 ms)
error: {"code":"PACKAGE_NOT_FOUND","message":"Package not found on pub.flutter-io.cn.",…
14:06:10.320 #003 ⚠ pub 503 /api/search (318 ms) — retry 1/3 in 500 ms
14:06:10.840 #003 → pub GET /api/search?q=foo [retry 1]
14:07:00.001 #004 ⚡ cache hit get_package:http (age 12s, no pub.flutter-io.cn call)
How to read the markers and lines:
← LLM/→ LLM— a call coming in from the agent, and the result going back to it. The result line showsokorERROR <CODE>, the duration, and the result size.→ pub/← pub— a request the server sent upstream, and the response. A request is tagged[cache miss]when it followed a cache miss and[retry N]when it is a retry; a response shows status, latency, byte size, and content type.⚡ cache hit— an answer served from cache with no pub.flutter-io.cn call, with the entry's age. A cache miss is visible as the→ pubrequest that follows.⚠— a transient pub.flutter-io.cn failure, showing the attempt number and the backoff before the retry.args:/body:/error:— continuation lines carrying the full arguments, a truncated body preview, or the Tool Error payload. Previews over the cap are cut and annotated… (truncated, <size> total); a cap of0omits bodies entirely.- HTML endpoints (docs, changelog, example) log the converted-markdown
preview only — never raw HTML — annotated with both sizes
(
… KB HTML → … KB md). Tarball downloads are logged as metadata only (size and extracted file count); archive bytes are never dumped.
Autocomplete (completions) traffic is deliberately excluded so it does not bury the signal.