* feat(agent-core): unify the v1 MCP management plane - McpServerRegistry: one config view over global (layered mcp.json), plugin (manifests, read-only, final effective config), and caller (SDK-injected) servers; name collisions keep both entries. - Write plane: add/update/removeGlobalMcpServer mutate the user-level file and push into live sessions; getGlobalMcpServer returns the effective config; mutations of read-only entries are rejected. - testGlobalMcpServer accepts an inline config; addSessionMcpServer connects a server in one live session with an optional persist flag; reconnect accepts a replacement config and re-resolves via the registry. - One process-wide McpOAuthService shared with every session: obtained_at stamps, offline token state, single-flight and proactive refresh, and credential events. Sessions self-subscribe in the constructor, so even initializing sessions see every event; token writes serialize through the process-local OAuthTokenTransaction per credential identity. - inspectAppMcpServers + locator-addressed begin/complete/cancel/reset cover plugin servers; inspection output redacts env/headers to sorted key lists; locator OAuth ops reject ambiguous shared runtime names. - The legacy auth-status surface reads the registry (offline by default, verify=true probes) and never mutates credentials. - VS Code panel receives source/origin/mutable and hides mutating actions on read-only entries. - v2 client facade in node-sdk mirrors the surface over agent-core-v2 (plugin inventory stays v1-only for now). * fix(agent-core): close the v1 MCP live-session reconciliation gaps Recompute each live session's MCP target from the registry's runtime resolution (enabled plugin > project layer > user file; caller injection shadows everything) behind every config mutation, instead of per-path patching: shadowed file layers recover when a plugin winner is disabled or removed, removing a user-level entry resurrects its project-layer shadow, disabled plugin descriptors no longer block removals, persisted session adds validate against the session's project layer and broadcast to other live sessions, and per-session sync failures are logged with context. Session status entries and read-only management entries now report redacted config views (envKeys/headerKeys instead of literal env/headers values); core-internal reconciliation compares full configs via the connection manager's raw-entry accessor. OAuth: interactive flows are serialized per credential (concurrent begins join the in-flight flow instead of clobbering its PKCE/state), a malformed credential meta sidecar no longer aborts core start, grants inside the refresh-ahead window refresh immediately while far-future grants re-arm through a max-length timer, and the service shuts its timers and flows down with KimiCore/SDKRpcClient close. * fix(agent-core): route the proactive MCP OAuth refresh through the token transaction refreshNow ran its /token request with the SDK default fetch, outside the credential-serializing OAuthTokenTransaction that every other token write uses; a slower response carrying an older rotating refresh token could overwrite a newer grant written by a concurrent transport-side refresh. * fix(agent-core): keep disabled MCP servers out of auth-state classification The unified mcpServerAuthState dropped the previous enabled short-circuit, so a disabled oauth-flagged server reported oauth-required — or was even probed over the network — instead of not-applicable. * fix(kimi-code-sdk): short-circuit disabled MCP servers in the v2 auth-status classifier The v2 parity copy of v1's mcpServerAuthState missed the same enabled guard v1 just regained; a disabled oauth-flagged entry would report oauth-required (or be probed). The parity suite now pins the disabled case on both engines. * fix(kimi-code): refresh the VS Code MCP list with the workspace cwd after mutations The add/update/remove RPCs return a cwd-less management list, so the webview broadcast dropped project-layer entries until the next full load; re-list with the workspace cwd after every mutation instead. * fix(agent-core): keep SDK token saves matched to the OAuth token transaction saveTokens stamped obtained_at onto a fresh object before calling tokenTransaction.save, so it never matched the exact payload the transaction recorded for a grant fetch; the consume path was dead and every save re-wrote. Between the fetch and the SDK callback an intervening clear could then be overwritten — the resurrected grant came back after a reset. The write callback stamps the durable record instead. * fix(agent-core): reject ambiguous legacy name-based MCP auth lookups The legacy begin/reset auth RPCs took the registry's first name match, silently starting OAuth for one entry of a runtime-name collision while the locator path refused the same ambiguity; align them on the shared uniqueness rule and point callers at the locator-addressed variants. * fix(agent-core): propagate registry errors during live-session MCP sync resolveMcpRuntimeTarget collapsed every registry failure into "no target": a project config file that turned malformed mid-session made sync treat a still-configured server as gone (tearing down the live connection) and made config-aware reconnects report "no longer configured" instead of the actionable config error. Absence still resolves to undefined; malformed config now propagates — per-session sync logs and keeps the entry, and reconnect surfaces config.invalid. * fix(agent-core): close the remaining registry-error and ambiguity gaps The management guard lookup mapped every registry failure to "absent", so a malformed project config let a persisted session add write a user-level entry over an unknown state; only not-found is a miss now. And the name-only connection test now shares the auth paths' uniqueness rule instead of probing the first match of a runtime-name collision. * fix(agent-core): probe the enabled MCP entry under a disabled-name collision The name-only connection test counted enabled matches for its ambiguity guard but still probed the first registry match, and the file layers list before plugins. With a disabled file entry shadowing an enabled plugin of the same runtime name, Test probed the disabled entry instead of the one a live session would run. Select the sole enabled match, falling back to the first entry only when every match is disabled so it reports as disabled. * fix(agent-core): let session-local MCP adds shadow plugin entries Caller injection shadows every registry source at session start, plugins included, and reconciliation leaves caller entries untouched; the live non-persist add path rejected plugin-owned names anyway, so SDK clients could not apply the same per-session override without a restart. Gate the plugin-source rejection on persist: session-local adds connect as caller, while persisted adds stay rejected as user-level writes behind a read-only owner. * fix(agent-core): normalize session MCP names before connecting The persisted store trims server names, but addSessionMcpServer used the raw name for the live connect and cross-session reconciliation: a padded name persisted under the trimmed key while the requesting session ran and reconciled the raw one, and a blank name connected with no identity at all. Normalize once up front (rejecting blank) so the store write, the session entry, and reconciliation agree on the same server. * fix(agent-core,node-sdk): close the collision-selection and probe-freshness gaps The legacy name-only auth resolver started from the first registry match, so a disabled file-layer shadow plus an enabled plugin of the same runtime name was misread as an ambiguity conflict; select the sole enabled match before judging ambiguity, exactly like the test probe path. On the v2 client, addSessionMcpServer connected the raw name while the store wrote the trimmed key — normalize once for both, and route the verify-triggered auth probes through the per-call OAuth service instead of the cached one whose providers snapshot tokens at construction, so a grant saved after the first probe is honored. * fix(agent-core): normalize global MCP mutation names and guard disabled reconnect swaps The global add/update/remove mutations guarded and reconciled with the raw server name while the store persisted the trimmed key, so a padded name left live sessions unreconciled and could slip past the plugin read-only guard; normalize once before lookup, persistence, and reconciliation. And a config-carrying reconnect assigned the replacement before the disabled check fired, leaving a connected entry that reported the disabled config; reject disabled replacements before mutating, keeping the same error. * fix(agent-core): skip proactive refresh while an interactive flow owns the credential refreshNow reset the shared provider's flow state before and after the token request; when a proactive timer (or a manual refresh) fired while beginAuthorization was waiting on the browser callback for the same store key, that wiped the redirect URL, PKCE verifier, and state the in-flight flow needed — complete() then failed the exchange even though the user authorized. Refresh now skips when an interactive flow is active for the credential: the flow delivers fresh tokens on completion, and the 401 transport path is the backstop if it fails. * fix(agent-core): allow global MCP adds over disabled plugin descriptors A disabled plugin entry is absent from the runtime target, but the read-only guard still treated it as the owner, so a user-level fallback could only exist if it predated the plugin disable. Relax the shared guard: disabled plugin descriptors never block mutations (disabled project entries still shadow the user file and keep their rejection). * fix(node-sdk): close the v2 session-MCP parity gaps A v2 reconnect with an explicit enabled:false replacement config used connect()'s upsert semantics — closing the live client and reporting success where v1's manager reconnect rejects before applying anything; reject disabled replacements up front with the same error. And a persisted v2 session add never consulted the workspace config, so a same-named project-layer entry was silently shadowed: the user-level write never takes effect while the direct workspace-manager upsert displaces the project config for every live session. Resolve the workspace layers and reject like v1's read-only rule. * fix(agent-core): keep __proto__-named MCP servers through config parsing A z.record() parse rebuilds its output via property assignment, so a server literally named __proto__ hit the prototype setter and vanished before validation; the layer merge then repeated the same trap with plain object accumulators. Parse the server map entry-by-entry over the JSON own keys and accumulate into null-prototype maps, so session startup and the unified registry keep the declared server and its origin. * fix(node-sdk): begin v2 MCP auth against a fresh OAuth service The v2 begin path ran through the cached globalMcpOAuth, whose providers snapshot tokens at construction: a grant another process saved (or reset) after that cache materialized was invisible, so begin could open a browser flow over a valid grant, or report already-authorized off a removed one. Build the service per call — the read path and the verify probes already do — and route the status list through the same helper. The test fixture grows a real token endpoint honoring one rotating refresh token; the regression fails against the cached-service implementation on v2. * fix(agent-core): broadcast SDK-driven MCP token invalidations to live sessions * test(agent-core-v2): give the no-op reconnect test runtime plumbing The branch added the case against a bare McpConnectionManager, but #2961 made stdio connects resolve the runtime through runtimeResolver, matching every other case in the file. |
||
|---|---|---|
| .. | ||
| .vscode | ||
| docs | ||
| resources | ||
| scripts | ||
| shared | ||
| src | ||
| test | ||
| webview-ui | ||
| .vscode-test.mjs | ||
| .vscodeignore | ||
| CHANGELOG.md | ||
| LICENSE | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| tsdown.config.ts | ||
| vitest.config.ts | ||
Kimi Code
AI coding assistant for VS Code, built for long-context workflows and complex coding tasks.
Features
- Works alongside you: Kimi autonomously explores your codebase, reads and writes code, and runs terminal commands with your permission
- Thinking controls: Toggle reasoning or choose a model-supported thinking effort
- Provider-aware models: Distinguish and select same-named models across configured providers
- Native editor integration: Review AI-proposed changes directly in VS Code's diff viewer
- MCP support: Extend capabilities with Model Context Protocol servers
- Slash commands: Quick actions like
/initto analyze your project and/compactto manage context
Install
Kimi Code requires VS Code 1.100.0 or later.
- Install from the VS Code Marketplace
- Open a folder in VS Code
- Click the Kimi icon in the Activity Bar
- Sign in with a kimi.com/code subscription, or use a provider already configured in the shared
config.toml
The extension runs the Kimi Code Node SDK in the VS Code Extension Host. When
the extension and the Kimi Code terminal app resolve to the same
KIMI_CODE_HOME, they share config.toml, MCP configuration, login state, and
sessions. The system-level KIMI_CODE_HOME environment variable is supported;
there is no separate VS Code setting for it. Do not run the same session from
both applications at the same time, because cross-process session locking is
not guaranteed.
After upgrading from version 0.5.x, the extension prompts before migrating any legacy data it finds. Migration copies or merges data into the current Kimi Code home and does not delete the legacy source. Legacy Kimi Code OAuth and MCP OAuth credentials are not copied, so those connections must be authorized again. See the changelog for the full compatibility notes.
Docs
Official doc for Kimi Code can be found at www.kimi.com/code/docs