feat(mcp): count admitted initializes, the denominator the refusal counter needs #28

Merged
jlxq0 merged 1 commit from feat-initialize-admitted into main 2026-08-26 15:11:06 +00:00
Owner

Refs #21. The gap I filed two hours ago, closed.

What was wrong with v0.2.0's instrumentation

caldav_mcp_initialize_refusals_total was added to investigate how many sessions an identity opens. It cannot answer that. It counts only refusals, so there is no rate and no baseline. A night was spent on that question and the instrument built to investigate it was blind to it.

The general form, now in AGENTS.md: when adding a counter for a bad outcome, ask whether anyone will need the denominator. A refusal rate needs both halves and only one of them ever feels worth the line.

What this adds

  • caldav_mcp_initialize_admitted_total.
  • One info line per admitted initialize, carrying user_hash.

The per-identity count is in the log and not in a metric label, because a hash label is unbounded cardinality and identities do not belong in a metrics backend. user_hash reverses against a candidate list, which is exactly why it works in a log line and exactly why it must not become a label.

What it counts, stated so nobody reads it as more

It counts requests the limiter admitted. That is not the same as sessions rmcp went on to create: the limiter is the last gate observable outside the MCP router, and a request can pass it and still fail further in. The metric name says admitted rather than created for that reason.

It is still the denominator the refusal counter needs, and it is still the number #21 wants, because #21's claim is about how many initializes a workload costs rather than how many sessions survive.

Why it matters past this repo

#21's claim spans three servers. matrix-mcp established four session initializes in a few minutes by reading the call graph; m365-mcp established a fresh session per tool call the same way. Neither can produce a count. This is the only one of the three that can, and until this change it could not either.

matrix-mcp also flagged that the claude.ai connector and a Claude Code channel session may be different clients. If so, two clients showing one shape is a stronger fact about the ecosystem and a weaker one about any single implementation — and separating them needs per-identity acceptance counts, which is what the log line gives.

Verified by mutation

mutation died
admissions counted on the refusal family admitted_and_refused_are_counted_separately
admissions not counted at all same test

Both with the pattern asserted to apply and the harness checked for a test result: line. The test asserts the two are separate families, because sharing one would make the rate this pair exists to produce unreadable.

Gates

cargo fmt --check, cargo clippy -D warnings, cargo test --all-features (117 + 9), green on rustc 1.98.0, through the shared build slot.

Release

An instrument that exists and is not deployed answers nothing, which is tonight's lesson in one line. Tagging v0.2.1 after this merges, and the pod digest goes to Clark and Alan.

Refs #21. The gap I filed two hours ago, closed. ## What was wrong with v0.2.0's instrumentation `caldav_mcp_initialize_refusals_total` was added to investigate how many sessions an identity opens. **It cannot answer that.** It counts only refusals, so there is no rate and no baseline. A night was spent on that question and the instrument built to investigate it was blind to it. The general form, now in `AGENTS.md`: **when adding a counter for a bad outcome, ask whether anyone will need the denominator.** A refusal rate needs both halves and only one of them ever feels worth the line. ## What this adds - `caldav_mcp_initialize_admitted_total`. - One `info` line per admitted initialize, carrying `user_hash`. **The per-identity count is in the log and not in a metric label**, because a hash label is unbounded cardinality and identities do not belong in a metrics backend. `user_hash` reverses against a candidate list, which is exactly why it works in a log line and exactly why it must not become a label. ## What it counts, stated so nobody reads it as more It counts requests **the limiter admitted**. That is not the same as sessions `rmcp` went on to create: the limiter is the last gate observable outside the MCP router, and a request can pass it and still fail further in. The metric name says `admitted` rather than `created` for that reason. It is still the denominator the refusal counter needs, and it is still the number #21 wants, because #21's claim is about how many initializes a workload costs rather than how many sessions survive. ## Why it matters past this repo #21's claim spans three servers. `matrix-mcp` established four session initializes in a few minutes by reading the call graph; `m365-mcp` established a fresh session per tool call the same way. **Neither can produce a count.** This is the only one of the three that can, and until this change it could not either. `matrix-mcp` also flagged that the claude.ai connector and a Claude Code channel session may be different clients. If so, two clients showing one shape is a stronger fact about the ecosystem and a weaker one about any single implementation — and separating them needs per-identity acceptance counts, which is what the log line gives. ## Verified by mutation | mutation | died | |---|---| | admissions counted on the refusal family | `admitted_and_refused_are_counted_separately` | | admissions not counted at all | same test | Both with the pattern asserted to apply and the harness checked for a `test result:` line. The test asserts the two are **separate families**, because sharing one would make the rate this pair exists to produce unreadable. ## Gates `cargo fmt --check`, `cargo clippy -D warnings`, `cargo test --all-features` (117 + 9), green on `rustc 1.98.0`, through the shared build slot. ## Release An instrument that exists and is not deployed answers nothing, which is tonight's lesson in one line. Tagging `v0.2.1` after this merges, and the pod digest goes to Clark and Alan.
feat(mcp): count admitted initializes, the denominator the refusal counter needs
All checks were successful
CI / cargo (pull_request) Successful in 51s
CI / docker (pull_request) Successful in 57s
f0023d492f
v0.2.0 added a refusal counter to investigate how many sessions an identity was
opening. It cannot answer that. Counting only the bad outcome gives no rate and
no baseline, so the instrument built for the question was blind to it: built
for the failure, blind to the denominator.

An admitted initialize now increments caldav_mcp_initialize_admitted_total and
writes one info line carrying user_hash. The per-identity count lives in the log
rather than in a metric label, because a hash label is unbounded cardinality and
identities do not belong in a metrics backend.

It counts requests the limiter ADMITTED, which is not the same as sessions rmcp
went on to create. The limiter is the last gate observable outside the MCP
router, and the name says admitted rather than created so nobody reads it as
the stronger claim.

This is the number jlxq0/caldav-mcp#21 needs and that neither matrix-mcp nor
m365-mcp can produce: both established a fresh session per tool call by call
graph rather than by count.

Refs #21
jlxq0 merged commit 705fcddcfb into main 2026-08-26 15:11:05 +00:00
jlxq0 deleted branch feat-initialize-admitted 2026-08-26 15:11:06 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
jlxq0/caldav-mcp!28
No description provided.