mirror of
https://github.com/mcp-use/mcp-use.git
synced 2026-09-14 18:06:01 +08:00
d0107b3484
* fix(agent): count Anthropic cache tokens and stop message_delta erasing usage (#2127) * fix(agent): count Anthropic cache tokens and stop message_delta erasing usage Two counting bugs on the Anthropic path, both silent. Anthropic reports `input_tokens` net of the prompt cache and bills `cache_read_input_tokens` and `cache_creation_input_tokens` separately, so `input_tokens + output_tokens` is not what the call is charged on. It never sends `total_tokens`, so the computed branch is always the one that runs. A call billed on 21,623 tokens reported 123. `cache_creation_input_tokens` was not read anywhere in the repository, and Anthropic bills cache writes above the base rate. OpenAI is the opposite: its `cached_tokens` sits inside `prompt_tokens`, so adding it would double count. Only the Anthropic-shaped keys are summed, and a test pins that. Second, `tokenUsageFromRecord` returns every key and sets the ones it did not find to `undefined`. Anthropic's streaming `message_delta` carries `output_tokens` only, so `usage = { ...usage, ...deltaUsage }` overwrote `inputTokens` and `cachedInputTokens` with `undefined`, discarding what `message_start` had already reported. After any streamed call the whole input side of the accounting was gone, with nothing raised. `mergeTokenUsage` merges only defined values. It does not touch `totalTokens`, because whether a cache counter is additive is a provider question and that information is gone once usage has been normalised, so the caller owns the total. Three of the added tests fail on main. * fix(agent,inspector): one owner for the Anthropic total, and stop the inspector dropping cache Follow-up on the review. Four points were raised; three were right and are fixed, one would have introduced a bug and the reasoning is below. The same wrong total existed in a third place. `message_stop` recomputed it as `inputTokens + outputTokens`, so the fix at `message_delta` survived only because `??` short-circuited on the total already set. Two places knowing how Anthropic bills is how this drifts, so `message_stop` now owns it alone and `message_delta` just merges. Added an end-to-end test that drives real `message_start` then `message_delta` SSE through `streamChat`, rather than exercising `mergeTokenUsage` in isolation. On the base commit it reports `totalTokens: undefined`, not merely a wrong number, because the input counters were gone by the time `message_stop` ran. The inspector was dropping more than the new field. `InspectorTokenUsage` declares `cachedInputTokens` and `reasoningTokens`, the trace view reads them, and `inspectorTokenUsageFromUnknown` returned only `inputTokens`, `outputTokens` and `totalTokens`. Both have always rendered as absent whatever the provider sent. It also repeated the same input-plus-output total. Both fixed, and `cacheCreationInputTokens` is carried through. The merge test now seeds `cache_creation_input_tokens` too, since cache writes are billed above base rate and need the same protection as cache reads. Not done, deliberately: adding `cachedInputTokens` to the computed total inside `tokenUsageFromRecord`. On Anthropic that counter sits outside `input_tokens`; on OpenAI `cached_tokens` sits inside `prompt_tokens`. Once usage is normalised that distinction is gone, so summing it would double count OpenAI. Only the Anthropic-shaped keys are added, and a test pins the OpenAI case at 14. * style(inspector): run prettier on trace.ts format:check fails the typescript-lint job on this one file. Prettier wraps the cachedInputTokens call across three lines, the way the two calls below it already are. Formatting only, no behaviour change. * fix(inspector): aggregate cacheCreationInputTokens and stop double-counting OpenAI cache reads Addresses @khandrew1's review on #2127. addUsage dropped cacheCreationInputTokens: the field was parsed onto individual usage events but never summed, so it vanished from state.usage, the LLM span's usage, and the aggregate tokenUsage in the raw-chat payload. It is now summed alongside the other counters. The fallback total could also over-count. uncountedCache was built from the provider-neutral cachedInputTokens, but on OpenAI those tokens are already inside inputTokens, so { inputTokens: 10, outputTokens: 4, cachedInputTokens: 3 } totalled 17 instead of 14. The total now adds only the Anthropic-shaped cache_read_input_tokens, mirroring the provider-safe path in agent/src/llm/usage.ts. cachedInputTokens is still parsed and returned for observability. Two tests in trace.test.ts pin both: the OpenAI-vs-Anthropic total distinction, and that cacheCreationInputTokens survives aggregation and the LLM span. Changesets added for @mcp-use/agent and @mcp-use/inspector. * chore: enter canary prerelease mode * chore(typescript): version packages (canary) * fix(inspector): scope loading state by chat session (#2232) * fix(inspector): give each chat session one id and one state record Chat state lived in hook-wide React state, so starting a new chat cleared the values an in-flight stream was still writing to: the fresh chat inherited the previous session's loading state and could not send. Rework it around a single identity. A session is created with one id and keeps it; that id is handed to ChatStorageProvider.createChat, so runtime state, chat history and OAuth retry all name the same chat. All of a session's state and turn machinery live in one record inside ChatSessionStore, which notifies only the subscribers of the session that changed, so a background turn keeps streaming into its own record. useChatSessions owns the lifecycle: minting ids, activating a session, reattaching to persisted chats, and reopening the session a full-page OAuth redirect interrupted. New Chat now only switches the active id. Closes #2217 * refactor(inspector): simplify chat session state * fix(inspector): harden chat session recovery --------- Co-authored-by: Andrew Khadder <andrew@manufact.com> * chore(typescript): version packages (canary) * fix(ci): give inspector tests the same timeout as every other package (canary) (#2290) * fix(ci): give inspector tests the same timeout as every other package Same one-line change as #2268, which targets main. canary carries the same 10s cap and is failing on it independently: run 32053629834 compressed-assets.test.ts 10230ms Test timed out in 10000ms run 32051250836 same test main is red on it too (run 32054211669). Recent margins are 10029ms, 10230ms and 10837ms, all just over the cap. The inspector is the only package at 10s; agent, client, cli and server all use 60000, and these cases mount a server and decompress the bundled app. 45 files, 217 tests still pass locally. * chore(ci): remove timeout rationale comment --------- Co-authored-by: Andrew Khadder <andrew@manufact.com> * feat(oauth): add Scalekit provider (#2272) * feat(oauth): add Scalekit provider Add oauthScalekitProvider next to Auth0 and Clerk. The verifier accepts both environment-root and resource-scoped issuers, binds audience to the res_… resource id, and advertises DCR plus CIMD. No Scalekit SDK. * fix(oauth): keep Scalekit resource-id audience with extra aud Always verify aud includes the resource id. Optional audience is an extra AND check, not a replacement. Drop the new v1 provider page. * fix(oauth): drop Scalekit issuerBoundAccessTokens option Scalekit binds tokens to the resource id. The dashboard will own that opt-in. Keep the static oauthMetadata copy because mcp-use requires it. Custom claims stay on ctx.auth.payload. * docs: drop v1 and legacy skill changes * docs: fix Scalekit environment variables --------- Co-authored-by: Saif Shines <saifshine7@gmail.com> Co-authored-by: Andrew Khadder <andrew@manufact.com> * chore(typescript): version packages (canary) * fix(inspector): add a test script so pnpm test covers this package (#2289) * fix(inspector): add a test script so pnpm test covers this package The root test script is `pnpm run -r test`, and the inspector only had test:unit. pnpm skips a package with no matching script and reports nothing, so 217 unit tests were absent from the workspace-wide run: $ pnpm --filter @mcp-use/inspector test (no output) $ pnpm --filter @mcp-use/inspector test:unit Test Files 45 passed (45) Tests 217 passed (217) CI is unaffected; its step calls test:unit directly. This is the documented `pnpm test` contributors run. Uses run mode rather than watch, matching tunnel, so a recursive run cannot sit waiting on a watcher. * chore(inspector): remove test-only changeset --------- Co-authored-by: Andrew Khadder <andrew@manufact.com> * fix(types): align pnpm workspace tooling (#2301) * docs: update TypeScript release changelogs * fix(inspector): use secure chat session ids --------- Co-authored-by: Arthi Arumugam <62213284+arthi-arumugam-git@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Mert Çetin <97505365+merttcetn@users.noreply.github.com> Co-authored-by: Ayaan Gazali <ayaangazali.work@gmail.com> Co-authored-by: saif-at-scalekit <saif.shaik@scalekit.com> Co-authored-by: Saif Shines <saifshine7@gmail.com>
Mintlify Starter Kit
Click on Use this template to copy the Mintlify starter kit. The starter kit contains examples including
- Guide pages
- Navigation
- Customizations
- API Reference pages
- Use of popular components
Development
Install the Mintlify CLI to preview the documentation changes locally. To install, use the following command
npm i -g mintlify
Run the following command at the root of your documentation (where docs.json is)
mintlify dev
Publishing Changes
Install our Github App to auto propagate changes from your repo to your deployment. Changes will be deployed to production automatically after pushing to the default branch. Find the link to install on your dashboard.
Troubleshooting
- Mintlify dev isn't running - Run
mintlify installit'll re-install dependencies. - Page loads as a 404 - Make sure you are running in a folder with
docs.json