Announcing Beacon: Self-improving memory for coding agents
← All MCP servers
MCP server

io.github.whdrnr2583-cmd/token-meter

mcp:whdrnr2583-cmd/token-meter

Local-first dashboard + MCP for Claude Code and Codex token usage. Per-MCP/tool breakdown.

Verdict
No issues found

Nothing found that works against the person who installs it.

Analyzed Oct 29, 2026, 15:45 UTC at 36c01be

Dispute security verdict

If you believe this verdict is incorrect, submit a dispute and we'll review it.

0
findings
—
highest severity
0
threat classes
153
files scanned
506/506
checks satisfied
0
package advisories

Why this verdict

  • benign: 506 checks satisfied, nothing works against the installer of mcp-server:. (14 notes, 0 third-party flags)

Security findings 0

No security findings

Nothing found that works against the person who installs it.

Notes 14

Capabilities, vulnerabilities and disclosed behavior worth knowing. Nothing here works against the person who installs it, so notes never change the verdict.

Data exfiltration

mediumNoteConfirmed on reviewlow confidence

The proxy command forwards local LLM traffic to a user-supplied --backend URL, an operator-configured endpoint the user chooses and runs.

backend: flagVal('--backend')
vector:code
Reviewer's reasoning

The --backend URL is supplied by the user on the proxy command line, so the forwarding destination is operator-chosen configuration.

Persistence

mediumNoteConfirmed on reviewlow confidence

The install-mcp command, run by the user, registers the MCP server in client configs (claude-code, cursor, claude-desktop) through an unshipped module; the user invokes this step and sees its results.

const { installMcp } = await import('./install-mcp.js');
vector:code
Reviewer's reasoning

The install-mcp branch runs only when the user types the install-mcp command, which is declared in usage text as registering the MCP server.

Persistence

mediumNoteConfirmed on reviewlow confidence

The setup command, as its usage text states, adds a gating export to the user's shell rc files, which the user invokes deliberately; this is disclosed and the rc write code lives in an unshipped module.

activate + add gating export to ~/.zshrc / ~/.bashrc
vector:instruction
Reviewer's reasoning

The setup command is user-invoked and its usage text discloses the rc-file export, so under test 4 it is a note; the shown setup branch only prints and does not itself write rc files, which I cannot confirm from unshipped code.

Persistence

mediumNoteConfirmed on reviewmedium confidence

The user-invoked install step writes the slash-command file into the agent-wide ~/.claude/commands directory, overwriting after a backup; undeclared in the declared purpose but run only when the user installs.

writeFileSync(target, desired, 'utf8');
vector:code
Reviewer's reasoning

The slash-command file is written only when the user runs install-command, which is the declared purpose, and the existing file is backed up first.

Persistence

mediumNoteConfirmed on reviewmedium confidence

The user-invoked MCP installer merges a token-meter entry into the Cursor and Claude Desktop MCP config files, backing up the original; an agent-wide config write run only on user request.

writeFileSync(configPath, JSON.stringify(merged, null, 2)
vector:code
Reviewer's reasoning

The config merge runs only when the user requests install-mcp for Cursor or Claude Desktop, is declared in usage, and backs up the original file first.

Persistence

mediumNoteConfirmed on reviewmedium confidence

The user-invoked installer runs a shell command that registers the publisher's npx package as a Claude Code MCP server; a user-run step that adds an MCP config entry.

claude mcp add ${MCP_SERVER_NAME} -- npx -y ${MCP_PACKAGE} mcp
vector:code
Reviewer's reasoning

The claude mcp add command is a user-run installer step that registers the publisher's own package, which the note rule covers.

Persistence

mediumNoteConfirmed on reviewmedium confidence

The install-mcp command, run by the user, merges a token-meter entry into an agent's MCP client config file and rewrites it, backing up the prior file first; this writes agent control-plane configuration, but only on the user's explicit install step.

Read an MCP-style JSON config, merge `mcpServers["token-meter"]`, and write
vector:code
Reviewer's reasoning

The merge helper runs only on the user's explicit install step and documents a backup before rewriting, so it is a user-opted agent config write.

Credential access

mediumNoteConfirmed on reviewmedium confidence

Activation stores the user's license key in plaintext in ~/.tokenmeter/license.json (mode 0600) after a user-invoked activate; the key goes only to the publisher's own verify step.

license_key: trimmed,
vector:code
Reviewer's reasoning

The license key is written to a local file only after the user runs activate, and the key is sent only to the publisher's own verify endpoint, which issued it.

Data exfiltration

mediumNoteConfirmed on reviewmedium confidence

An environment variable redirects the license verification and activation endpoint, which then receives the license key; the operator controls this variable, so it is a note.

process.env.TOKEN_METER_API_BASE ?? API_BASE_DEFAULT
vector:code
Reviewer's reasoning

The environment variable is operator-set configuration chosen by the user, so the license key goes to a host the user directed, which the note rule covers.

Data exfiltration

mediumNoteConfirmed on reviewlow confidence

The local proxy forwards all incoming request headers, including any Authorization credential, and the body to the backend the user configured; disclosed and user-directed, so a note.

const headers = { ...req.headers };
vector:code
Reviewer's reasoning

The proxy forwards headers, including any API key, only to the backend the user configured for their own model client, which is disclosed and user-directed.

Data exfiltration

mediumNoteConfirmed on reviewmedium confidence

The rule webhook POSTs a usage summary (spend, event counts, top models) to a URL the user configured; the user directs the destination, so it is a note.

body: JSON.stringify(payload)
vector:code
Reviewer's reasoning

The webhook posts the usage summary only to a rule URL the user configured, so the user directs the destination and the data is the declared rule payload.

Supply chain

lowNoteConfirmed on reviewlow confidence

The dashboard page loads the chart.js library from the jsdelivr CDN at a pinned version without subresource integrity; this is a documented, pinned third-party dependency and is noted only.

<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.4/dist/chart.umd.min.js"></script>
vector:code
Reviewer's reasoning

The chart.js script is pinned to an exact version on a CDN, so it is a documented third-party dependency loaded by a local dashboard page; missing SRI is a hygiene issue, not a level-6 or level-7 case.

Agent hijacking

lowNoteConfirmed on reviewlow confidence

The slash-command template tells the agent to follow its steps exactly, suppress non-output comments, and print a verbatim Pro upsell block; this is the publisher's own product promotion the user sees and can decline.

다음 단계를 정확히 따르세요.
vector:instruction
Reviewer's reasoning

The template is a user-invoked slash command whose Pro promotion is the publisher's own disclosed product text, and the template tells the agent to omit only non-output comments; this does not steer the user against their interests beyond a promotion they can decline.

Supply chain

lowNoteConfirmed on reviewmedium confidence

The MCP entry launches the publisher's own package via unpinned npx -y, so the registered server fetches whatever is latest on each start; a note per the unpinned-publisher-package rule.

args: Object.freeze(['-y', MCP_PACKAGE, 'mcp'])
vector:code
Reviewer's reasoning

The MCP entry launches the publisher's own package without a version pin, which the note rule explicitly covers for the artifact's own launch path.

Open questions 2

What the analysis could not settle from the code alone.

[file request src/mcp.ts] Does startMcpServer or any code it loads call installCommand, installMcp, or activateLicense, or trigger install or license activation without a user-run install command?
Persistence
[file request src/cli.ts] Does any automatic path (startup, hook, postinstall, or the MCP server itself) call installCommand, installMcp, or activateLicense without a user-run install command?
Persistence