---
title: "Report that one MCP tool fired. Fire-and-forget; records which tool ran, whether it succeeded, failed, or refused by design, and an opaque digest of the repository it ran in."
method: POST
path: "/api/v1/connection/tool-call"
tags: ["connection"]
---

# Report that one MCP tool fired. Fire-and-forget; records which tool ran, whether it succeeded, failed, or refused by design, and an opaque digest of the repository it ran in.

`POST /api/v1/connection/tool-call`

Called automatically by @pathmode/mcp-server once per tool invocation, in connected (cloud) mode ONLY — a keyless local-mode server makes no network request at all. Emits exactly one canonical PostHog MCP Analytics event, $mcp_tool_call, carrying the allowlisted tool name and outcome (also projected as $mcp_tool_name and $mcp_is_error); deliberately touches NO api_keys column, so a tool firing never moves last_used_at and the activation series stays comparable across the day this shipped. Accepts only tool, outcome, an optional refusal kind from a closed list, and an optional opaque repository digest; arguments, responses, agent intent, spec content, and paths are never accepted. Clients must treat failures, including 429, as non-fatal.

## Request body

- object
  - `tool` string, required — Name of the tool that ran, e.g. check_intent_readiness. Checked against the server's registered tool list; an unrecognised name is recorded as "unknown" rather than stored as given, so this field cannot carry spec content, paths, or anything else from the caller's repo.
  - `outcome` string, required — "ok", "error", or "refused". "refused" is a designed refusal, such as a preflight that cannot identify which repository it is about, and is kept out of the error rate. Anything else is recorded as "unknown".
  - `refusal` string — Optional, and kept only when outcome is "refused": which designed refusal it was, one of "repo_unresolved", "no_repo_intent", "ambiguous_roots", or "ambiguous_intent_files". Checked against that closed list, so this field cannot carry text from the caller's repo either.
  - `repo` string — Optional. A 32-character lowercase hex digest of the git remote the call happened in, used to count distinct repositories. Validated by shape, so nothing resembling a path or URL is accepted, and salted with your workspace before it is stored, so the same repository is one identity across every key in the workspace. Omit it when there is no network remote; the call is still recorded, just without repository granularity.

## Response `200`

OK — invocation recorded

- object

## Other responses

- `401` — Invalid/expired API key, or no Bearer key and no valid session cookie
- `429` — Rate limited (2000 pings per user per hour). Clients drop the datapoint and carry on.

## Changes

- **2026-09-23** `c014a089aa9c` — 1 info
  - added the new optional request property `refusal`
- **2026-08-31** `6fc9acd657bd` — 1 info
  - added the new optional request property `repo`
- **2026-08-26** `e10b1669489d` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/pathmode/apis/pathmode-api/changes/api/v1/connection/tool-call/post.md)

---

[API](https://skmtc.dev/pathmode/apis/pathmode-api.md) · [All operations](https://skmtc.dev/pathmode/apis/pathmode-api/llms.txt) · [OpenAPI document](https://skmtc.dev/pathmode/apis/pathmode-api/revisions/0f4a7b92b504?raw)
