@agent-native/core 0.18.1 → 0.19.1

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.
Files changed (168) hide show
  1. package/README.md +1 -11
  2. package/dist/a2a/caller-auth.d.ts +1 -0
  3. package/dist/a2a/caller-auth.d.ts.map +1 -1
  4. package/dist/a2a/caller-auth.js +1 -1
  5. package/dist/a2a/caller-auth.js.map +1 -1
  6. package/dist/a2a/client.d.ts +7 -0
  7. package/dist/a2a/client.d.ts.map +1 -1
  8. package/dist/a2a/client.js +3 -0
  9. package/dist/a2a/client.js.map +1 -1
  10. package/dist/agent/production-agent.d.ts +1 -1
  11. package/dist/agent/production-agent.d.ts.map +1 -1
  12. package/dist/agent/production-agent.js +34 -2
  13. package/dist/agent/production-agent.js.map +1 -1
  14. package/dist/cli/code-agent-executor.d.ts.map +1 -1
  15. package/dist/cli/code-agent-executor.js +47 -256
  16. package/dist/cli/code-agent-executor.js.map +1 -1
  17. package/dist/cli/connect.d.ts +94 -0
  18. package/dist/cli/connect.d.ts.map +1 -0
  19. package/dist/cli/connect.js +443 -0
  20. package/dist/cli/connect.js.map +1 -0
  21. package/dist/cli/index.js +16 -0
  22. package/dist/cli/index.js.map +1 -1
  23. package/dist/cli/mcp-config-writers.d.ts +71 -0
  24. package/dist/cli/mcp-config-writers.d.ts.map +1 -0
  25. package/dist/cli/mcp-config-writers.js +210 -0
  26. package/dist/cli/mcp-config-writers.js.map +1 -0
  27. package/dist/client/AgentPanel.d.ts +3 -1
  28. package/dist/client/AgentPanel.d.ts.map +1 -1
  29. package/dist/client/AgentPanel.js +4 -4
  30. package/dist/client/AgentPanel.js.map +1 -1
  31. package/dist/client/AssistantChat.d.ts +3 -0
  32. package/dist/client/AssistantChat.d.ts.map +1 -1
  33. package/dist/client/AssistantChat.js +22 -66
  34. package/dist/client/AssistantChat.js.map +1 -1
  35. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  36. package/dist/client/MultiTabAssistantChat.js +4 -1
  37. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  38. package/dist/client/composer/PromptComposer.d.ts +6 -1
  39. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  40. package/dist/client/composer/PromptComposer.js +5 -4
  41. package/dist/client/composer/PromptComposer.js.map +1 -1
  42. package/dist/client/composer/TiptapComposer.d.ts +6 -1
  43. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  44. package/dist/client/composer/TiptapComposer.js +20 -10
  45. package/dist/client/composer/TiptapComposer.js.map +1 -1
  46. package/dist/client/conversation/AgentConversation.d.ts +18 -0
  47. package/dist/client/conversation/AgentConversation.d.ts.map +1 -0
  48. package/dist/client/conversation/AgentConversation.js +94 -0
  49. package/dist/client/conversation/AgentConversation.js.map +1 -0
  50. package/dist/client/conversation/AgentConversation.spec.d.ts +2 -0
  51. package/dist/client/conversation/AgentConversation.spec.d.ts.map +1 -0
  52. package/dist/client/conversation/AgentConversation.spec.js +69 -0
  53. package/dist/client/conversation/AgentConversation.spec.js.map +1 -0
  54. package/dist/client/conversation/index.d.ts +4 -0
  55. package/dist/client/conversation/index.d.ts.map +1 -0
  56. package/dist/client/conversation/index.js +3 -0
  57. package/dist/client/conversation/index.js.map +1 -0
  58. package/dist/client/conversation/types.d.ts +54 -0
  59. package/dist/client/conversation/types.d.ts.map +1 -0
  60. package/dist/client/conversation/types.js +2 -0
  61. package/dist/client/conversation/types.js.map +1 -0
  62. package/dist/client/conversation/use-near-bottom-autoscroll.d.ts +15 -0
  63. package/dist/client/conversation/use-near-bottom-autoscroll.d.ts.map +1 -0
  64. package/dist/client/conversation/use-near-bottom-autoscroll.js +66 -0
  65. package/dist/client/conversation/use-near-bottom-autoscroll.js.map +1 -0
  66. package/dist/client/dynamic-suggestions.d.ts +43 -0
  67. package/dist/client/dynamic-suggestions.d.ts.map +1 -0
  68. package/dist/client/dynamic-suggestions.js +344 -0
  69. package/dist/client/dynamic-suggestions.js.map +1 -0
  70. package/dist/client/index.d.ts +2 -0
  71. package/dist/client/index.d.ts.map +1 -1
  72. package/dist/client/index.js +2 -0
  73. package/dist/client/index.js.map +1 -1
  74. package/dist/client/resources/ResourceTree.d.ts.map +1 -1
  75. package/dist/client/resources/ResourceTree.js +2 -2
  76. package/dist/client/resources/ResourceTree.js.map +1 -1
  77. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  78. package/dist/client/resources/ResourcesPanel.js +4 -28
  79. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  80. package/dist/client/settings/SettingsPanel.js +2 -2
  81. package/dist/client/settings/SettingsPanel.js.map +1 -1
  82. package/dist/code-agents/index.d.ts +1 -0
  83. package/dist/code-agents/index.d.ts.map +1 -1
  84. package/dist/code-agents/index.js +1 -0
  85. package/dist/code-agents/index.js.map +1 -1
  86. package/dist/code-agents/transcript-normalizer.d.ts +50 -0
  87. package/dist/code-agents/transcript-normalizer.d.ts.map +1 -0
  88. package/dist/code-agents/transcript-normalizer.js +356 -0
  89. package/dist/code-agents/transcript-normalizer.js.map +1 -0
  90. package/dist/coding-tools/index.d.ts +31 -0
  91. package/dist/coding-tools/index.d.ts.map +1 -0
  92. package/dist/coding-tools/index.js +411 -0
  93. package/dist/coding-tools/index.js.map +1 -0
  94. package/dist/extensions/schema.d.ts +1 -1
  95. package/dist/mcp/build-server.d.ts.map +1 -1
  96. package/dist/mcp/build-server.js +30 -0
  97. package/dist/mcp/build-server.js.map +1 -1
  98. package/dist/mcp/builtin-tools.d.ts.map +1 -1
  99. package/dist/mcp/builtin-tools.js +85 -26
  100. package/dist/mcp/builtin-tools.js.map +1 -1
  101. package/dist/mcp/connect-route.d.ts +43 -0
  102. package/dist/mcp/connect-route.d.ts.map +1 -0
  103. package/dist/mcp/connect-route.js +744 -0
  104. package/dist/mcp/connect-route.js.map +1 -0
  105. package/dist/mcp/connect-store.d.ts +132 -0
  106. package/dist/mcp/connect-store.d.ts.map +1 -0
  107. package/dist/mcp/connect-store.js +434 -0
  108. package/dist/mcp/connect-store.js.map +1 -0
  109. package/dist/mcp/org-directory.d.ts +83 -0
  110. package/dist/mcp/org-directory.d.ts.map +1 -0
  111. package/dist/mcp/org-directory.js +201 -0
  112. package/dist/mcp/org-directory.js.map +1 -0
  113. package/dist/mcp/server.d.ts +38 -1
  114. package/dist/mcp/server.d.ts.map +1 -1
  115. package/dist/mcp/server.js +208 -77
  116. package/dist/mcp/server.js.map +1 -1
  117. package/dist/scripts/dev/index.d.ts +6 -4
  118. package/dist/scripts/dev/index.d.ts.map +1 -1
  119. package/dist/scripts/dev/index.js +28 -13
  120. package/dist/scripts/dev/index.js.map +1 -1
  121. package/dist/server/agent-chat-plugin.d.ts +6 -6
  122. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  123. package/dist/server/agent-chat-plugin.js +32 -32
  124. package/dist/server/agent-chat-plugin.js.map +1 -1
  125. package/dist/server/agent-teams.js +2 -2
  126. package/dist/server/agent-teams.js.map +1 -1
  127. package/dist/server/agents-bundle.d.ts +3 -3
  128. package/dist/server/agents-bundle.js +5 -5
  129. package/dist/server/agents-bundle.js.map +1 -1
  130. package/dist/server/auth.d.ts +17 -0
  131. package/dist/server/auth.d.ts.map +1 -1
  132. package/dist/server/auth.js +149 -33
  133. package/dist/server/auth.js.map +1 -1
  134. package/dist/server/better-auth-instance.d.ts +43 -0
  135. package/dist/server/better-auth-instance.d.ts.map +1 -1
  136. package/dist/server/better-auth-instance.js +25 -0
  137. package/dist/server/better-auth-instance.js.map +1 -1
  138. package/dist/server/core-routes-plugin.d.ts +12 -0
  139. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  140. package/dist/server/core-routes-plugin.js +42 -0
  141. package/dist/server/core-routes-plugin.js.map +1 -1
  142. package/dist/server/identity-sso-store.d.ts +86 -0
  143. package/dist/server/identity-sso-store.d.ts.map +1 -0
  144. package/dist/server/identity-sso-store.js +243 -0
  145. package/dist/server/identity-sso-store.js.map +1 -0
  146. package/dist/server/identity-sso.d.ts +78 -0
  147. package/dist/server/identity-sso.d.ts.map +1 -0
  148. package/dist/server/identity-sso.js +425 -0
  149. package/dist/server/identity-sso.js.map +1 -0
  150. package/dist/server/index.d.ts +1 -0
  151. package/dist/server/index.d.ts.map +1 -1
  152. package/dist/server/index.js +1 -0
  153. package/dist/server/index.js.map +1 -1
  154. package/dist/server/onboarding-html.d.ts.map +1 -1
  155. package/dist/server/onboarding-html.js +2 -1
  156. package/dist/server/onboarding-html.js.map +1 -1
  157. package/dist/server/sentry.d.ts.map +1 -1
  158. package/dist/server/sentry.js +17 -2
  159. package/dist/server/sentry.js.map +1 -1
  160. package/dist/sharing/schema.d.ts +1 -1
  161. package/docs/content/client.md +15 -0
  162. package/docs/content/code-agents-ui.md +25 -4
  163. package/docs/content/cross-app-sso.md +118 -0
  164. package/docs/content/drop-in-agent.md +3 -1
  165. package/docs/content/external-agents.md +130 -51
  166. package/docs/content/frames.md +1 -1
  167. package/docs/content/migration-workbench.md +6 -1
  168. package/package.json +2 -1
@@ -1,56 +1,90 @@
1
1
  ---
2
2
  title: "External Agents"
3
- description: "Connect Claude Code, Cowork, and Codex to an agent-native app over MCPwith deep links that drop the user back into the running UI and live artifact round-trip."
3
+ description: "Connect your own Claude Code, Cowork, or Codex to a hosted agent-native app in one command then round-trip artifacts back into the running UI with deep links."
4
4
  ---
5
5
 
6
6
  # External Agents
7
7
 
8
8
  An agent-native app is reachable by any external coding agent — Claude Code (desktop & CLI), Claude Cowork, Codex — over [MCP](/docs/mcp-protocol). External agents are great at producing artifacts (a draft, an event, a dashboard) but they live in a terminal or another app. Without a bridge, the user gets a wall of JSON and has to go find the thing.
9
9
 
10
- The external-agent bridge closes the loop: the agent does the work over MCP, then hands the user a single **"Open in <app> →"** link that opens the real app focused on exactly what was produced. It reuses the existing `navigate` / `application_state` contract the UI already drains every 2s (see [Context Awareness](/docs/context-awareness)) — there is no second navigation mechanism.
10
+ The external-agent bridge closes the loop. First you connect your own agent to a **hosted** app — one command, no token copying. Then the agent does the work over MCP and hands the user a single **"Open in <app> →"** link that opens the real app focused on exactly what was produced. It reuses the existing `navigate` / `application_state` contract the UI already drains every 2s (see [Context Awareness](/docs/context-awareness)) — there is no second navigation mechanism.
11
11
 
12
- ## Overview {#overview}
12
+ ## Connect in one command {#connect}
13
13
 
14
- - **One-command setup** `agent-native mcp install --client <c>` writes the client config and provisions a token.
15
- - **`link` builder** — any action that produces or lists a navigable resource returns a deep link; MCP/A2A surfaces auto-append an "Open in … →" link.
16
- - **`/_agent-native/open` route** — a pure pointer (view + record ids + filters); the record-focusing write is always scoped to the **browser session**, never the agent's token.
17
- - **Ingest actions** — GET + `readOnly` + `publicAgent` actions let an external agent pull **live** app state into its own context.
18
- - **Generic cross-app verbs** — a stable verb set (`list_apps`, `open_app`, `ask_app`, `create_workspace_app`, `list_templates`) so an external agent has a predictable surface without guessing per-app action names.
14
+ The first-party hosted apps live at `mail.agent-native.com`, `calendar.agent-native.com`, `analytics.agent-native.com`, and so on. To wire your own Claude Code (and Codex / Cowork if detected) to one of them:
19
15
 
20
- ## Connect an external agent {#connect}
21
-
22
- The framework already mounts an HTTP MCP endpoint at `/_agent-native/mcp` (see [MCP Protocol](/docs/mcp-protocol)). Every `defineAction` is exposed as an MCP tool, plus the `ask-agent` meta-tool that runs the full agent loop (the same entry point [A2A](/docs/a2a-protocol) uses). Hosted apps point an external agent at that URL with a bearer token (`ACCESS_TOKEN`, or an `A2A_SECRET` JWT carrying the caller's `sub` + `org_domain` so tool runs stay tenant-scoped).
16
+ ```bash
17
+ npx @agent-native/core connect https://mail.agent-native.com
18
+ ```
23
19
 
24
- For local Claude Code / Codex / Cowork, one command writes the client config:
20
+ This opens your browser at the app. You are already logged in, so you just click **Authorize** once. The command detects every installed agent client and writes the MCP config for each — no token to copy, no local server to run. Connect every first-party hosted app at once with:
25
21
 
26
22
  ```bash
27
- agent-native mcp install --client claude-code|claude-code-cli|codex|cowork \
28
- [--app <id>] [--scope user|project]
23
+ npx @agent-native/core connect --all
29
24
  ```
30
25
 
31
- It provisions a token (a random `ACCESS_TOKEN` into the workspace `.env` for local dev, or a signed JWT for a detected hosted deployment) and writes an idempotent stdio server entry:
26
+ The connection is **per-user, scoped, and revocable**. The browser session you authorized with is the identity the agent acts as; nothing exposes the deployment's shared secret.
32
27
 
33
- - **claude-code / claude-code-cli** — an `mcpServers` entry in `.mcp.json` (project scope, default) or `~/.claude.json` (`--scope user`).
34
- - **cowork** — the same Claude Code JSON shape in `~/.cowork/mcp.json`.
35
- - **codex** — an `[mcp_servers.<name>]` block in `~/.codex/config.toml`.
28
+ ### No-CLI alternative {#no-cli}
36
29
 
37
- The entry runs `agent-native mcp serve --app <id>`, which by default is a **thin stdio proxy** to the running local app's `/_agent-native/mcp` so the live action registry, HMR, and correct deep links stay the single source of truth. Pass `--standalone` to build the registry in-process instead. When `agent-native mcp install` detects a hosted origin (a non-localhost `APP_URL` / `BETTER_AUTH_URL` / `AGENT_NATIVE_MCP_URL` in the workspace `.env`), it writes an `http` client entry pointing at `<origin>/_agent-native/mcp` with a `Bearer` JWT instead of a stdio entry.
30
+ If you'd rather not run a command, open the app in your browser and use its **Connect** affordance (served at `https://<app>/_agent-native/mcp/connect`). While logged in, click **Connect / Authorize**. The page hands you either a one-click deep link that configures a detected agent, or a ready-to-paste `.mcp.json` block:
38
31
 
39
- Companion subcommands:
32
+ ```jsonc
33
+ // .mcp.json
34
+ {
35
+ "mcpServers": {
36
+ "mail": {
37
+ "type": "url",
38
+ "url": "https://mail.agent-native.com/_agent-native/mcp",
39
+ "headers": { "Authorization": "Bearer <minted-token>" },
40
+ },
41
+ },
42
+ }
43
+ ```
40
44
 
41
- | Command | What it does |
42
- | ----------------------------------------- | ------------------------------------------------------------------- |
43
- | `agent-native mcp serve [--app <id>]` | Run the MCP stdio transport (what client configs spawn). |
44
- | `agent-native mcp install --client <c>` | Provision a token + write the client's MCP config (idempotent). |
45
- | `agent-native mcp uninstall --client <c>` | Remove the named MCP entry from a client's config (idempotent). |
46
- | `agent-native mcp status` | Show resolved MCP URL/port, token state, and per-client entries. |
47
- | `agent-native mcp token [--rotate]` | Print (or rotate) the local `ACCESS_TOKEN` in the workspace `.env`. |
45
+ Restart the agent client after connecting so it picks up the new MCP server.
48
46
 
49
- Restart the client after `install` so it picks up the new MCP server.
47
+ ## What you can do once connected {#what-you-can-do}
48
+
49
+ Once your agent is connected, the app's full action surface is available as MCP tools, plus the `ask-agent` meta-tool that runs the full agent loop (the same entry point [A2A](/docs/a2a-protocol) uses). Ask your agent to do real work and it hands back a link straight into the running app:
50
+
51
+ ```
52
+ > draft an email to John about the Q3 report
53
+
54
+ Claude Code calls: manage-draft(to: "john@example.com", subject: "Q3 Report", body: "…")
55
+ → Open draft in Mail → https://mail.agent-native.com/_agent-native/open?app=mail&view=inbox&compose=…
56
+ ```
57
+
58
+ Click that link and Mail opens with the draft restored — focused exactly where you, the logged-in user, are. The agent never had to know your session; it just produced the artifact.
59
+
60
+ ### Generic cross-app verbs {#cross-app}
61
+
62
+ On top of the per-action tools the MCP server exposes a stable verb set, so an external agent has a predictable surface without guessing per-app action names:
63
+
64
+ | Tool | Side effects | Returns |
65
+ | ------------------------------------------ | ------------ | ------------------------------------------------------------------------------------ |
66
+ | `list_apps` | none | workspace apps + their URLs / running state |
67
+ | `open_app({ app, view, params? })` | none | a `buildDeepLink` URL (surfaces as an "Open …" link) |
68
+ | `ask_app({ app, message })` | agent loop | routes a natural-language task to that app's in-app agent (delegates to `ask-agent`) |
69
+ | `create_workspace_app({ name, template })` | scaffolds | a new app booted via the workspace path, plus its running URL + deep link |
70
+ | `list_templates` | none | the allow-listed templates only |
71
+
72
+ `create_workspace_app` rejects any non-allow-listed template — the public template allow-list in `packages/shared-app-config/templates.ts` is authoritative and CI-guarded; an external agent cannot widen it. A same-named template action overrides a builtin (template-over-core precedence). Disable the whole set with `MCPConfig.builtinCrossAppTools: false`.
73
+
74
+ ### Per-app tour {#tour}
75
+
76
+ Every allow-listed template that produces or lists a navigable resource ships a `link` builder, and the ingest-heavy ones ship a GET + `publicAgent` action so a connected agent can pull live state:
77
+
78
+ - **Mail** — `manage-draft` returns a `compose`-encoded deep link; clicking it opens the inbox with the draft restored into a `compose-<id>`. `list-emails` / `search-emails` point at a filtered inbox view.
79
+ - **Calendar** — `create-event` returns `buildDeepLink({ app: "calendar", view: "calendar", params: { eventId, date } })`; the click lands on the calendar with that event focused on its date.
80
+ - **Analytics** — `update-dashboard` / `save-analysis` return `buildDeepLink({ app: "analytics", view: "adhoc", params: { dashboardId } })`; the agent builds a dashboard over MCP and hands back "Open dashboard in Analytics".
81
+ - **Design** — `get-design-snapshot` is the GET + `publicAgent` ingest action: it returns the **live** Yjs file contents plus the resolved tweak values so the agent continues from the tuned design, not the original tokens. `apply-tweaks` round-trips back with an "Open design" editor link.
82
+ - **Content** — `pull-document` is the GET + `publicAgent` ingest action: it flushes any open live collaborative session to SQL first so the external agent ingests exactly what the user sees, then surfaces a deep link to the document.
83
+ - **Brain** — `ask-brain` / `search-everything` return a cited answer plus a deep link to the underlying knowledge/capture, so a terminal agent's lookup links straight back into the source in the running app.
50
84
 
51
- ## The `link` builder {#link-builder}
85
+ ## Authoring: the `link` builder {#link-builder}
52
86
 
53
- `defineAction` accepts an optional `link` builder. When set, every MCP/A2A result for that tool auto-appends a markdown `[label →](absoluteUrl)` block and a structured `_meta["agent-native/openLink"] = { label, view, webUrl, desktopUrl }`. `tools/list` adds `annotations["agent-native/producesOpenLink"]` and a description suffix so the external agent knows the tool yields an openable link and should surface it.
87
+ This section is for template authors. `defineAction` accepts an optional `link` builder. When set, every MCP/A2A result for that tool auto-appends a markdown `[label →](absoluteUrl)` block and a structured `_meta["agent-native/openLink"] = { label, view, webUrl, desktopUrl }`. `tools/list` adds `annotations["agent-native/producesOpenLink"]` and a description suffix so the external agent knows the tool yields an openable link and should surface it.
54
88
 
55
89
  Build the URL with `buildDeepLink(...)` — it is the single source of truth for the open-route format. Never hand-format the `/_agent-native/open` URL.
56
90
 
@@ -91,7 +125,7 @@ The `link` builder is **pure and synchronous — no I/O, no awaits**. It runs be
91
125
 
92
126
  `buildDeepLink({ app, view, params?, to?, compose? })` returns the app-relative path `/_agent-native/open?app=…&view=…&<recordId>=…`. The MCP layer turns that into an absolute web URL (`toAbsoluteOpenUrl`, using the request origin) and a desktop `agentnative://open?…` URL (`toDesktopOpenUrl`); the markdown link uses the desktop URL when the client signals `target: "desktop"`.
93
127
 
94
- ## The `/_agent-native/open` route {#open-route}
128
+ ### The `/_agent-native/open` route {#open-route}
95
129
 
96
130
  When the user clicks the link in any browser or inline webview, `GET /_agent-native/open` (`createOpenRouteHandler`, mounted by the core routes plugin):
97
131
 
@@ -102,11 +136,11 @@ When the user clicks the link in any browser or inline webview, `GET /_agent-nat
102
136
 
103
137
  Cross-origin, scheme-relative `//host`, and control-char redirects are rejected (open-redirect guard). The route can be disabled per app via `disableOpenRoute`.
104
138
 
105
- ### The browser-session identity rule {#identity-rule}
139
+ #### The browser-session identity rule {#identity-rule}
106
140
 
107
141
  The link carries **no privileged state** — it is just `view` + record ids + filters. The record-focusing `navigate` write is scoped to whoever is logged into the **browser**, never the external agent's MCP token. So an agent authenticated as one identity can hand a user a link, and when that user clicks it the record opens where _the user_ is logged in. This is what makes the deep link safe to surface in a terminal or chat transcript. See [Context Awareness](/docs/context-awareness) for the `navigate` / `application_state` contract this bridges to.
108
142
 
109
- ## Ingest actions {#ingest}
143
+ ### Ingest actions {#ingest}
110
144
 
111
145
  An action an external agent reads to pull live app state into its own context must be:
112
146
 
@@ -125,43 +159,86 @@ export default defineAction({
125
159
 
126
160
  `GET` + `readOnly` keeps the action side-effect-free and out of the screen-refresh poll. `publicAgent` is the **explicit opt-in** — a public web route never implies public MCP/A2A exposure; see [Actions](/docs/actions). Design/content ingest actions MUST read **live** state (the Yjs collaborative document, not the stale DB snapshot column) so the external agent sees what the user actually has on screen. Content's `pull-document` flushes any open live collab session to SQL first; design's `get-design-snapshot` returns the live Yjs file contents plus the user's resolved tweak values.
127
161
 
128
- ## Generic cross-app verbs + scaffolding {#cross-app}
162
+ ## Advanced: local development & manual setup {#advanced}
129
163
 
130
- On top of the per-action tools the MCP server exposes a stable verb set so an external agent has a predictable surface without guessing per-app action names:
164
+ The hosted `connect` flow above is the recommended path. The options below are for local development and hand-rolled setups.
131
165
 
132
- | Tool | Side effects | Returns |
133
- | ------------------------------------------ | ------------ | ------------------------------------------------------------------------------------ |
134
- | `list_apps` | none | workspace apps + their dev URLs / running state |
135
- | `open_app({ app, view, params? })` | none | a `buildDeepLink` URL (surfaces as an "Open …" link) |
136
- | `ask_app({ app, message })` | agent loop | routes a natural-language task to that app's in-app agent (delegates to `ask-agent`) |
137
- | `create_workspace_app({ name, template })` | scaffolds | a new app booted via the workspace path, plus its running URL + deep link |
138
- | `list_templates` | none | the allow-listed templates only |
166
+ ### Local development {#local-dev}
139
167
 
140
- `create_workspace_app` rejects any non-allow-listed template the public template allow-list in `packages/shared-app-config/templates.ts` is authoritative and CI-guarded; an external agent cannot widen it. A same-named template action overrides a builtin (template-over-core precedence). Disable the whole set with `MCPConfig.builtinCrossAppTools: false`.
168
+ Run your app locally (`pnpm dev` / `agent-native dev`), then point a local agent at it with one command:
141
169
 
142
- ## Per-app tour {#tour}
170
+ ```bash
171
+ agent-native mcp install --client claude-code|claude-code-cli|codex|cowork \
172
+ [--app <id>] [--scope user|project]
173
+ ```
143
174
 
144
- Every allow-listed template that produces or lists a navigable resource ships a `link` builder, and the ingest-heavy ones ship a GET + `publicAgent` action:
175
+ It provisions a token (a random `ACCESS_TOKEN` into the workspace `.env` for local dev, or a signed JWT if it detects a hosted origin) and writes an idempotent stdio server entry:
145
176
 
146
- - **Mail** — `manage-draft` returns a `compose`-encoded deep link; clicking it opens the inbox with the draft restored into a `compose-<id>`. `list-emails` / `search-emails` point at a filtered inbox view.
147
- - **Calendar** — `create-event` returns `buildDeepLink({ app: "calendar", view: "calendar", params: { eventId, date } })`; the click lands on the calendar with that event focused on its date.
148
- - **Analytics** — `update-dashboard` / `save-analysis` return `buildDeepLink({ app: "analytics", view: "adhoc", params: { dashboardId } })`; the agent builds a dashboard over MCP and hands back "Open dashboard in Analytics".
149
- - **Design** — `get-design-snapshot` is the GET + `publicAgent` ingest action: it returns the **live** Yjs file contents plus the resolved tweak values so the agent continues from the tuned design, not the original tokens. `apply-tweaks` round-trips back with an "Open design" editor link.
150
- - **Content** `pull-document` is the GET + `publicAgent` ingest action: it flushes any open live collaborative session to SQL first so the external agent ingests exactly what the user sees, then surfaces a deep link to the document.
151
- - **Brain** — `ask-brain` / `search-everything` return a cited answer plus a deep link to the underlying knowledge/capture, so a terminal agent's lookup links straight back into the source in the running app.
177
+ - **claude-code / claude-code-cli** — an `mcpServers` entry in `.mcp.json` (project scope, default) or `~/.claude.json` (`--scope user`).
178
+ - **cowork** — the same Claude Code JSON shape in `~/.cowork/mcp.json`.
179
+ - **codex** — an `[mcp_servers.<name>]` block in `~/.codex/config.toml`.
180
+
181
+ The entry runs `agent-native mcp serve --app <id>`, which by default is a **thin stdio proxy** to the running local app's `/_agent-native/mcp` so the live action registry, HMR, and correct deep links stay the single source of truth. Pass `--standalone` to build the registry in-process instead. When `agent-native mcp install` detects a hosted origin (a non-localhost `APP_URL` / `BETTER_AUTH_URL` / `AGENT_NATIVE_MCP_URL` in the workspace `.env`), it writes an `http` client entry pointing at `<origin>/_agent-native/mcp` with a `Bearer` JWT instead of a stdio entry.
182
+
183
+ Companion subcommands:
184
+
185
+ | Command | What it does |
186
+ | ----------------------------------------- | ------------------------------------------------------------------- |
187
+ | `agent-native mcp serve [--app <id>]` | Run the MCP stdio transport (what client configs spawn). |
188
+ | `agent-native mcp install --client <c>` | Provision a token + write the client's MCP config (idempotent). |
189
+ | `agent-native mcp uninstall --client <c>` | Remove the named MCP entry from a client's config (idempotent). |
190
+ | `agent-native mcp status` | Show resolved MCP URL/port, token state, and per-client entries. |
191
+ | `agent-native mcp token [--rotate]` | Print (or rotate) the local `ACCESS_TOKEN` in the workspace `.env`. |
192
+
193
+ Restart the client after `install` so it picks up the new MCP server.
194
+
195
+ ### Manual `.mcp.json` HTTP entry {#manual-entry}
196
+
197
+ You can also write the MCP client config by hand against any deployed endpoint with a token you supply yourself (an `ACCESS_TOKEN`, or an `A2A_SECRET`-signed JWT carrying the caller's `sub` + `org_domain` so tool runs stay tenant-scoped):
198
+
199
+ ```jsonc
200
+ // .mcp.json
201
+ {
202
+ "mcpServers": {
203
+ "analytics": {
204
+ "type": "url",
205
+ "url": "https://analytics.agent-native.com/_agent-native/mcp",
206
+ "headers": { "Authorization": "Bearer <ACCESS_TOKEN-or-JWT>" },
207
+ },
208
+ },
209
+ }
210
+ ```
211
+
212
+ This is the unmanaged equivalent of what `connect` writes for you. See [MCP Protocol](/docs/mcp-protocol) for the full auth env-var matrix.
213
+
214
+ ### Dev vs production tool surface {#dev-vs-prod}
215
+
216
+ In plain local dev (`NODE_ENV=development` and `AGENT_MODE !== "production"`) the MCP `tools/list` deliberately exposes only the generic builtins plus actions with `publicAgent.requiresAuth === false` — the per-app ingest actions (`requiresAuth: true`) and mutating actions (no `publicAgent`) are filtered out (`filterPublicAgentActions`). The full per-app surface appears when the request is authenticated as a real caller: a deployed / `AGENT_MODE=production` app, or a local app reached through `connect` / `agent-native mcp install` (which provisions a token so the caller has an identity). So if `tools/list` looks sparse, you are hitting an unauthenticated dev endpoint — connect (or present a token) rather than assuming the action is missing.
217
+
218
+ ## How it works & security {#how-it-works}
219
+
220
+ The hosted `connect` flow never copies the deployment's shared secret. Instead:
221
+
222
+ - A logged-in browser session mints a **per-user, scoped, revocable** token — an `A2A_SECRET`-signed JWT carrying the caller's `sub` + `org_domain` and a unique `jti`, so every tool run stays tenant-scoped via `runWithRequestContext`.
223
+ - The existing `/_agent-native/mcp` endpoint accepts that token like any other bearer (see [MCP Protocol](/docs/mcp-protocol)) — no new endpoint, no new transport.
224
+ - The same Connect page lists every token you've minted and lets you **revoke** any of them by `jti`. Treat them like personal access tokens: one per agent client, revoke when a machine is decommissioned.
225
+ - The deep link the agent hands back carries no privileged state. The record-focusing `navigate` write is always scoped to the **browser** session, never the agent's token — so a link is safe to paste into a terminal or chat transcript.
152
226
 
153
227
  ## Do / Don't {#do-dont}
154
228
 
155
229
  **Do**
156
230
 
231
+ - Connect your own agent to a hosted app with `npx @agent-native/core connect <url>` (or `--all`) — it's the frictionless path.
157
232
  - Add a `link` builder to any action that produces or lists a navigable resource (draft, event, dashboard, document).
158
233
  - Build the URL with `buildDeepLink(...)` — the single source of truth for the open-route format.
159
234
  - Keep `link` pure and synchronous; return `null` when there's nothing to open.
160
235
  - Make external-agent ingest actions GET + `readOnly` + `publicAgent`, and read live (Yjs) state, not the stale DB column.
161
236
  - Let the open route resolve the browser session; pass record ids as deep-link params and let the UI focus them via the polled `navigate` command.
237
+ - Revoke a minted connect token by `jti` when an agent client is decommissioned.
162
238
 
163
239
  **Don't**
164
240
 
241
+ - Copy a deployment's shared `ACCESS_TOKEN` / `A2A_SECRET` into a client config when `connect` can mint a per-user, revocable token instead.
165
242
  - Hand-format the `/_agent-native/open` URL — always go through `buildDeepLink`.
166
243
  - Do I/O, awaits, DB reads, or app-state reads inside a `link` builder.
167
244
  - Scope the `navigate` write to the agent token, or pass privileged state through the deep link — it's a pure pointer.
@@ -175,3 +252,5 @@ Every allow-listed template that produces or lists a navigable resource ships a
175
252
  - [A2A Protocol](/docs/a2a-protocol) — the `ask-agent` meta-tool and JSON-RPC peer calls.
176
253
  - [Actions](/docs/actions) — defining actions, `publicAgent`, GET / `readOnly`.
177
254
  - [Context Awareness](/docs/context-awareness) — the `navigate` / `application_state` contract the open route bridges to.
255
+ </content>
256
+ </invoke>
@@ -12,7 +12,7 @@ Agent-native apps run with an AI agent alongside the app UI. Locally, the agent
12
12
  - Ships with `@agent-native/core` — no separate package needed
13
13
  - Agent panel embedded directly in your app with chat and optional CLI terminal
14
14
  - Supports multiple AI coding CLIs — switch between them from the settings panel
15
- - Toggle between production mode (app tools only) and development mode (full filesystem, shell, and database access)
15
+ - Toggle between production mode (app tools only) and development mode (shared `bash`/`read`/`edit`/`write` coding tools plus database access)
16
16
  - Great for local development, self-hosted production, and OSS
17
17
 
18
18
  ## Supported CLIs {#supported-clis}
@@ -59,6 +59,11 @@ code> /migrate ./my-next-app --out ../migrated-app
59
59
  code> /audit --url https://example.com
60
60
  ```
61
61
 
62
+ Agent-Native Code uses the same minimal coding tools as the sidebar development
63
+ agent: `bash` for discovery/search/tests/builds, `read` for line-numbered file
64
+ reads, `edit` for exact replacements, and `write` for new files or full
65
+ rewrites.
66
+
62
67
  The same goals can run directly from the command line:
63
68
 
64
69
  ```bash
@@ -209,7 +214,7 @@ In Agent-Native Code, Desktop, or the internal run surface, connect providers th
209
214
 
210
215
  ## Agent-Native Code
211
216
 
212
- Agent-Native Desktop includes a **Agent-Native Code** hub for long-running coding-agent sessions. It is the general Code app/surface in Desktop, and it pairs with the `agent-native code` shell as the primary CLI/Desktop coding experience. A bare prompt is the generic coding session, and `/migrate` is one specialized capability there: the hub shows recent and active runs, opens a transcript-first session view, renders tool events and artifacts, sends follow-up prompts, stops tracked runners, opens a terminal in the run workspace, and handles links like:
217
+ Agent-Native Desktop includes a **Agent-Native Code** hub for long-running coding-agent sessions. It is the general Code app/surface in Desktop, and it pairs with the `agent-native code` shell as the primary CLI/Desktop coding experience. A bare prompt is the generic coding session, and `/migrate` is one specialized capability there: the hub shows recent and active runs, opens a transcript-first session view with compact tool summaries and artifacts, sends follow-up prompts, stops tracked runners, opens a terminal in the run workspace, and handles links like:
213
218
 
214
219
  ```text
215
220
  agentnative://open?goal=migrate&run=<runId>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.18.1",
3
+ "version": "0.19.1",
4
4
  "type": "module",
5
5
  "description": "Framework for agent-native application development — where AI agents and UI share state via files",
6
6
  "license": "MIT",
@@ -78,6 +78,7 @@
78
78
  "./usage": "./dist/usage/store.js",
79
79
  "./connections": "./dist/connections/index.js",
80
80
  "./code-agents": "./dist/code-agents/index.js",
81
+ "./code-agents/transcript-normalizer": "./dist/code-agents/transcript-normalizer.js",
81
82
  "./workspace-connections": "./dist/workspace-connections/index.js",
82
83
  "./notifications": "./dist/notifications/index.js",
83
84
  "./client/notifications": "./dist/client/notifications/index.js",