agent-connector · diff
git:20260624.09226fc to git:20260624.9017fed
68 added, 220 removed. Audit A to A.
---
name: agent-connector
- description: Two audiences. (A) MCP DEVELOPER — add agent-connector as a framework dependency inside a developer-branded MCP package, write the server/hooks/surfaces ONCE with defineConnector({...}), and ship install/doctor/uninstall through the branded package/bin (for example `npx @acme/acme-db-mcp install`) across every detected AI-agent CLI in the 42 registered deploy adapters, with default local-first per-tool token telemetry for YOUR OWN wrapped stdio server. package.json name/mcpName/bin/version are the default metadata source; explicit id/mcp.hostAlias/version are advanced overrides only. (B) AGENT-CLI END USER — with NO connector at all, run `agent-connector usage` to see per-CLI / per-model token totals scanned read-only from each agent CLI's own session logs. Use this when a developer wants one integration to reach many agent hosts and to see which of their own server's tools cost the most context, OR when any agent-CLI user wants whole-conversation token totals per CLI/model with zero setup.
+ description: Use when building, reviewing, installing, packaging, or diagnosing an agent-connector integration. Two audiences: MCP developers use agent-connector as a framework dependency inside their own branded MCP package/bin, while agent-CLI users use connector-free `agent-connector usage` for whole-conversation token totals. Always keep package.json name/mcpName/bin/version as the default identity source; explicit id/displayName/bin/version are advanced overrides only.
---
# agent-connector
- agent-connector serves two distinct audiences and the work forks between them:
-
- - **(A) MCP developer** — depends on agent-connector as a framework inside their
- own branded MCP package, writes an integration once with `defineConnector()`,
- and ships their MCP server + lifecycle hooks (+ commands / skills / subagents /
- memory) across every detected agent CLI through their own package/bin. It solves two dev problems: (1) each agent host re-invents
- MCP registration + lifecycle hooks with incompatible config files, root keys, formats
- (JSON/JSONC/TOML/YAML/exported TS), and event names; (2) no host reports per-tool
- token usage back to an MCP server. Write the integration once; the branded CLI renders it into
- each installed host's native dialect and measures the developer's OWN wrapped stdio
- server's per-tool token footprint locally.
- - **(B) Agent-CLI user** — has NOT authored a connector and just runs an agent CLI
- (Claude Code, Codex, Cursor, …). Their entire supported surface is one connector-free
- command, `agent-connector usage`, which reads each agent CLI's own session logs
- read-only to show per-CLI / per-model token totals. No `defineConnector`, no install,
- no config file.
-
- The one accuracy-critical line between them: if you BUILD an MCP integration,
- agent-connector is the framework underneath your branded package/bin, which deploys
- it everywhere and measures your own server's per-tool tokens. If you just USE agent CLIs, agent-connector reads their logs to show you per-CLI /
- per-model token totals — whole-conversation only, never itemized per MCP or per tool.
-
- ## When to reach for it
-
- - **(A) MCP developer** wants to ship ONE MCP server (and/or hooks / slash commands /
- Agent Skills / subagents / standing memory guidance) across many agent CLIs without
- hand-authoring N config dialects → `defineConnector` + a branded package/bin
- command such as `npx @acme/acme-db-mcp install`.
- - **(A) MCP developer** asks "which of MY OWN server's tools cost the most context?" →
- `telemetry report --by tool` / `telemetry leaderboard --by mcp|tool`. Requires a
- declared connector with a wrapped stdio server (per-tool counts exist only for the
- server your connector declares and wraps; remote http/sse/ws servers are not wrapped).
- - **(B) Agent-CLI user (no connector needed)** wants to compare token spend across the
- agent CLIs on their machine → `usage` (alone). This reports WHOLE-CONVERSATION totals
- per CLI / model / project / session / day — it does NOT and cannot itemize cost per
- individual MCP server or per tool, because agent CLIs do not log per-tool token
- attribution. For per-MCP/per-tool numbers, that MCP must be deployed and wrapped via a
- connector (the developer track above).
-
- Do NOT use it to author a brand-new MCP server protocol — it deploys + measures an
- existing server command/URL and wraps lifecycle hooks; it does not implement tools.
-
- ## Write once: defineConnector({...})
-
- Create `agent-connector.config.mjs` (or `.js` / `.json`) at the project root:
-
- ```ts
- import { defineConnector } from "@ken-jo/agent-connector";
-
- export default defineConnector({
- // package.json name/mcpName/bin/version are the default metadata source.
- // Set id or mcp.hostAlias only for legacy configs or multi-instance aliases.
-
- // MCP server — declared once, transport-polymorphic. Omit for a hooks-only connector.
- server: {
- transport: "stdio", // stdio | http | sse | ws
- command: "npx", // stdio: command required; remote: url required
- args: ["-y", "@acme/acme-db-mcp"],
- env: { ACME_DB_DSN: "${env:ACME_DB_DSN}" }, // universal ${env:VAR} / ${env:VAR:-default}
- tools: { include: ["*"] },
- timeoutMs: 30_000,
- // wrapForTelemetry defaults true for stdio when telemetry is on
- },
-
- // Lifecycle hooks — 13 canonical events (SessionStart, SessionEnd, UserPromptSubmit,
- // PreToolUse, PostToolUse, PreCompact, Stop, Notification, PermissionRequest,
- // PostToolUseFailure, SubagentStart, SubagentStop, PostCompact); the framework
- // synthesizes the right entrypoint per host paradigm (json-stdio binary /
- // ts-plugin module / skip on mcp-only). Hosts without a native analog skip-warn —
- // never silently dropped.
- hooks: {
- PreToolUse: {
- matcher: "acme_write", // regex on tool name; empty = all
- async handler(evt) {
- return evt.toolName === "acme_write"
- ? { decision: "ask", reason: "Confirm Acme DB write" } // allow|deny|modify|context|ask
- : { decision: "allow" };
- },
- },
- SessionStart: {
- async handler() {
- return { decision: "context", additionalContext: "Acme DB schema v12 loaded." };
- },
- },
- },
-
- // Content surfaces (all optional, content-only files; written where supported).
- commands: [
- { name: "db-report", description: "Summarize the schema", prompt: "Report on {{schema}}.", argumentHint: "[schema]" },
- ],
- skills: [
- { name: "db-helper", description: "Guides DB queries; use when the user asks about the schema.",
- body: "# DB helper\nUse acme_query first...", resources: { "references/api.md": "..." } },
- ],
- // subagents: [{ name: "db-auditor", description: "...", prompt: "..." }],
-
- // Standing guidance (memory) — written ONCE as a marker-fenced, hash-stamped
- // managed block into the memory file each host actually reads: the standard
- // AGENTS.md on most supporting hosts, CLAUDE.md on Claude Code (opt-in
- // `platforms["claude-code"].memory.mode: "agents-import"` manages an @AGENTS.md
- // bridge instead), GEMINI.md on Gemini CLI. User edits inside the block are
- // hash-detected and never clobbered (`install --force` overrides after a backup);
- // uninstall excises exactly your block. 16 KiB hard cap / 4 KiB soft warn.
- memory: [
- { content: "Use the acme-db MCP tools for schema questions; never hand-edit migrations." },
- ],
-
- telemetry: { enabled: true, modelFamilyHint: "auto", measureToolDefs: true }, // ON by default
-
- // Per-platform escape hatches: disable a surface, force scope, merge `extra`
- // verbatim; `nativeHooks` wires ANY host hook event outside the 13 normalized
- // ones by its verbatim name on adapters with supportsNativeHooks; `configPatch`
- // patches claude-code host-exclusive settings keys (set-if-absent + skip-warn,
- // refcounted ownership, sensitive-key denylist, reversible uninstall).
- platforms: {
- warp: { hooks: false },
- "claude-code": {
- nativeHooks: {
- TaskCompleted: { async handler(evt) { /* evt.raw = host JSON, verbatim */ } },
- },
- configPatch: [{
- key: "statusLine", // dotted LEAF path into settings.json
- value: { type: "command", command: "acme-db statusline" },
- reason: "Render the Acme meter in Claude Code's status line",
- }],
- // memory: { mode: "agents-import" }, // or memory: { path: "docs/AGENTS.md" }
- },
- },
- targets: "auto", // "auto" = all detected, or e.g. ["claude-code","codex"]
- });
- ```
-
- A connector must declare at least one of `server`, `hooks`, `commands`, `skills`,
- `subagents`, or `memory` (or a per-platform `nativeHooks` / `configPatch`
- declaration). `defineConnector` validates eagerly and throws `ConnectorConfigError`
- on bad ids or missing derivable package identity, non-function handlers, duplicate surface names, oversized skill
- descriptions (>1024 chars), unsafe skill `resources` paths, memory content over the
- 16 KiB hard cap (or containing the literal managed-block marker tokens), a
- `nativeHooks` key that names one of the 13 normalized events (use `hooks` for
- those), or a `configPatch` key in the agent-connector namespace (`hooks*`,
- `mcpServers*` — the sensitive-key denylist is enforced at install).
-
- ## CLI workflow
-
- ```bash
- npm install @ken-jo/agent-connector # framework dependency of your MCP package
- cd my-mcp-project
-
- npx @acme/acme-db-mcp detect # user-facing path: your branded package/bin
- npx @acme/acme-db-mcp install --dry-run # preview every change, everywhere (nothing written)
- npx @acme/acme-db-mcp install # deploy across detected hosts
- npx @acme/acme-db-mcp doctor [--probe] # health checks; --probe spawns the real stdio server: initialize → ping → tools/list
- npx @acme/acme-db-mcp uninstall # full inverse — removes everything install wrote
-
- npx @ken-jo/agent-connector install --dry-run --connector ./agent-connector.config.mjs
- # development fallback / CI-debug path; not the foreground install brand for users
- ```
-
- `--scope` is `user` (default) or `project`. `--targets` is a comma-separated
- PlatformId list. `--dry-run` works on install/upgrade/uninstall. `--connector <path>`
- points at a config explicitly; otherwise it's found by walking up from the project.
- `install --force` additionally overwrites USER-EDITED memory managed blocks (hash
- drift) after a timestamped backup — the default is warn-and-leave. Canonical
- flag-level reference: `llms-full.txt` §3 / the docs site `/docs/dev/cli`.
-
- ## Telemetry, leaderboards, usage
+ agent-connector serves two distinct audiences. Pick the track first.
- There are two completely separate token-measurement axes, split by audience. They
- measure DIFFERENT things and are NEVER summed.
+ - **MCP developer**: building an MCP integration. They depend on
+ `@ken-jo/agent-connector`, write `defineConnector({...})`, expose their own
+ branded package/bin, and deploy to detected agent hosts through that brand.
+ - **Agent-CLI user**: not authoring a connector. They use
+ `agent-connector usage` only, which scans agent CLI logs read-only and reports
+ whole-conversation totals by CLI/model/project/session/day.
- **Axis 1 — `telemetry` / 🔌 (MCP-developer track, the developer's OWN wrapped server).**
- Telemetry is ON by default: stdio servers are wrapped with `agent-connector serve` so
- every `tools/call` is measured (args in, results out, plus the one-time `tools/list`
- schema cost) and tokenized locally. This is the ONLY source of per-MCP and per-tool
- numbers, and it exists only for a server a registered connector declares and wraps —
- `serve` loads the connector by id and every record requires a connector id, so an
- arbitrary third-party MCP the user didn't author produces nothing here. Wrapping is
- stdio-only; remote (http/sse/ws) servers are registered but never wrapped. Every record
- carries a confidence tag (`tokenizer-exact | tokenizer-calibrated | tokenizer-approx |
- heuristic | host-native`).
+ The accuracy boundary is strict: developer telemetry can measure per-MCP and
+ per-tool tokens only for the developer's own wrapped stdio server. Connector-free
+ `usage` cannot itemize arbitrary MCPs or tools because agent CLIs do not log
+ per-tool attribution.
- ```bash
- agent-connector telemetry report --by tool --since 7d # ranked per-tool footprint (also session|project)
- agent-connector telemetry export --format csv --out tel.csv
- agent-connector telemetry leaderboard --by mcp # which of YOUR servers costs most (also --by tool | --by surface)
- ```
+ ## Read The Right Reference
- **Axis 2 — `usage` / 🖥️ (agent-CLI-user track, host-log scan, NO connector needed).**
- Reads each agent CLI's OWN session logs/DBs read-only and aggregates WHOLE-CONVERSATION
- totals. It groups ONLY by `platform | project | session | model | day` — there is NO
- per-MCP or per-tool dimension, because agent CLIs do not log per-tool token attribution.
- Use this for "which agent CLI / model is burning the most tokens?"; never read it as
- "which MCP/tool costs the most." Local readers report host-logged counts; a few are
- host-estimated (shown in the CONFIDENCE column); 5 "synced" platforms (cursor,
- antigravity, antigravity-cli, trae, warp) are skipped as "requires sync" unless a local
- cache already exists.
+ This skill is intentionally small. Read the relevant reference file before
+ acting:
- ```bash
- npm i -g @ken-jo/agent-connector # optional: connector-free token telemetry utility
- agent-connector usage report --by platform --since 7d # whole-conversation totals from CLI logs (also project|session|model|day)
- agent-connector usage leaderboard --by platform # which CLI/host spent the most (also --by model)
- agent-connector usage export --format csv --out usage.csv
- ```
+ - `references/package-first.md` — required for any scaffold, code review,
+ wizard, docs, or naming/identity decision. It defines the package-first
+ contract and what not to ask the user for.
+ - `references/authoring.md` — required when creating or editing
+ `agent-connector.config.*`, SDK imports, hooks, commands, skills, subagents,
+ memory, statusline, actions, or platform escape hatches.
+ - `references/cli-workflow.md` — required when wiring `bin.mjs`, install,
+ uninstall, upgrade/sync/update, doctor, package, or marketplace/direct install
+ flows.
+ - `references/telemetry.md` — required for any token, usage, leaderboard,
+ privacy, opt-out, or "which MCP/tool costs tokens?" question.
+ - `references/agent-readiness.md` — required when improving agent-facing docs,
+ skills, scaffold/boilerplate, lint/audit, MCP-server affordances, or other
+ "make this easy for AI agents" surfaces.
- The unified `agent-connector leaderboard` shows three origin-labeled boards with
- DIFFERENT prerequisites — never summed: 🔌 per-MCP (needs a connector + serve traffic),
- 🛰️ live host-native turns (needs the opt-in usage hook, installed only by the Gemini CLI
- and Antigravity adapters, and a connector at runtime), and 🖥️ host usage (the only board
- that works with no setup — same whole-conversation, per-CLI/per-model scan as `usage`).
- For a plain agent-CLI user with no connector, 🔌 and 🛰️ are empty; `usage` is the
- primary end-user entry point precisely because only its data source is connector-free.
+ For exhaustive field-level detail, use `llms-full.txt`. For the short map, use
+ `llms.txt`. For current host coverage and platform count, use the website
+ `/coverage` page; do not copy a fixed count into this skill. The public website
+ mirrors developer docs under `/docs/dev`.
- ## Operating model
+ ## Default Agent Procedure
- - **Home-dir single binary.** Runtime installs once under `~/.agent-connector`
- (override `AGENT_CONNECTOR_DATA_DIR`). Every host config we write is a thin
- pointer to that one stable binary, so one managed `agent-connector upgrade`
- propagates everywhere — never silent auto-update.
- - **Per-project data.** Telemetry/state is keyed by project identity (git remote or
- normalized path), stored under the home data-root — survives `git clean`, shared
- across hosts opening the same project. Native host config files are never relocated.
- - **Windows-first.** No symlinks, no POSIX-only assumptions.
+ 1. Inspect the target package's `package.json` first.
+ 2. Use `package.json` `name`, `mcpName`, `bin`, and `version` as the source of
+ truth for MCP identity, host alias/display label, public command, and
+ connector version.
+ 3. Do not request separate connector id, display name, bin name, or version
+ unless metadata is absent or the user explicitly needs a legacy/multi-instance
+ override.
+ When showing generated host configs, comment that host-native ids are install
+ artifacts derived from package metadata, not second user-maintained inputs.
+ 4. Import new authoring code from `@ken-jo/agent-connector/sdk`.
+ 5. Put `createConnectorCli({ packageJson, connector })` in the developer's
+ package bin from `@ken-jo/agent-connector/cli`; comment that `packageJson`
+ supplies identity while `connector` supplies behavior.
+ 6. Foreground the developer's brand in MCP lifecycle/runtime commands:
+ `npx @acme/acme-db-mcp install`, `acme-db doctor --probe`, `acme-db upgrade`,
+ `acme-db uninstall`, `acme-db telemetry report`, etc.
+ 7. Keep framework tooling separate: `package` emits host/MCP distribution
+ artifacts, so document it as `npx @ken-jo/agent-connector package --connector
+ ...` (or global `agent-connector package` for developers who installed the
+ framework CLI).
+ 8. Use other `npx @ken-jo/agent-connector ... --connector` commands only as a
+ local framework development/debug fallback.
+ 9. Verify with typecheck/tests, SDK offline harnesses when relevant, then
+ `doctor --probe` when a real stdio server/host is available.
- ## Privacy / opt-out
+ ## Hard Do-Nots
- Aggregate counts only — raw tool arguments and results are never stored or
- transmitted. Local-first, zero network egress by default. Opt out via
- `AGENT_CONNECTOR_TELEMETRY=0` or `telemetry: { enabled: false }`. Network
- calibration (Anthropic `count_tokens`) and host-native turn capture are opt-in only.
+ - Do not use agent-connector to write a brand-new MCP server protocol
+ implementation. It deploys and measures an existing server command/URL.
+ - Do not present global `@ken-jo/agent-connector` install as the normal user
+ install path for a branded MCP package.
+ - Do not claim connector-free `usage` can report per-MCP or per-tool cost.
+ - Do not duplicate package metadata in `defineConnector` unless there is a real
+ override case.
+ - Do not silently drop unsupported host surfaces; the expected behavior is
+ native support, disabled, or skip-warn with a reason.