[BUG] claude_code.pull_request.count matches MCP tool names, not pull requests — misses tools that put the verb in an argument (follow-up to #45776)

Status Open
Reported on v2.1.232
Maintainer reply None cached
Activity 0 comments · opened Aug 14, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

claude_code.pull_request.count appears to match on the NAME of the MCP tool invoked,
not on a pull request actually being created. This is a follow-up to #45776 ("PR
count not emitted via MCP tools"), which was closed as completed — the fix that
followed is incomplete and, separately, unsound.

Confirmed with a local no-op MCP server (no network, no auth, no repo — just a
tool that returns a fixed string) exposing five identically-implemented tools that
differ only in name:

| Tool name | Counted? |
|-----------------------------|----------|
| create_pull_request | yes |
| create_merge_request | yes |
| createPullRequest | yes |
| repo_pull_request_write | no |
| create_pr_stub (control) | no |

No pull request existed in any of these five cases. The matcher appears to require
a create-verb AND a pull/merge-request noun IN THE TOOL NAME. This explains two
real-world consequences:

  1. It fires with zero PRs created, for any tool merely named right.
  2. It misses tools that express the verb as an ARGUMENT instead of the name —

notably Microsoft's official Azure DevOps MCP server (@azure-devops/mcp), whose
PR tool is repo_pull_request_write with action: "create". A real, successful,
published PR created via that tool produced zero datapoints, while the same repo/
project/user creating a real PR via a third-party ADO MCP server
(@tiberriver256/mcp-server-azure-devops, tool name create_pull_request) DID
count. Also confirms #45776's own GitLab case (create_merge_request) genuinely
works now — this is not a re-report of that issue.

What Should Happen?

The counter should increment once per pull request actually created, regardless of
the MCP server or tool name used to create it, and should not increment when no
pull request exists.

Error Messages/Logs

No errors. The metric is silently absent or silently present-but-wrong — there is
no signal that anything is misdetected, which is what made this expensive to
diagnose (it reads as "low MCP-based PR creation" rather than "broken instrumentation").

Steps to Reproduce

Minimal repro — no Azure DevOps, no credentials, no real PR:

  1. Save this as server.py (or ask an AI assistant to write it): a stdio MCP server

exposing two tools, create_pull_request and create_pr_stub, each a pure
no-op returning a fixed string — no network call, no repository access.

  1. claude mcp add prcount-stub -- python3 /path/to/server.py
  2. Restart Claude Code.
  3. In one conversation turn, invoke create_pull_request. In a SEPARATE turn (so

the ~60s metric export windows don't overlap), invoke create_pr_stub.

  1. Inspect the OTLP metrics export ~60-120s after each call.

Expected: no datapoint for either (neither creates a PR).
Actual: create_pull_request produces claude_code.pull_request.count = 1.0;
create_pr_stub produces nothing.

Extending the same stub with repo_pull_request_write and create_merge_request (and
a camelCase createPullRequest) reproduces the yes/no table above and confirms the
matching rule is name-based, not outcome-based.

Second repro, with real Azure DevOps pull requests (no stub):

  1. Create a PR via Microsoft's official ADO MCP server (@azure-devops/mcp),

repo_pull_request_write, action=create. PR is created successfully.

  1. Check claude_code.pull_request.count — no datapoint.
  2. Create a PR the same way via a third-party ADO MCP server

(@tiberriver256/mcp-server-azure-devops), tool create_pull_request. PR is
created successfully.

  1. Check the metric again — datapoint of value 1.0 appears within ~60s.

Same repository, same project, same user, only the tool name differs.

Claude Model

Opus

Is this a regression?

No, this never worked

Last Working Version

_No response_

Claude Code Version

2.1.232 (Claude Code)

Platform

Anthropic API

Operating System

Other Linux

Terminal/Shell

WSL (Windows Subsystem for Linux)

Additional Information

Related, likely same root cause (name/shape-based detection instead of observing
actual VCS/PR state) — flagging in case maintainers want to track separately:

  • claude_code.commit.count counts per Bash invocation, not per commit. Two `git

commit` calls issued in a single Bash tool call produce ONE datapoint of value 1;
the same two commits split across two separate Bash calls produce two datapoints.
Agents routinely batch multiple commits into one shell call, so this
systematically undercounts. (Different from #20918, which reported counters stuck
at 1 — this is about batching within one export interval, not a stuck value.)

  • MCP tool identity is unobservable in telemetry without OTEL_LOG_TOOL_DETAILS,

which also emits full untruncated Bash command lines and so can't be enabled
where commands may contain secrets. A successful MCP call logs only
tool_name = "mcp_tool" on tool_result — never which MCP tool — unless that flag
is set. We could only see which tool was called when it FAILED, because the tool
name leaks inside the error string. Exposing MCP server/tool name independently
of full tool-call details would fix both this diagnosability gap and the general
inability to measure MCP adoption.

View original on GitHub ↗