@bastani/atomic 0.9.25-alpha.2 → 0.9.25-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +55 -0
- package/dist/builtin/intercom/package.json +2 -2
- package/dist/builtin/mcp/CHANGELOG.md +43 -0
- package/dist/builtin/mcp/OAUTH.md +59 -269
- package/dist/builtin/mcp/README.md +58 -345
- package/dist/builtin/mcp/index.bundle.mjs +4 -27792
- package/dist/builtin/mcp/native-client-licenses/LICENSES/modelcontextprotocol-typescript-sdk.txt +21 -0
- package/dist/builtin/mcp/native-client-licenses/NOTICE +30 -0
- package/dist/builtin/mcp/package.json +4 -25
- package/dist/builtin/subagents/package.json +3 -3
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/workflows/CHANGELOG.md +12 -0
- package/dist/builtin/workflows/builtin/{chunk-e1254zvd.js → chunk-kfsnh3w7.js} +40 -12
- package/dist/builtin/workflows/builtin/{chunk-cpw5gtzg.js → chunk-rqmasd3d.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-qy6g0baf.js → chunk-wz783pvd.js} +1 -1
- package/dist/builtin/workflows/builtin/goal.js +2 -2
- package/dist/builtin/workflows/builtin/index.js +3 -3
- package/dist/builtin/workflows/builtin/ralph.js +2 -2
- package/dist/builtin/workflows/package.json +2 -2
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +472 -88
- package/dist/builtin/workflows/src/index.js +65 -28
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +2 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session-accessors.d.ts.map +1 -1
- package/dist/core/agent-session-accessors.js +7 -0
- package/dist/core/agent-session-accessors.js.map +1 -1
- package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
- package/dist/core/agent-session-extension-bindings.js +103 -7
- package/dist/core/agent-session-extension-bindings.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +7 -1
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-state.d.ts.map +1 -1
- package/dist/core/agent-session-state.js +3 -2
- package/dist/core/agent-session-state.js.map +1 -1
- package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
- package/dist/core/agent-session-tool-registry.js +6 -3
- package/dist/core/agent-session-tool-registry.js.map +1 -1
- package/dist/core/agent-session-types.d.ts +1 -0
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/agent-session.d.ts +3 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +6 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/api-types.d.ts +3 -0
- package/dist/core/extensions/api-types.d.ts.map +1 -1
- package/dist/core/extensions/api-types.js.map +1 -1
- package/dist/core/extensions/context-types.d.ts +3 -1
- package/dist/core/extensions/context-types.d.ts.map +1 -1
- package/dist/core/extensions/context-types.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -0
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -0
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader-api.d.ts.map +1 -1
- package/dist/core/extensions/loader-api.js +15 -0
- package/dist/core/extensions/loader-api.js.map +1 -1
- package/dist/core/extensions/loader-runtime.d.ts.map +1 -1
- package/dist/core/extensions/loader-runtime.js +3 -0
- package/dist/core/extensions/loader-runtime.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +3 -0
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/extensions/mcp-server-registry.d.ts.map +1 -1
- package/dist/core/extensions/mcp-server-registry.js +4 -0
- package/dist/core/extensions/mcp-server-registry.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +4 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/runtime-types.d.ts +3 -0
- package/dist/core/extensions/runtime-types.d.ts.map +1 -1
- package/dist/core/extensions/runtime-types.js.map +1 -1
- package/dist/core/extensions/tool-types.d.ts +1 -0
- package/dist/core/extensions/tool-types.d.ts.map +1 -1
- package/dist/core/extensions/tool-types.js.map +1 -1
- package/dist/core/extensions/workflow-run-control-hub.d.ts +23 -0
- package/dist/core/extensions/workflow-run-control-hub.d.ts.map +1 -0
- package/dist/core/extensions/workflow-run-control-hub.js +57 -0
- package/dist/core/extensions/workflow-run-control-hub.js.map +1 -0
- package/dist/core/extensions/workflow-run-control.d.ts +163 -0
- package/dist/core/extensions/workflow-run-control.d.ts.map +1 -0
- package/dist/core/extensions/workflow-run-control.js +73 -0
- package/dist/core/extensions/workflow-run-control.js.map +1 -0
- package/dist/core/mcp-child-policy.d.ts +11 -0
- package/dist/core/mcp-child-policy.d.ts.map +1 -0
- package/dist/core/mcp-child-policy.js +31 -0
- package/dist/core/mcp-child-policy.js.map +1 -0
- package/dist/core/mcp-servers.d.ts +34 -25
- package/dist/core/mcp-servers.d.ts.map +1 -1
- package/dist/core/mcp-servers.js +148 -1
- package/dist/core/mcp-servers.js.map +1 -1
- package/dist/core/package-manager-manifest.js.map +1 -1
- package/dist/core/package-manager-mcp-servers.js +1 -1
- package/dist/core/package-manager-mcp-servers.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +4 -9
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/sdk.js +11 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/tool-loadout.d.ts +1 -0
- package/dist/core/tool-loadout.d.ts.map +1 -1
- package/dist/core/tool-loadout.js +3 -0
- package/dist/core/tool-loadout.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +11 -30
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/truncate.d.ts +8 -0
- package/dist/core/tools/truncate.d.ts.map +1 -1
- package/dist/core/tools/truncate.js +24 -0
- package/dist/core/tools/truncate.js.map +1 -1
- package/dist/extensions/codemode/execute.d.ts.map +1 -1
- package/dist/extensions/codemode/execute.js +26 -0
- package/dist/extensions/codemode/execute.js.map +1 -1
- package/dist/extensions/codemode/renderer.d.ts.map +1 -1
- package/dist/extensions/codemode/renderer.js +38 -23
- package/dist/extensions/codemode/renderer.js.map +1 -1
- package/dist/extensions/codemode/tool.d.ts.map +1 -1
- package/dist/extensions/codemode/tool.js +22 -10
- package/dist/extensions/codemode/tool.js.map +1 -1
- package/dist/extensions/mcp/cli.d.ts +21 -0
- package/dist/extensions/mcp/cli.d.ts.map +1 -0
- package/dist/extensions/mcp/cli.js +500 -0
- package/dist/extensions/mcp/cli.js.map +1 -0
- package/dist/extensions/mcp/cli.lazy.d.ts +3 -0
- package/dist/extensions/mcp/cli.lazy.d.ts.map +1 -0
- package/dist/extensions/mcp/cli.lazy.js +3 -0
- package/dist/extensions/mcp/cli.lazy.js.map +1 -0
- package/dist/extensions/mcp/client/auth-provider.d.ts +15 -0
- package/dist/extensions/mcp/client/auth-provider.d.ts.map +1 -0
- package/dist/extensions/mcp/client/auth-provider.js +2 -0
- package/dist/extensions/mcp/client/auth-provider.js.map +1 -0
- package/dist/extensions/mcp/client/client.d.ts +89 -0
- package/dist/extensions/mcp/client/client.d.ts.map +1 -0
- package/dist/extensions/mcp/client/client.js +457 -0
- package/dist/extensions/mcp/client/client.js.map +1 -0
- package/dist/extensions/mcp/client/index.d.ts +9 -0
- package/dist/extensions/mcp/client/index.d.ts.map +1 -0
- package/dist/extensions/mcp/client/index.js +7 -0
- package/dist/extensions/mcp/client/index.js.map +1 -0
- package/dist/extensions/mcp/client/oauth/callback.d.ts +42 -0
- package/dist/extensions/mcp/client/oauth/callback.d.ts.map +1 -0
- package/dist/extensions/mcp/client/oauth/callback.js +106 -0
- package/dist/extensions/mcp/client/oauth/callback.js.map +1 -0
- package/dist/extensions/mcp/client/oauth/discovery.d.ts +27 -0
- package/dist/extensions/mcp/client/oauth/discovery.d.ts.map +1 -0
- package/dist/extensions/mcp/client/oauth/discovery.js +153 -0
- package/dist/extensions/mcp/client/oauth/discovery.js.map +1 -0
- package/dist/extensions/mcp/client/oauth/errors.d.ts +24 -0
- package/dist/extensions/mcp/client/oauth/errors.d.ts.map +1 -0
- package/dist/extensions/mcp/client/oauth/errors.js +46 -0
- package/dist/extensions/mcp/client/oauth/errors.js.map +1 -0
- package/dist/extensions/mcp/client/oauth/flow.d.ts +82 -0
- package/dist/extensions/mcp/client/oauth/flow.d.ts.map +1 -0
- package/dist/extensions/mcp/client/oauth/flow.js +292 -0
- package/dist/extensions/mcp/client/oauth/flow.js.map +1 -0
- package/dist/extensions/mcp/client/oauth/index.d.ts +7 -0
- package/dist/extensions/mcp/client/oauth/index.d.ts.map +1 -0
- package/dist/extensions/mcp/client/oauth/index.js +6 -0
- package/dist/extensions/mcp/client/oauth/index.js.map +1 -0
- package/dist/extensions/mcp/client/oauth/provider.d.ts +59 -0
- package/dist/extensions/mcp/client/oauth/provider.d.ts.map +1 -0
- package/dist/extensions/mcp/client/oauth/provider.js +116 -0
- package/dist/extensions/mcp/client/oauth/provider.js.map +1 -0
- package/dist/extensions/mcp/client/oauth/types.d.ts +77 -0
- package/dist/extensions/mcp/client/oauth/types.d.ts.map +1 -0
- package/dist/extensions/mcp/client/oauth/types.js +109 -0
- package/dist/extensions/mcp/client/oauth/types.js.map +1 -0
- package/dist/extensions/mcp/client/protocol/content.d.ts +82 -0
- package/dist/extensions/mcp/client/protocol/content.d.ts.map +1 -0
- package/dist/extensions/mcp/client/protocol/content.js +41 -0
- package/dist/extensions/mcp/client/protocol/content.js.map +1 -0
- package/dist/extensions/mcp/client/protocol/jsonrpc.d.ts +59 -0
- package/dist/extensions/mcp/client/protocol/jsonrpc.d.ts.map +1 -0
- package/dist/extensions/mcp/client/protocol/jsonrpc.js +67 -0
- package/dist/extensions/mcp/client/protocol/jsonrpc.js.map +1 -0
- package/dist/extensions/mcp/client/protocol/types.d.ts +123 -0
- package/dist/extensions/mcp/client/protocol/types.d.ts.map +1 -0
- package/dist/extensions/mcp/client/protocol/types.js +7 -0
- package/dist/extensions/mcp/client/protocol/types.js.map +1 -0
- package/dist/extensions/mcp/client/testing/index.d.ts +2 -0
- package/dist/extensions/mcp/client/testing/index.d.ts.map +1 -0
- package/dist/extensions/mcp/client/testing/index.js +2 -0
- package/dist/extensions/mcp/client/testing/index.js.map +1 -0
- package/dist/extensions/mcp/client/transports/in-memory.d.ts +19 -0
- package/dist/extensions/mcp/client/transports/in-memory.d.ts.map +1 -0
- package/dist/extensions/mcp/client/transports/in-memory.js +50 -0
- package/dist/extensions/mcp/client/transports/in-memory.js.map +1 -0
- package/dist/extensions/mcp/client/transports/stdio.d.ts +32 -0
- package/dist/extensions/mcp/client/transports/stdio.d.ts.map +1 -0
- package/dist/extensions/mcp/client/transports/stdio.js +201 -0
- package/dist/extensions/mcp/client/transports/stdio.js.map +1 -0
- package/dist/extensions/mcp/client/transports/streamable-http.d.ts +96 -0
- package/dist/extensions/mcp/client/transports/streamable-http.d.ts.map +1 -0
- package/dist/extensions/mcp/client/transports/streamable-http.js +456 -0
- package/dist/extensions/mcp/client/transports/streamable-http.js.map +1 -0
- package/dist/extensions/mcp/client/transports/transport.d.ts +28 -0
- package/dist/extensions/mcp/client/transports/transport.d.ts.map +1 -0
- package/dist/extensions/mcp/client/transports/transport.js +38 -0
- package/dist/extensions/mcp/client/transports/transport.js.map +1 -0
- package/dist/extensions/mcp/config.d.ts +72 -0
- package/dist/extensions/mcp/config.d.ts.map +1 -0
- package/dist/extensions/mcp/config.js +158 -0
- package/dist/extensions/mcp/config.js.map +1 -0
- package/dist/extensions/mcp/index.d.ts +76 -0
- package/dist/extensions/mcp/index.d.ts.map +1 -0
- package/dist/extensions/mcp/index.js +1119 -0
- package/dist/extensions/mcp/index.js.map +1 -0
- package/dist/extensions/mcp/log.d.ts +16 -0
- package/dist/extensions/mcp/log.d.ts.map +1 -0
- package/dist/extensions/mcp/log.js +66 -0
- package/dist/extensions/mcp/log.js.map +1 -0
- package/dist/extensions/mcp/oauth.d.ts +103 -0
- package/dist/extensions/mcp/oauth.d.ts.map +1 -0
- package/dist/extensions/mcp/oauth.js +382 -0
- package/dist/extensions/mcp/oauth.js.map +1 -0
- package/dist/extensions/mcp/resources.d.ts +43 -0
- package/dist/extensions/mcp/resources.d.ts.map +1 -0
- package/dist/extensions/mcp/resources.js +262 -0
- package/dist/extensions/mcp/resources.js.map +1 -0
- package/dist/extensions/mcp/runtime.d.ts +104 -0
- package/dist/extensions/mcp/runtime.d.ts.map +1 -0
- package/dist/extensions/mcp/runtime.js +546 -0
- package/dist/extensions/mcp/runtime.js.map +1 -0
- package/dist/extensions/mcp/runtime.lazy.d.ts +3 -0
- package/dist/extensions/mcp/runtime.lazy.d.ts.map +1 -0
- package/dist/extensions/mcp/runtime.lazy.js +3 -0
- package/dist/extensions/mcp/runtime.lazy.js.map +1 -0
- package/dist/extensions/mcp/tools.d.ts +84 -0
- package/dist/extensions/mcp/tools.d.ts.map +1 -0
- package/dist/extensions/mcp/tools.js +251 -0
- package/dist/extensions/mcp/tools.js.map +1 -0
- package/dist/extensions/mcp/ui.d.ts +60 -0
- package/dist/extensions/mcp/ui.d.ts.map +1 -0
- package/dist/extensions/mcp/ui.js +175 -0
- package/dist/extensions/mcp/ui.js.map +1 -0
- package/dist/extensions/tool-search/tool.d.ts +1 -1
- package/dist/extensions/tool-search/tool.d.ts.map +1 -1
- package/dist/extensions/tool-search/tool.js +3 -13
- package/dist/extensions/tool-search/tool.js.map +1 -1
- package/dist/index-extensions.d.ts +2 -1
- package/dist/index-extensions.d.ts.map +1 -1
- package/dist/index-extensions.js +1 -1
- package/dist/index-extensions.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +7 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts +27 -3
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.js +39 -6
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
- package/docs/extensions/api-reference.md +3 -3
- package/docs/extensions/events.md +2 -0
- package/docs/extensions.md +8 -8
- package/docs/mcp-servers.md +171 -50
- package/docs/packages/authoring.md +2 -2
- package/docs/providers.md +8 -0
- package/docs/sdk/reference.md +16 -0
- package/docs/sdk.md +67 -1
- package/docs/settings.md +2 -0
- package/docs/tools.md +6 -0
- package/docs/workflows/operations.md +3 -1
- package/examples/extensions/built-in-tool-renderer.ts +16 -40
- package/examples/extensions/minimal-mode.ts +28 -108
- package/npm-shrinkwrap.json +69 -69
- package/package.json +8 -8
- package/dist/builtin/mcp/app-bridge.bundle.js +0 -67
- package/dist/builtin/mcp/xdg-open +0 -1267
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,61 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.9.25-alpha.4] - 2026-09-30
|
|
6
|
+
|
|
7
|
+
### Breaking Changes
|
|
8
|
+
|
|
9
|
+
- Replaced the old MCP adapter with the native client. Only `~/.atomic/agent/mcp.json` and trusted `.atomic/mcp.json` are read, using the native configuration shape. Shared config layers, client imports, and old-field translations are no longer supported; old OAuth credentials are not imported.
|
|
10
|
+
- MCP tools now use `mcp__<server>__<tool>` names and default to `codemode` exposure. The old gateway, configurable prefixes, lazy/idle lifecycle settings, metadata cache, SSE transport, MCP Apps rendering, and setup command are removed. Enabled servers connect in the background; `/mcp reconnect` without a name selects one server rather than reconnecting every server.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- MCP servers can set `oauth.authServerMetadataUrl` to a trusted authorization server metadata document when discovery advertises the wrong server or none. See [MCP authentication](docs/mcp-servers.md#override-oauth-authorization-server-discovery) ([#10172](https://github.com/earendil-works/pi/issues/10172)).
|
|
15
|
+
- Added `/mcp login [server]`, command completion, and server selection for login, logout, and reconnect. The manager offers per-server action menus for enabled state and tool exposure, and OAuth sign-in accepts a pasted redirect URL when the browser is on another machine.
|
|
16
|
+
- MCP servers support `codemode`, `deferred`, `direct`, and `hidden` exposure with per-tool pattern overrides, standard resource list/read tools, and per-server OAuth callback ports and URLs. See [MCP servers](docs/mcp-servers.md).
|
|
17
|
+
- Added shell commands `atomic mcp add`, `remove`, `list`, `login`, and `logout` to configure, check, and authenticate file-configured servers without starting a session.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- MCP now uses pi's native client, tool exposure, resources, and server manager. Calls, including codemode calls, pass through Atomic's tool permission pipeline. Native OAuth credentials are stored in `mcp-auth.json`.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- MCP OAuth rejects authorization responses from another issuer, including a missing `iss` when the server promises it under RFC 9207.
|
|
26
|
+
- MCP OAuth sign-in and refresh now tolerate empty or null optional token and registration fields, and empty requested scopes use the next scope source ([#10266](https://github.com/earendil-works/pi/issues/10266)).
|
|
27
|
+
- MCP sign-out no longer lets an in-progress OAuth refresh restore deleted credentials.
|
|
28
|
+
- Session shutdown now closes MCP connections that are still opening instead of leaving them running after the session ends.
|
|
29
|
+
- Replacing an extension-contributed MCP server now retires pending connections, and reloading with active servers no longer fails during connection cleanup.
|
|
30
|
+
- Malformed MCP configuration errors no longer quote file contents that may contain credentials.
|
|
31
|
+
- MCP OAuth refreshes authorization-server discovery when a server advertises a changed metadata URL.
|
|
32
|
+
|
|
33
|
+
## [0.9.25-alpha.3] - 2026-09-30
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- SDK hosts can now manage the workflow runs their session owns through `session.workflows`: `listRuns()`, `getRun()`, `getStages()`, `pause()`, `quit()` and `resume()` return the workflow tool's structured results, and failures reject with typed `WorkflowRunControlError` subclasses (`WorkflowRunNotFoundError`, `WorkflowRunOwnershipError`, `WorkflowRunNotResumableError`, `WorkflowRunDatabaseError`, `WorkflowStageNotFoundError`, `WorkflowStageAmbiguousError`, `WorkflowStageResumeUnsupportedError`) instead of strings. A batch `pause({ all: true })` or `quit({ all: true })` returns a `partial` outcome whose `failedRuns` names the runs still active only when that call stopped at least one run, and rejects with `WorkflowRunControlError` carrying `failedRuns` when active runs could not be stopped and the call stopped none, even if other runs were already paused. Already-paused and already-ended runs are not failures. A database outage while checking who owns a run rejects `pause()` and `quit()` with `WorkflowRunDatabaseError`. It uses the same ownership and durable-resume rules as the `workflow` tool, so runs owned by another session or live process stay read-only ([#3377](https://github.com/bastani-inc/atomic/issues/3377)).
|
|
38
|
+
- Codemode scripts can retrieve namespace summaries, instructions, and callable tool names with `describeNamespace(name)`. Tool search indexes namespace instructions without including them in inline tool listings, and codemode listings no longer include tool counts ([#10212](https://github.com/earendil-works/pi/issues/10212)).
|
|
39
|
+
- `/reload` enables tools newly added to `defaultTools`, while preserving session-disabled tools, tools removed from the setting, and explicit CLI tool restrictions ([#10245](https://github.com/earendil-works/pi/issues/10245)).
|
|
40
|
+
- Added Anthropic workload identity federation from the `ANTHROPIC_FEDERATION_RULE_ID`, `ANTHROPIC_ORGANIZATION_ID`, and `ANTHROPIC_IDENTITY_TOKEN_FILE` environment variables, with optional `ANTHROPIC_SERVICE_ACCOUNT_ID` and `ANTHROPIC_WORKSPACE_ID`. See [Providers](docs/providers.md#anthropic-workload-identity-federation) ([#10177](https://github.com/earendil-works/pi/issues/10177), [#10242](https://github.com/earendil-works/pi/pull/10242) by [@philfreo](https://github.com/philfreo)).
|
|
41
|
+
- MCP servers can set `oauth.clientName` for dynamic OAuth registration, or use `"auth": { "provider": "<provider>" }` to send the current provider login token. Provider-token authentication is restricted to global configuration and extension registrations, with HTTPS required except on loopback hosts. See [MCP authentication](docs/mcp-servers.md#authentication) ([#10226](https://github.com/earendil-works/pi/issues/10226)).
|
|
42
|
+
- `/login anthropic` now offers **Copy code login (headless)** when the browser is on another machine and cannot reach Atomic's local callback ([#10194](https://github.com/earendil-works/pi/pull/10194) by [@lucasmeijer](https://github.com/lucasmeijer)).
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- On a heavily loaded machine, a workflow run could fail with a bare `Query read timeout` while Atomic verified its managed PostgreSQL connection, even though the database was healthy. Health queries now get more time (3 s) on every path, and both the check of a borrowed connection and Atomic's periodic background health check repeat once after a timeout. If the timeout persists, the run fails with a resumable database-unavailable error instead of `Query read timeout`, and other running workflows' database connections are not closed and PostgreSQL is not restarted. A refused or terminated connection, a server shutdown, or a changed database identity is still treated as an outage.
|
|
47
|
+
- Renderer examples now retain the built-in tools' prompt guidance and execution behavior when customizing their display ([#10072](https://github.com/earendil-works/pi/issues/10072)).
|
|
48
|
+
- Reduced model lookup overhead when merging large remote provider catalogs.
|
|
49
|
+
- Invalid extension commands now fail registration with a clear error instead of crashing slash-command completion ([#10054](https://github.com/earendil-works/pi/issues/10054)).
|
|
50
|
+
- Codemode and tool-search descriptions now remain unchanged when deferred tools register, preserving prompt stability while discovery continues to find those tools ([#10212](https://github.com/earendil-works/pi/issues/10212)).
|
|
51
|
+
- Collapsed codemode scripts and results now limit wrapped screen lines, so long single-line JSON no longer fills the transcript. Bash previews use the same cached visual-line component.
|
|
52
|
+
- In `codemode.mode: "only"`, the system prompt's tool list no longer advertises tools whose direct declarations are hidden ([#10192](https://github.com/earendil-works/pi/issues/10192)).
|
|
53
|
+
- Fixed context overflow detection for Z.AI CN endpoint `Prompt exceeds max length` errors ([#10208](https://github.com/earendil-works/pi/issues/10208)).
|
|
54
|
+
- Anthropic tools with strict-schema constraints the provider rejects now fall back to non-strict mode when strict sampling is preferred ([#9953](https://github.com/earendil-works/pi/issues/9953)).
|
|
55
|
+
- Provider retries now use exponential backoff when `Retry-After` contains an unparseable date ([#9571](https://github.com/earendil-works/pi/issues/9571)).
|
|
56
|
+
- MCP sign-in URLs remain clickable when they wrap, including inside the `/mcp` panel ([#10186](https://github.com/earendil-works/pi/issues/10186)).
|
|
57
|
+
- MCP tool names now use JavaScript-safe identifiers with deterministic suffixes for collisions and long names, consistently across direct tools, gateway discovery, and codemode ([#10239](https://github.com/earendil-works/pi/issues/10239)).
|
|
58
|
+
- Codemode `image()` now rejects malformed base64 and unsupported image types before saving a tool result, and detects the MIME type from the image data instead of trusting the supplied type ([#10215](https://github.com/earendil-works/pi/issues/10215)).
|
|
59
|
+
|
|
5
60
|
## [0.9.25-alpha.2] - 2026-09-30
|
|
6
61
|
|
|
7
62
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/intercom",
|
|
3
|
-
"version": "0.9.25-alpha.
|
|
3
|
+
"version": "0.9.25-alpha.4",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension providing a private coordination channel between parent and child agent sessions. Fork of: https://github.com/nicobailon/pi-intercom",
|
|
6
6
|
"contributors": [
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@bastani/atomic": "*",
|
|
47
|
-
"@earendil-works/pi-tui": "^0.99.
|
|
47
|
+
"@earendil-works/pi-tui": "^0.99.2",
|
|
48
48
|
"typebox": "*"
|
|
49
49
|
},
|
|
50
50
|
"peerDependenciesMeta": {
|
|
@@ -7,6 +7,49 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.9.25-alpha.4] - 2026-09-30
|
|
11
|
+
|
|
12
|
+
### Breaking Changes
|
|
13
|
+
|
|
14
|
+
- Replaced the old adapter with the native client. Only `~/.atomic/agent/mcp.json` and trusted `.atomic/mcp.json` are read, using the native configuration shape. Shared config layers, client imports, and old-field translations are no longer supported; old OAuth credentials are not imported.
|
|
15
|
+
- Tools now use `mcp__<server>__<tool>` names and default to `codemode` exposure. The old gateway, configurable prefixes, lazy/idle lifecycle settings, metadata cache, SSE transport, MCP Apps rendering, and setup command are removed. Enabled servers connect in the background; `/mcp reconnect` without a name selects one server rather than reconnecting all servers.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Set `oauth.authServerMetadataUrl` to use a trusted authorization server metadata document instead of discovery when an MCP server advertises the wrong authorization server or none ([#10172](https://github.com/earendil-works/pi/issues/10172)).
|
|
20
|
+
- Added `/mcp login [server]`, completion and optional server selection for login/logout/reconnect, and a server manager with enabled-state and exposure menus. Sign-in accepts pasted remote-browser redirect URLs.
|
|
21
|
+
- Added native tool exposure modes and per-tool patterns, standard resource list/read tools, and per-server OAuth `callbackPort` and `callbackUrl`.
|
|
22
|
+
- Added shell commands `atomic mcp add`, `remove`, `list`, `login`, and `logout` to configure, check, and authenticate file-configured servers without starting a session.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- Adopted pi's native MCP client, tool exposure, resources, and server manager. Calls, including codemode calls, use Atomic's permission pipeline. Native OAuth credentials are stored in `mcp-auth.json`.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- OAuth authorization codes are rejected before exchange when the response's `iss` names another issuer, or is missing when the authorization server promises it under RFC 9207.
|
|
31
|
+
- Empty or null optional OAuth token and client registration fields now count as absent. Refresh responses retain the previous refresh token when the new one is empty, and `expires_in: null` no longer immediately expires a token ([#10266](https://github.com/earendil-works/pi/issues/10266)).
|
|
32
|
+
- Empty OAuth scopes fall through to the configured scope instead of overriding it.
|
|
33
|
+
- Tool and resource listing now accepts an empty or null final pagination cursor ([#10266](https://github.com/earendil-works/pi/issues/10266)).
|
|
34
|
+
- Sign-out no longer lets an in-progress OAuth refresh restore deleted credentials.
|
|
35
|
+
- Session shutdown now closes MCP connections that are still opening instead of leaving them running after the session ends.
|
|
36
|
+
- Replacing or unregistering an extension-contributed server now retires its pending connection without leaving a detached transport running.
|
|
37
|
+
- Reloading a session with active MCP servers no longer fails during cleanup of the old connections.
|
|
38
|
+
- OAuth refreshes discovery when a server advertises a changed metadata URL instead of retaining the previous authorization server.
|
|
39
|
+
|
|
40
|
+
## [0.9.25-alpha.3] - 2026-09-30
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
|
|
44
|
+
- Set `oauth.clientName` to choose the client name sent during dynamic OAuth registration. The default is `atomic` ([#10226](https://github.com/earendil-works/pi/issues/10226)).
|
|
45
|
+
- HTTP MCP servers can set `"auth": { "provider": "<provider>" }` to send the current `/login` token of a provider as the bearer token instead of using MCP OAuth. The token is read for every request and is never stored by MCP. It is accepted only from the global `mcp.json` and extension registrations, requires `https` except on `localhost`, `127.0.0.1`, and `[::1]`, and is sent only to the server's origin.
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
|
|
49
|
+
- MCP sign-in now displays a clickable terminal hyperlink and a Cmd/Ctrl+click hint, including when the authorization URL wraps across lines ([#10186](https://github.com/earendil-works/pi/issues/10186)).
|
|
50
|
+
- MCP tool names now use JavaScript-safe identifiers. Tools whose names sanitize to the same identifier all receive deterministic hash suffixes, preventing codemode calls from reaching the wrong tool. Server names that differ only in `-` and `_` conflict ([#10239](https://github.com/earendil-works/pi/issues/10239)).
|
|
51
|
+
- Cached MCP tools now reconnect after `/login <provider>` when a provider-authenticated server needs sign-in, without requiring `/mcp reconnect`.
|
|
52
|
+
|
|
10
53
|
## [0.9.25-alpha.1] - 2026-09-29
|
|
11
54
|
|
|
12
55
|
### Changed
|
|
@@ -1,61 +1,36 @@
|
|
|
1
|
-
# OAuth
|
|
1
|
+
# MCP OAuth authentication
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Atomic supports OAuth authorization-code login with PKCE, authorization server discovery, dynamic client registration, and token refresh for HTTP MCP servers. Most servers need only a URL:
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- **Automatic OAuth endpoint discovery** (RFC 9728) - No manual configuration needed
|
|
10
|
-
- **Dynamic client registration** (RFC 7591) - No clientId needed for most servers
|
|
11
|
-
- **Automatic callback handling** - Built-in HTTP server handles callbacks automatically
|
|
12
|
-
- **Automatic token refresh** - SDK handles token refresh transparently
|
|
13
|
-
|
|
14
|
-
## Features
|
|
5
|
+
```json
|
|
6
|
+
{ "mcpServers": { "sentry": { "url": "https://mcp.sentry.dev/mcp" } } }
|
|
7
|
+
```
|
|
15
8
|
|
|
16
|
-
|
|
17
|
-
- ✅ **Automatic Callback Server** - No URL copying needed, browser redirects automatically
|
|
18
|
-
- ✅ **Dynamic Client Registration** - Automatically registers with OAuth servers
|
|
19
|
-
- ✅ **Auto-Discovery** - Discovers OAuth endpoints from server metadata
|
|
20
|
-
- ✅ **Automatic Token Refresh** - SDK handles expired tokens automatically
|
|
21
|
-
- ✅ **State Parameter Validation** - CSRF protection
|
|
22
|
-
- ✅ **Secure Token Storage** - Stored in `~/.pi/agent/mcp-oauth/<server>/tokens.json`
|
|
9
|
+
OAuth applies when the server has no static `Authorization` header or provider-token configuration. Keep personal credentials in user-global configuration, not shared project files.
|
|
23
10
|
|
|
24
|
-
##
|
|
11
|
+
## Sign in and out
|
|
25
12
|
|
|
26
|
-
|
|
13
|
+
Run `/mcp login sentry`, select the server in `/mcp` and choose **Sign in**, or run `atomic mcp login sentry` from a shell. Session commands without a name choose an eligible server when unambiguous or ask you to select one; shell commands require a server name.
|
|
27
14
|
|
|
28
|
-
|
|
15
|
+
Atomic opens the browser and displays a clickable authorization URL. Approve access in the browser. If it runs on another machine, such as an SSH client, paste the complete URL it was redirected to into Atomic's waiting sign-in prompt. Atomic validates the state and issuer before exchanging the code. Treat both authorization and redirect URLs as sensitive.
|
|
29
16
|
|
|
30
|
-
|
|
31
|
-
{
|
|
32
|
-
"mcpServers": {
|
|
33
|
-
"my-oauth-server": {
|
|
34
|
-
"url": "https://api.example.com/mcp"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
```
|
|
17
|
+
Successful login reconnects the server. Session login requires an interactive UI; shell login opens the browser without starting a session. Sign in before unattended work. Shell login waits up to 300 seconds by default; use `--timeout <seconds>` to change that budget. A running session uses new credentials on its next turn. If a server requests additional scope later, sign in again.
|
|
39
18
|
|
|
40
|
-
|
|
41
|
-
- Auto-detect if the server requires OAuth
|
|
42
|
-
- Discover OAuth endpoints from the server
|
|
43
|
-
- Register a dynamic client (if supported by the server)
|
|
44
|
-
- Handle the entire OAuth flow including callback
|
|
19
|
+
Run `/mcp logout sentry` or `atomic mcp logout sentry` to delete its stored credentials. Signing out is also available in the manager.
|
|
45
20
|
|
|
46
|
-
|
|
21
|
+
## Pre-registered clients
|
|
47
22
|
|
|
48
|
-
|
|
23
|
+
For servers without dynamic client registration:
|
|
49
24
|
|
|
50
25
|
```json
|
|
51
26
|
{
|
|
52
27
|
"mcpServers": {
|
|
53
|
-
"
|
|
54
|
-
"url": "https://
|
|
55
|
-
"auth": "oauth",
|
|
28
|
+
"example": {
|
|
29
|
+
"url": "https://mcp.example.com/mcp",
|
|
56
30
|
"oauth": {
|
|
57
|
-
"clientId": "
|
|
58
|
-
"clientSecret": "
|
|
31
|
+
"clientId": "registered-client",
|
|
32
|
+
"clientSecret": "${EXAMPLE_SECRET}",
|
|
33
|
+
"callbackPort": 8765,
|
|
59
34
|
"scope": "read write"
|
|
60
35
|
}
|
|
61
36
|
}
|
|
@@ -63,263 +38,78 @@ You can optionally provide a pre-registered client:
|
|
|
63
38
|
}
|
|
64
39
|
```
|
|
65
40
|
|
|
41
|
+
`clientSecret` is optional. It can reference an environment variable or use a whole-value `!command` expression. The redirect URI must match the client's registration.
|
|
66
42
|
|
|
43
|
+
| Option | Meaning |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| `clientId` | Pre-registered client ID. Omit it for dynamic registration. |
|
|
46
|
+
| `clientSecret` | Optional secret for a confidential client. |
|
|
47
|
+
| `scope` | Space-separated scopes when the server does not advertise them. Later requests are added to this value. |
|
|
48
|
+
| `clientName` | Dynamic registration name, default `atomic`. Sign out before registering under a changed name. |
|
|
49
|
+
| `callbackPort` | Port for `http://127.0.0.1:<port>/callback`. |
|
|
50
|
+
| `callbackUrl` | Another registered loopback redirect URI. |
|
|
51
|
+
| `authServerMetadataUrl` | Trusted authorization server metadata document to use instead of discovery. |
|
|
67
52
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
- `url` - The MCP server URL (required)
|
|
71
|
-
- `auth` - Set to `"oauth"` to force OAuth, `false` to disable, or omit to auto-detect
|
|
72
|
-
- `oauth.grantType` - `"authorization_code"` (default, browser flow) or `"client_credentials"` (non-interactive)
|
|
73
|
-
- `oauth.clientId` - Pre-registered client ID (optional, SDK tries dynamic registration if not provided)
|
|
74
|
-
- `oauth.clientSecret` - Client secret for confidential clients (optional)
|
|
75
|
-
- `oauth.scope` - Requested OAuth scopes (optional)
|
|
53
|
+
`callbackUrl` must use HTTP on `localhost`, `127.0.0.1`, or `[::1]`, without query or fragment. Atomic sends it as written. If it omits a port, Atomic adds `callbackPort` or a free port, as allowed for loopback redirects by RFC 8252. Use a fixed port when the client registration requires an exact URI.
|
|
76
54
|
|
|
77
|
-
|
|
55
|
+
## Override authorization server discovery
|
|
78
56
|
|
|
79
|
-
|
|
57
|
+
Atomic normally finds the authorization server through protected resource metadata and checks its metadata issuer. If a server advertises the wrong authorization server or none, configure the correct metadata document:
|
|
80
58
|
|
|
81
59
|
```json
|
|
82
60
|
{
|
|
83
61
|
"mcpServers": {
|
|
84
|
-
"
|
|
85
|
-
"url": "https://
|
|
86
|
-
"auth": "oauth",
|
|
62
|
+
"example": {
|
|
63
|
+
"url": "https://mcp.example.com/mcp",
|
|
87
64
|
"oauth": {
|
|
88
|
-
"
|
|
89
|
-
"clientId": "service-client-id",
|
|
90
|
-
"clientSecret": "service-client-secret",
|
|
91
|
-
"scope": "read write"
|
|
65
|
+
"authServerMetadataUrl": "https://example.okta.com/.well-known/openid-configuration"
|
|
92
66
|
}
|
|
93
67
|
}
|
|
94
68
|
}
|
|
95
69
|
}
|
|
96
70
|
```
|
|
97
71
|
|
|
98
|
-
|
|
72
|
+
The document may use RFC 8414 or OpenID Connect discovery. Atomic trusts it as configured, including its issuer, so only point it at a document you trust. The URL must use HTTPS except for HTTP on `localhost`, `127.0.0.1`, or `[::1]`.
|
|
99
73
|
|
|
100
|
-
|
|
74
|
+
An authorization response's `iss` must name the flow's authorization server. If the metadata promises `authorization_response_iss_parameter_supported`, the response must include `iss`. Mismatched or required-but-missing issuers are rejected before code exchange under RFC 9207. Pasted redirect URLs have the same checks as browser callbacks.
|
|
101
75
|
|
|
102
|
-
|
|
76
|
+
## Tokens and refresh
|
|
103
77
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
```
|
|
107
|
-
/mcp-auth my-oauth-server
|
|
108
|
-
```
|
|
78
|
+
Credentials are stored in `~/.atomic/agent/mcp-auth.json`, keyed by server URL. `ATOMIC_CODING_AGENT_DIR` relocates the agent directory. Tokens refresh when expired or rejected, and signing out removes the stored credentials.
|
|
109
79
|
|
|
110
|
-
|
|
80
|
+
Optional OAuth response fields that are empty or null count as absent, including `scope`, `refresh_token`, `id_token`, and `client_secret`. A refresh response with no new refresh token keeps the previous one. `expires_in: null` does not immediately expire an access token. Empty scope values fall through to the next scope source.
|
|
111
81
|
|
|
112
|
-
|
|
113
|
-
1. Start the callback server (configured port, default `19876`)
|
|
114
|
-
2. Discover OAuth endpoints automatically
|
|
115
|
-
3. Register a dynamic client (if no clientId provided)
|
|
116
|
-
4. Open your browser for authentication
|
|
117
|
-
5. Wait for the automatic callback
|
|
118
|
-
6. Complete the OAuth flow
|
|
119
|
-
7. Store tokens securely
|
|
120
|
-
|
|
121
|
-
### Step 2: Use the Server
|
|
122
|
-
|
|
123
|
-
Once authenticated, use the server normally:
|
|
124
|
-
|
|
125
|
-
```
|
|
126
|
-
mcp({ server: "my-oauth-server" })
|
|
127
|
-
mcp({ tool: "my-tool", args: '{"key": "value"}' })
|
|
128
|
-
```
|
|
82
|
+
Old adapter credential files are not imported. Sign in through `/mcp login <server>` or `atomic mcp login <server>` to authorize the native client.
|
|
129
83
|
|
|
130
|
-
|
|
131
|
-
- Adds the access token to requests
|
|
132
|
-
- Refreshes expired tokens automatically
|
|
133
|
-
- Re-authenticates if tokens are invalid
|
|
84
|
+
## Use a provider login instead
|
|
134
85
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
```
|
|
138
|
-
/mcp logout my-oauth-server
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## How It Works
|
|
142
|
-
|
|
143
|
-
### Authentication Flow
|
|
144
|
-
|
|
145
|
-
```
|
|
146
|
-
┌─────────┐ ┌──────────────┐ ┌─────────────────┐
|
|
147
|
-
│ Pi │────▶│ MCP Server │────▶│ OAuth Server │
|
|
148
|
-
│ │ │ │ │ │
|
|
149
|
-
│ 1. Init │ │ 2. Discovery │ │ 3. Register │
|
|
150
|
-
│ │ │ │ │ │
|
|
151
|
-
│ │◀────│ │◀────│ 4. Auth URL │
|
|
152
|
-
│ │ │ │ │ │
|
|
153
|
-
│ │────▶│ Callback │◀────│ 5. Browser │
|
|
154
|
-
│ │ │ Server │ │ Redirect │
|
|
155
|
-
│ │ │ │ │ │
|
|
156
|
-
│ │◀────│ │◀────│ 6. Code │
|
|
157
|
-
│ │ │ │ │ │
|
|
158
|
-
│ │────▶│ │────▶│ 7. Exchange │
|
|
159
|
-
│ │ │ │ │ │
|
|
160
|
-
│ │◀────│ │◀────│ 8. Tokens │
|
|
161
|
-
└─────────┘ └──────────────┘ └─────────────────┘
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### Auto-Discovery
|
|
165
|
-
|
|
166
|
-
The SDK attempts to discover OAuth endpoints using:
|
|
167
|
-
|
|
168
|
-
1. **RFC 9728 Metadata** - Fetches `/.well-known/oauth-protected-resource`
|
|
169
|
-
2. **WWW-Authenticate Header** - Parses `resource_metadata` from 401 responses
|
|
170
|
-
|
|
171
|
-
### Dynamic Client Registration
|
|
172
|
-
|
|
173
|
-
If no `clientId` is provided, the SDK:
|
|
174
|
-
|
|
175
|
-
1. Discovers the registration endpoint from OAuth metadata
|
|
176
|
-
2. Registers a new client with:
|
|
177
|
-
- `client_name`: "Pi Coding Agent"
|
|
178
|
-
- `redirect_uris`: `["http://localhost:<active-callback-port>/callback"]`
|
|
179
|
-
- `grant_types`: `["authorization_code", "refresh_token"]`
|
|
180
|
-
3. Stores the registered client credentials
|
|
181
|
-
|
|
182
|
-
### Callback Server
|
|
183
|
-
|
|
184
|
-
A Node.js HTTP server runs on `localhost` at path `/callback`:
|
|
185
|
-
|
|
186
|
-
- Preferred callback port is `19876` (or `MCP_OAUTH_CALLBACK_PORT` if set)
|
|
187
|
-
- For dynamic registration, if the preferred port is busy, the adapter scans forward for a free local port
|
|
188
|
-
- For pre-registered clients (`oauth.clientId`), the adapter requires the exact configured callback port
|
|
189
|
-
|
|
190
|
-
- Handles `code`, `state`, and `error` parameters
|
|
191
|
-
- Displays success/error HTML pages
|
|
192
|
-
- Validates state parameter for CSRF protection
|
|
193
|
-
- Has a 5-minute timeout for pending authorizations
|
|
194
|
-
- Rejects and removes pending authorization waiters during session restart/shutdown before replacement-session startup continues
|
|
195
|
-
|
|
196
|
-
## Token Storage
|
|
197
|
-
|
|
198
|
-
Tokens are stored per-server in `~/.pi/agent/mcp-oauth/<server>/tokens.json`:
|
|
86
|
+
A server can use a provider token instead of MCP OAuth:
|
|
199
87
|
|
|
200
88
|
```json
|
|
201
|
-
{
|
|
202
|
-
"tokens": {
|
|
203
|
-
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
204
|
-
"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
|
|
205
|
-
"expiresAt": 1709769600,
|
|
206
|
-
"scope": "read write"
|
|
207
|
-
},
|
|
208
|
-
"clientInfo": {
|
|
209
|
-
"clientId": "auto-registered-client-id",
|
|
210
|
-
"clientSecret": "auto-generated-secret"
|
|
211
|
-
},
|
|
212
|
-
"serverUrl": "https://api.example.com/mcp"
|
|
213
|
-
}
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
Example directory structure:
|
|
89
|
+
{ "mcpServers": { "radius": { "url": "https://radius.example/mcp", "auth": { "provider": "radius" } } } }
|
|
217
90
|
```
|
|
218
|
-
~/.pi/agent/mcp-oauth/
|
|
219
|
-
├── linear/
|
|
220
|
-
│ └── tokens.json
|
|
221
|
-
├── github/
|
|
222
|
-
│ └── tokens.json
|
|
223
|
-
└── ...
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
The `serverUrl` field ensures credentials are invalidated if the server URL changes.
|
|
227
|
-
|
|
228
|
-
## Security Considerations
|
|
229
|
-
|
|
230
|
-
### PKCE
|
|
231
|
-
|
|
232
|
-
All OAuth flows use PKCE with the S256 method, preventing authorization code interception attacks.
|
|
233
|
-
|
|
234
|
-
### State Parameter
|
|
235
|
-
|
|
236
|
-
A cryptographically secure random state parameter is generated for each flow and validated on callback.
|
|
237
|
-
|
|
238
|
-
### File Permissions
|
|
239
91
|
|
|
240
|
-
|
|
92
|
+
Run `/login radius`, then retry the MCP call. Atomic reads the current token for every request and does not copy it into MCP credential storage.
|
|
241
93
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
Credentials are tied to a specific server URL. If the URL changes, the credentials are invalidated and re-authentication is required.
|
|
94
|
+
This setting is accepted only in global configuration and extension registrations, not project files or package manifests. HTTPS is required except on exact loopback hosts. Tokens go only to the server's configured origin; only same-origin `307` and `308` redirects are followed.
|
|
245
95
|
|
|
246
96
|
## Troubleshooting
|
|
247
97
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
```json
|
|
257
|
-
{
|
|
258
|
-
"mcpServers": {
|
|
259
|
-
"server": {
|
|
260
|
-
"url": "https://api.example.com/mcp",
|
|
261
|
-
"auth": "oauth",
|
|
262
|
-
"oauth": {
|
|
263
|
-
"clientId": "your-client-id",
|
|
264
|
-
"scope": "read"
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
### "Dynamic client registration not supported"
|
|
272
|
-
|
|
273
|
-
Some servers require pre-registered clients. Obtain a client ID from your OAuth provider and add it to the config.
|
|
274
|
-
|
|
275
|
-
### Callback server already in use
|
|
276
|
-
|
|
277
|
-
For dynamic registration, if the preferred callback port is busy, the adapter scans for the next available local port.
|
|
278
|
-
|
|
279
|
-
For pre-registered OAuth clients (`oauth.clientId`), the callback redirect URI must match exactly. In that case, free the configured port or set `MCP_OAUTH_CALLBACK_PORT` to the registered port. For clients registered like Slack MCP's Claude-compatible `http://localhost:3118/callback`, set `MCP_OAUTH_CALLBACK_PORT=3118`.
|
|
280
|
-
|
|
281
|
-
### Browser doesn't open
|
|
282
|
-
|
|
283
|
-
If the browser fails to open (e.g., in SSH sessions), Atomic displays the exact complete authorization URL for manual login, including all paths and parameters (state, callback, PKCE, resource, and any credentials). These intentional login instructions are not diagnostic logs; transport and RPC error diagnostics remain redacted. Treat the displayed URL as sensitive and do not share it. Browser-launch failure still cancels the pending attempt, so its callback cannot complete authentication; configure a working browser opener and retry `/mcp-auth <server-name>`.
|
|
98
|
+
- **Sign-in required:** run `/mcp login <server>` before unattended calls.
|
|
99
|
+
- **Dynamic registration unavailable:** obtain a client ID from the provider and configure `oauth.clientId`.
|
|
100
|
+
- **Redirect mismatch or callback port busy:** compare `callbackPort` and `callbackUrl` with the registered URI. Free its port or update the registration.
|
|
101
|
+
- **Browser cannot reach Atomic:** paste the complete redirected URL into the waiting sign-in prompt.
|
|
102
|
+
- **Wrong authorization page:** check server metadata, then use `authServerMetadataUrl` only if you know the correct trusted document.
|
|
103
|
+
- **Issuer mismatch:** check the authorization server's metadata and callback behavior. Do not accept an unexpected issuer to bypass the failure.
|
|
104
|
+
- **Provider token missing or rejected:** run `/login <provider>` and retry.
|
|
284
105
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
The OAuth implementation uses the following modules:
|
|
288
|
-
|
|
289
|
-
- `mcp-auth.ts` - Auth storage and retrieval (per-server `tokens.json` files)
|
|
290
|
-
- `mcp-oauth-provider.ts` - SDK OAuthClientProvider implementation
|
|
291
|
-
- `mcp-callback-server.ts` - Node.js HTTP callback server
|
|
292
|
-
- `mcp-auth-flow.ts` - High-level auth flow using SDK transport
|
|
293
|
-
|
|
294
|
-
## SDK Integration
|
|
295
|
-
|
|
296
|
-
The implementation uses these SDK exports:
|
|
297
|
-
|
|
298
|
-
```typescript
|
|
299
|
-
import {
|
|
300
|
-
auth,
|
|
301
|
-
UnauthorizedError,
|
|
302
|
-
OAuthClientProvider,
|
|
303
|
-
} from "@modelcontextprotocol/sdk/client/auth.js"
|
|
304
|
-
|
|
305
|
-
import {
|
|
306
|
-
StreamableHTTPClientTransport,
|
|
307
|
-
} from "@modelcontextprotocol/sdk/client/streamableHttp.js"
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
The `McpOAuthProvider` class implements `OAuthClientProvider` and is passed to `StreamableHTTPClientTransport`:
|
|
311
|
-
|
|
312
|
-
```typescript
|
|
313
|
-
const transport = new StreamableHTTPClientTransport(url, {
|
|
314
|
-
authProvider: new McpOAuthProvider(serverName, serverUrl, config, callbacks),
|
|
315
|
-
})
|
|
316
|
-
```
|
|
106
|
+
For configuration, tool exposure, and connection diagnostics, see [MCP servers](../coding-agent/docs/mcp-servers.md).
|
|
317
107
|
|
|
318
108
|
## References
|
|
319
109
|
|
|
320
|
-
- [MCP
|
|
321
|
-
- [
|
|
322
|
-
- [
|
|
323
|
-
- [
|
|
324
|
-
- [
|
|
325
|
-
- [
|
|
110
|
+
- [MCP authorization](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization)
|
|
111
|
+
- [PKCE, RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636)
|
|
112
|
+
- [Dynamic client registration, RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591)
|
|
113
|
+
- [Authorization server metadata, RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414)
|
|
114
|
+
- [Authorization response issuer, RFC 9207](https://datatracker.ietf.org/doc/html/rfc9207)
|
|
115
|
+
- [Protected resource metadata, RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728)
|