@agent-native/core 0.7.4 → 0.7.7
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/README.md +6 -5
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +8 -4
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/engine/types.d.ts +1 -1
- package/dist/agent/engine/types.d.ts.map +1 -1
- package/dist/agent/production-agent.d.ts +7 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +153 -118
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +4 -0
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +46 -25
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +12 -3
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +25 -4
- package/dist/agent/run-store.js.map +1 -1
- package/dist/chat-threads/store.d.ts +13 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +66 -10
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +8 -1
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +8 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/info.d.ts +2 -0
- package/dist/cli/info.d.ts.map +1 -0
- package/dist/cli/info.js +103 -0
- package/dist/cli/info.js.map +1 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +249 -85
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +12 -1
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +3 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +46 -2
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/VoiceButton.d.ts +21 -0
- package/dist/client/composer/VoiceButton.d.ts.map +1 -0
- package/dist/client/composer/VoiceButton.js +51 -0
- package/dist/client/composer/VoiceButton.js.map +1 -0
- package/dist/client/composer/useVoiceDictation.d.ts +38 -0
- package/dist/client/composer/useVoiceDictation.d.ts.map +1 -0
- package/dist/client/composer/useVoiceDictation.js +398 -0
- package/dist/client/composer/useVoiceDictation.js.map +1 -0
- package/dist/client/onboarding/OnboardingPanel.js +2 -2
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +5 -4
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +90 -24
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/resources/McpServerDetail.d.ts +15 -0
- package/dist/client/resources/McpServerDetail.d.ts.map +1 -0
- package/dist/client/resources/McpServerDetail.js +65 -0
- package/dist/client/resources/McpServerDetail.js.map +1 -0
- package/dist/client/resources/ResourceEditor.js +1 -1
- package/dist/client/resources/ResourceEditor.js.map +1 -1
- package/dist/client/resources/ResourceTree.d.ts +6 -1
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +18 -7
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +191 -20
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/use-mcp-servers.d.ts +68 -0
- package/dist/client/resources/use-mcp-servers.d.ts.map +1 -0
- package/dist/client/resources/use-mcp-servers.js +83 -0
- package/dist/client/resources/use-mcp-servers.js.map +1 -0
- package/dist/client/resources/use-resources.d.ts +39 -1
- package/dist/client/resources/use-resources.d.ts.map +1 -1
- package/dist/client/resources/use-resources.js +102 -0
- package/dist/client/resources/use-resources.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +3 -2
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.d.ts +14 -0
- package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -0
- package/dist/client/settings/VoiceTranscriptionSection.js +111 -0
- package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -0
- package/dist/client/sharing/ShareButton.d.ts +6 -4
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +299 -34
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/sharing/ShareDialog.d.ts +22 -4
- package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
- package/dist/client/sharing/ShareDialog.js +170 -148
- package/dist/client/sharing/ShareDialog.js.map +1 -1
- package/dist/client/sharing/VisibilityBadge.d.ts.map +1 -1
- package/dist/client/sharing/VisibilityBadge.js +1 -2
- package/dist/client/sharing/VisibilityBadge.js.map +1 -1
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +20 -1
- package/dist/client/use-action.js.map +1 -1
- package/dist/db/migrations.d.ts +18 -3
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +25 -3
- package/dist/db/migrations.js.map +1 -1
- package/dist/deploy/workspace-core.js +2 -2
- package/dist/mcp-client/config.d.ts +20 -1
- package/dist/mcp-client/config.d.ts.map +1 -1
- package/dist/mcp-client/config.js +28 -11
- package/dist/mcp-client/config.js.map +1 -1
- package/dist/mcp-client/hub-client.d.ts +38 -0
- package/dist/mcp-client/hub-client.d.ts.map +1 -0
- package/dist/mcp-client/hub-client.js +147 -0
- package/dist/mcp-client/hub-client.js.map +1 -0
- package/dist/mcp-client/hub-routes.d.ts +42 -0
- package/dist/mcp-client/hub-routes.d.ts.map +1 -0
- package/dist/mcp-client/hub-routes.js +114 -0
- package/dist/mcp-client/hub-routes.js.map +1 -0
- package/dist/mcp-client/index.d.ts +15 -0
- package/dist/mcp-client/index.d.ts.map +1 -1
- package/dist/mcp-client/index.js +35 -0
- package/dist/mcp-client/index.js.map +1 -1
- package/dist/mcp-client/manager.d.ts +54 -8
- package/dist/mcp-client/manager.d.ts.map +1 -1
- package/dist/mcp-client/manager.js +276 -59
- package/dist/mcp-client/manager.js.map +1 -1
- package/dist/mcp-client/remote-store.d.ts +102 -0
- package/dist/mcp-client/remote-store.d.ts.map +1 -0
- package/dist/mcp-client/remote-store.js +200 -0
- package/dist/mcp-client/remote-store.js.map +1 -0
- package/dist/mcp-client/routes.d.ts +55 -0
- package/dist/mcp-client/routes.d.ts.map +1 -0
- package/dist/mcp-client/routes.js +384 -0
- package/dist/mcp-client/routes.js.map +1 -0
- package/dist/mcp-client/visibility.d.ts +16 -0
- package/dist/mcp-client/visibility.d.ts.map +1 -0
- package/dist/mcp-client/visibility.js +45 -0
- package/dist/mcp-client/visibility.js.map +1 -0
- package/dist/org/context.js +2 -2
- package/dist/org/context.js.map +1 -1
- package/dist/org/handlers.js +2 -2
- package/dist/org/handlers.js.map +1 -1
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +30 -0
- package/dist/resources/handlers.js.map +1 -1
- package/dist/secrets/register-framework-secrets.d.ts +13 -0
- package/dist/secrets/register-framework-secrets.d.ts.map +1 -0
- package/dist/secrets/register-framework-secrets.js +59 -0
- package/dist/secrets/register-framework-secrets.js.map +1 -0
- package/dist/secrets/register.d.ts.map +1 -1
- package/dist/secrets/register.js +8 -1
- package/dist/secrets/register.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +22 -2
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +16 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +237 -70
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/app-url.d.ts.map +1 -1
- package/dist/server/app-url.js +11 -3
- package/dist/server/app-url.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +50 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +99 -4
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +44 -0
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/create-server.js +6 -0
- package/dist/server/create-server.js.map +1 -1
- package/dist/server/date-utils.d.ts +15 -0
- package/dist/server/date-utils.d.ts.map +1 -0
- package/dist/server/date-utils.js +41 -0
- package/dist/server/date-utils.js.map +1 -0
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/onboarding-html.d.ts +3 -0
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +13 -3
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/request-context.d.ts +9 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +10 -0
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +26 -0
- package/dist/server/transcribe-voice.d.ts.map +1 -0
- package/dist/server/transcribe-voice.js +143 -0
- package/dist/server/transcribe-voice.js.map +1 -0
- package/dist/styles/agent-native.css +111 -0
- package/dist/tailwind.preset.d.ts +2 -2
- package/dist/tailwind.preset.d.ts.map +1 -1
- package/dist/tailwind.preset.js +27 -7
- package/dist/tailwind.preset.js.map +1 -1
- package/dist/templates/default/app/global.css +65 -68
- package/dist/templates/default/components.json +1 -1
- package/dist/templates/default/package.json +2 -4
- package/dist/templates/default/vite.config.ts +3 -0
- package/dist/templates/workspace-core/package.json +1 -4
- package/dist/templates/workspace-core/src/index.ts +1 -1
- package/dist/templates/workspace-core/styles/tokens.css +22 -0
- package/dist/templates/workspace-core/tsconfig.json +1 -1
- package/dist/vite/client.d.ts +6 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +18 -1
- package/dist/vite/client.js.map +1 -1
- package/docs/content/actions.md +169 -74
- package/docs/content/agent-teams.md +139 -0
- package/docs/content/cloneable-saas.md +98 -0
- package/docs/content/creating-templates.md +9 -11
- package/docs/content/deployment.md +2 -9
- package/docs/content/drop-in-agent.md +200 -0
- package/docs/content/enterprise-workspace.md +22 -10
- package/docs/content/getting-started.md +34 -19
- package/docs/content/integrations.md +3 -3
- package/docs/content/key-concepts.md +50 -23
- package/docs/content/mcp-clients.md +71 -0
- package/docs/content/pure-agent-apps.md +69 -0
- package/docs/content/recurring-jobs.md +123 -0
- package/docs/content/skills-guide.md +8 -0
- package/docs/content/template-analytics.md +190 -0
- package/docs/content/template-calendar.md +151 -0
- package/docs/content/template-clips.md +55 -0
- package/docs/content/template-content.md +141 -0
- package/docs/content/template-dispatch.md +58 -0
- package/docs/content/template-forms.md +51 -0
- package/docs/content/template-mail.md +169 -0
- package/docs/content/template-slides.md +218 -0
- package/docs/content/template-starter.md +68 -0
- package/docs/content/template-video.md +162 -0
- package/docs/content/voice-input.md +59 -0
- package/docs/content/what-is-agent-native.md +142 -45
- package/docs/content/workspace-management.md +1 -0
- package/docs/content/{resources.md → workspace.md} +94 -42
- package/package.json +9 -16
- package/src/templates/default/app/global.css +65 -68
- package/src/templates/default/components.json +1 -1
- package/src/templates/default/package.json +2 -4
- package/src/templates/default/vite.config.ts +3 -0
- package/src/templates/workspace-core/package.json +1 -4
- package/src/templates/workspace-core/src/index.ts +1 -1
- package/src/templates/workspace-core/styles/tokens.css +22 -0
- package/src/templates/workspace-core/tsconfig.json +1 -1
- package/dist/templates/default/postcss.config.js +0 -6
- package/dist/templates/default/tailwind.config.ts +0 -7
- package/dist/templates/workspace-core/tailwind.preset.ts +0 -34
- package/src/templates/default/postcss.config.js +0 -6
- package/src/templates/default/tailwind.config.ts +0 -7
- package/src/templates/workspace-core/tailwind.preset.ts +0 -34
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Drop-in Agent"
|
|
3
|
+
description: "Mount the agent chat + workspace into any React app with <AgentPanel>, <AgentSidebar>, and sendToAgentChat()."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Drop-in Agent
|
|
7
|
+
|
|
8
|
+
You don't need to build agent-native from scratch. The agent chat, workspace tab, CLI terminal, voice input, and all the related infrastructure ship as a handful of React components you drop into any app.
|
|
9
|
+
|
|
10
|
+
> **Prerequisite:** the server has to be running the `agent-chat-plugin` (it auto-mounts in every template). If you're starting from scratch, see [Server](/docs/server).
|
|
11
|
+
|
|
12
|
+
## The components at a glance {#components}
|
|
13
|
+
|
|
14
|
+
| Component | What it is | Use it when |
|
|
15
|
+
| --------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------- |
|
|
16
|
+
| `<AgentSidebar>` | Wraps your app, adds a toggleable side panel containing the full agent | You want the agent available alongside your app on every screen |
|
|
17
|
+
| `<AgentToggleButton>` | Opens/closes `<AgentSidebar>` (put it in your header) | Pair with `<AgentSidebar>` |
|
|
18
|
+
| `<AgentPanel>` | The raw panel itself — chat + CLI + workspace tabs | You want full control over layout, or a dedicated agent page |
|
|
19
|
+
| `sendToAgentChat()` | Programmatically send a message to the chat | A button that hands work to the agent instead of running inline |
|
|
20
|
+
| `useActionMutation()` | Typesafe frontend wrapper around an action | The UI needs to run the same operation an agent tool would run |
|
|
21
|
+
|
|
22
|
+
All of these are exported from `@agent-native/core/client`.
|
|
23
|
+
|
|
24
|
+
## The 80% case: `<AgentSidebar>` {#sidebar}
|
|
25
|
+
|
|
26
|
+
The most common setup is a sidebar that slides in from the right on any screen. Two pieces — the wrapper and a header button:
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
// app/root.tsx
|
|
30
|
+
import { AgentSidebar, AgentToggleButton } from "@agent-native/core/client";
|
|
31
|
+
|
|
32
|
+
export default function Root() {
|
|
33
|
+
return (
|
|
34
|
+
<AgentSidebar
|
|
35
|
+
emptyStateText="How can I help?"
|
|
36
|
+
suggestions={[
|
|
37
|
+
"Summarize my inbox",
|
|
38
|
+
"Draft a reply to the latest email",
|
|
39
|
+
"Show me yesterday's signup numbers",
|
|
40
|
+
]}
|
|
41
|
+
sidebarWidth={420}
|
|
42
|
+
position="right"
|
|
43
|
+
>
|
|
44
|
+
<YourApp />
|
|
45
|
+
</AgentSidebar>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// somewhere in your header / navbar
|
|
50
|
+
<AgentToggleButton />;
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
That's it. The user now has a toggleable agent on every page — with chat history, workspace tab, CLI terminal, voice input, and a fullscreen mode. State persists across reloads via `localStorage`.
|
|
54
|
+
|
|
55
|
+
### Props
|
|
56
|
+
|
|
57
|
+
- **`children`** — your app. Rendered in the main area; the sidebar overlays from the chosen side.
|
|
58
|
+
- **`emptyStateText`** — greeting shown when the chat has no messages. Default: `"How can I help you?"`.
|
|
59
|
+
- **`suggestions`** — starter prompts rendered as clickable chips when empty.
|
|
60
|
+
- **`sidebarWidth`** — pixel width. Default: `380`.
|
|
61
|
+
- **`position`** — `"left"` or `"right"`. Default: `"right"`.
|
|
62
|
+
- **`defaultOpen`** — whether the sidebar starts open (desktop only). Default: `false`.
|
|
63
|
+
|
|
64
|
+
## The other 20%: `<AgentPanel>` {#panel}
|
|
65
|
+
|
|
66
|
+
When you need full control over layout — a dedicated `/chat` route, an embedded panel in a side column you manage, or a popup — render `<AgentPanel>` directly:
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
// app/routes/agent.tsx
|
|
70
|
+
import { AgentPanel } from "@agent-native/core/client";
|
|
71
|
+
|
|
72
|
+
export default function AgentRoute() {
|
|
73
|
+
return (
|
|
74
|
+
<div className="h-screen">
|
|
75
|
+
<AgentPanel defaultMode="chat" className="h-full" />
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`<AgentPanel>` gives you the raw tabs (Chat / CLI / Workspace) without the sidebar wrapper, the collapse button, or any state persistence. Put it wherever you want; you handle the layout.
|
|
82
|
+
|
|
83
|
+
### Selected props
|
|
84
|
+
|
|
85
|
+
- **`defaultMode`** — `"chat"` or `"cli"`. Default: `"chat"`.
|
|
86
|
+
- **`className`** — CSS class for the outer container.
|
|
87
|
+
- **`onCollapse`** — if provided, a collapse button appears in the header.
|
|
88
|
+
- **`isFullscreen`** / **`onToggleFullscreen`** — wire up external fullscreen state if you want a Claude-style centered column.
|
|
89
|
+
- **`storageKey`** — namespace for `localStorage` keys. Useful when you render multiple panels (different app instances or workspaces) in the same page.
|
|
90
|
+
|
|
91
|
+
Full props: `AgentPanelProps` in `@agent-native/core/client`.
|
|
92
|
+
|
|
93
|
+
## Programmatic messages: `sendToAgentChat()` {#send}
|
|
94
|
+
|
|
95
|
+
A button that hands work off to the agent (instead of running an inline `llm()` call — the anti-pattern from the [ladder](/docs/what-is-agent-native#the-ladder)):
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
import { sendToAgentChat } from "@agent-native/core/client";
|
|
99
|
+
|
|
100
|
+
<Button
|
|
101
|
+
onClick={() =>
|
|
102
|
+
sendToAgentChat({
|
|
103
|
+
message: "Generate a chart showing signups by source",
|
|
104
|
+
context: `Dashboard ID: ${dashboardId}, date range: last 30 days`,
|
|
105
|
+
submit: true,
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
>
|
|
109
|
+
Generate chart
|
|
110
|
+
</Button>;
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Options
|
|
114
|
+
|
|
115
|
+
- **`message`** — the visible prompt shown in chat.
|
|
116
|
+
- **`context`** — hidden context appended to the prompt (selected text, cursor position, current entity id — anything the agent should know but the user shouldn't see twice).
|
|
117
|
+
- **`submit`** — `true` to auto-run, `false` to prefill but wait. Omit to use the project default.
|
|
118
|
+
- **`openSidebar`** — set to `false` for background/silent sends. Default opens the sidebar so the user sees the response.
|
|
119
|
+
- **`type`** — `"content"` (default) keeps the work in the embedded app agent. `"code"` routes to the code-editing frame (for agent-written code changes, see [Frames](/docs/frames)).
|
|
120
|
+
|
|
121
|
+
`sendToAgentChat` returns a stable `tabId` you can use to track the chat run.
|
|
122
|
+
|
|
123
|
+
If you want a loading state, use the `useSendToAgentChat()` hook — it returns both `send` and `isGenerating`:
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { useSendToAgentChat } from "@agent-native/core/client";
|
|
127
|
+
|
|
128
|
+
const { send, isGenerating } = useSendToAgentChat();
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Typesafe actions from the UI: `useActionMutation()` {#use-action-mutation}
|
|
132
|
+
|
|
133
|
+
When the UI needs to run the same operation an agent tool would run — the fourth rung of the [ladder](/docs/what-is-agent-native#rung-three) — use `useActionMutation`:
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
import { useActionMutation } from "@agent-native/core/client";
|
|
137
|
+
|
|
138
|
+
const { mutate, isPending } = useActionMutation("replyToEmail");
|
|
139
|
+
|
|
140
|
+
<Button onClick={() => mutate({ emailId, body: "Thanks!" })}>
|
|
141
|
+
Send Reply
|
|
142
|
+
</Button>;
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Type-safe arguments come from the zod schema in your `defineAction()`. See [Actions](/docs/actions) for the full action system.
|
|
146
|
+
|
|
147
|
+
## Selection + cursor awareness {#selection}
|
|
148
|
+
|
|
149
|
+
The agent can see what the user has selected — text, cells, slides, contacts — via the `navigation` and `selection` keys in application state. If you'd like Cmd-I (or similar) to send a selected range into the chat as context, see [Context Awareness](/docs/context-awareness).
|
|
150
|
+
|
|
151
|
+
## Putting it all together {#putting-it-together}
|
|
152
|
+
|
|
153
|
+
A typical drop-in setup:
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
// app/root.tsx
|
|
157
|
+
import {
|
|
158
|
+
AgentSidebar,
|
|
159
|
+
AgentToggleButton,
|
|
160
|
+
sendToAgentChat,
|
|
161
|
+
} from "@agent-native/core/client";
|
|
162
|
+
|
|
163
|
+
export default function Root() {
|
|
164
|
+
return (
|
|
165
|
+
<AgentSidebar suggestions={["Draft a reply", "Summarize selection"]}>
|
|
166
|
+
<Header>
|
|
167
|
+
<AgentToggleButton />
|
|
168
|
+
</Header>
|
|
169
|
+
|
|
170
|
+
<Main>
|
|
171
|
+
<YourRoutes />
|
|
172
|
+
</Main>
|
|
173
|
+
</AgentSidebar>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
// Anywhere else in the app
|
|
180
|
+
<Button
|
|
181
|
+
onClick={() =>
|
|
182
|
+
sendToAgentChat({
|
|
183
|
+
message: "Summarize this thread",
|
|
184
|
+
context: `Thread id: ${threadId}`,
|
|
185
|
+
submit: true,
|
|
186
|
+
})
|
|
187
|
+
}
|
|
188
|
+
>
|
|
189
|
+
Summarize
|
|
190
|
+
</Button>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
The user sees a chat button in the header, can open it, and can talk to the agent. Your buttons hand work to that same agent instead of running one-shot LLM calls.
|
|
194
|
+
|
|
195
|
+
## What's next
|
|
196
|
+
|
|
197
|
+
- [**Actions**](/docs/actions) — `defineAction()` and `useActionMutation()`
|
|
198
|
+
- [**Context Awareness**](/docs/context-awareness) — selection, navigation, view-screen
|
|
199
|
+
- [**Workspace**](/docs/workspace) — what the Workspace tab contains (skills, memory, MCP servers, scheduled jobs)
|
|
200
|
+
- [**Voice Input**](/docs/voice-input) — the microphone in the chat composer
|
|
@@ -24,7 +24,7 @@ Anything every app in your org should agree on lives in the workspace core:
|
|
|
24
24
|
| Agent skills | `skills/<skill-name>/SKILL.md` |
|
|
25
25
|
| Shared agent actions | `actions/*.ts` |
|
|
26
26
|
| Shared React components | `src/client/*.tsx` (e.g. `AuthenticatedLayout`) |
|
|
27
|
-
| Design tokens / brand | `
|
|
27
|
+
| Design tokens / brand | `styles/tokens.css` |
|
|
28
28
|
| Shared API credentials | `src/credentials.ts` → `resolveCompanyCredential()` |
|
|
29
29
|
|
|
30
30
|
Each individual app becomes _just a set of screens_ — routes, dashboards, views, domain-specific actions. Everything else is inherited. If you're building ten tools for the same org, nine of them are 80% the same package, and the workspace core is where that 80% lives.
|
|
@@ -56,7 +56,7 @@ my-company-platform/
|
|
|
56
56
|
│ ├── actions/ # shared agent-callable actions
|
|
57
57
|
│ ├── skills/ # shared agent skills
|
|
58
58
|
│ ├── AGENTS.md # enterprise-wide instructions
|
|
59
|
-
│ └──
|
|
59
|
+
│ └── styles/tokens.css # brand tokens (Tailwind v4 @theme + CSS vars)
|
|
60
60
|
└── apps/
|
|
61
61
|
├── mail/
|
|
62
62
|
├── calendar/
|
|
@@ -159,6 +159,14 @@ A few onboarding flows are workspace-aware out of the box:
|
|
|
159
159
|
- **Builder `/cli-auth`**: clicking "Connect Builder" from any app writes `BUILDER_PRIVATE_KEY` and friends to the **workspace root** `.env`, so every app gains browser access at once.
|
|
160
160
|
- **Env-vars settings route** (`POST /_agent-native/env-vars`): when inside a workspace, defaults to writing the workspace root `.env`. Pass `scope: "app"` in the body to override one app.
|
|
161
161
|
|
|
162
|
+
## Shared MCP servers {#shared-mcp}
|
|
163
|
+
|
|
164
|
+
Drop an `mcp.config.json` at the workspace root and every app in the workspace connects to the same MCP servers — one place to configure `claude-in-chrome`, `@modelcontextprotocol/server-filesystem`, Playwright, or any internal MCP server. Individual apps can override with their own `mcp.config.json` (app-root wins over the workspace root for that one app).
|
|
165
|
+
|
|
166
|
+
For remote HTTP MCP servers (Zapier, Composio, internal tools), users can add them from the settings UI at **Personal** or **Team (org)** scope — no file edits, hot-reloaded into the running agent. And if you run the dispatch template, it can act as an **MCP hub** that every other app in the workspace pulls org-scope servers from, so you configure each URL + bearer token exactly once.
|
|
167
|
+
|
|
168
|
+
See [MCP Clients](/docs/mcp-clients) for the config schema, precedence rules, remote-UI scopes, and hub setup.
|
|
169
|
+
|
|
162
170
|
## Shared credentials {#shared-credentials}
|
|
163
171
|
|
|
164
172
|
Rotate a third-party API key in one place and every app picks it up:
|
|
@@ -173,18 +181,22 @@ Under the hood this wraps `@agent-native/core`'s `resolveCredential()`, which ch
|
|
|
173
181
|
|
|
174
182
|
## Shared design tokens {#design-tokens}
|
|
175
183
|
|
|
176
|
-
The
|
|
184
|
+
The framework is on Tailwind v4. The core ships a shared CSS file with the standard `@theme` tokens — each app imports it from its `app/global.css`:
|
|
177
185
|
|
|
178
|
-
```
|
|
179
|
-
import
|
|
186
|
+
```css
|
|
187
|
+
@import "tailwindcss";
|
|
188
|
+
@import "@my-company-platform/core-module/styles/tokens.css";
|
|
189
|
+
@source "./**/*.{ts,tsx}";
|
|
180
190
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
191
|
+
:root {
|
|
192
|
+
--background: 0 0% 100%; /* ...brand tokens... */
|
|
193
|
+
}
|
|
194
|
+
.dark {
|
|
195
|
+
--background: 220 6% 6%; /* ... */
|
|
196
|
+
}
|
|
185
197
|
```
|
|
186
198
|
|
|
187
|
-
Brand colors, typography, spacing scales, and any shared component classes live in one file. Update it in the core and every app rebrands on the next build. Shared React components in `src/client/` pick up the same tokens automatically.
|
|
199
|
+
Brand colors, typography, spacing scales, and any shared component classes live in that one CSS file. Update it in the core and every app rebrands on the next build. Shared React components in `src/client/` pick up the same tokens automatically.
|
|
188
200
|
|
|
189
201
|
## Deployment {#deployment}
|
|
190
202
|
|
|
@@ -5,7 +5,7 @@ description: "Pick a template, create your app, and start customizing it with AI
|
|
|
5
5
|
|
|
6
6
|
# Getting Started
|
|
7
7
|
|
|
8
|
-
The fastest way to get started is to pick a template and
|
|
8
|
+
The fastest way to get started is to pick a template and make it yours. Agent-native templates are **[cloneable SaaS](/docs/cloneable-saas)** — complete, production-grade apps, not starter kits. You get a working product in under a minute and start customizing it with the agent.
|
|
9
9
|
|
|
10
10
|
## Create Your Workspace {#create-your-app}
|
|
11
11
|
|
|
@@ -41,16 +41,19 @@ From here, use your AI coding tool (Claude Code, Cursor, Windsurf, etc.) to cust
|
|
|
41
41
|
|
|
42
42
|
Each template is a complete app with UI, agent actions, database schema, and AI instructions ready to go:
|
|
43
43
|
|
|
44
|
-
| Template
|
|
45
|
-
|
|
|
46
|
-
| [Mail](/templates/mail)
|
|
47
|
-
| [Calendar](/templates/calendar)
|
|
48
|
-
| [Content](/templates/content)
|
|
49
|
-
| [Slides](/templates/slides)
|
|
50
|
-
| [Video](/templates/video)
|
|
51
|
-
| [Analytics](/templates/analytics)
|
|
44
|
+
| Template | Replaces |
|
|
45
|
+
| ----------------------------------- | ------------------------------------------------ |
|
|
46
|
+
| [Mail](/templates/mail) | Superhuman, Gmail |
|
|
47
|
+
| [Calendar](/templates/calendar) | Google Calendar, Calendly |
|
|
48
|
+
| [Content](/templates/content) | Notion, Google Docs |
|
|
49
|
+
| [Slides](/templates/slides) | Google Slides, Pitch |
|
|
50
|
+
| [Video](/templates/video) | video editing |
|
|
51
|
+
| [Analytics](/templates/analytics) | Amplitude, Mixpanel, Looker |
|
|
52
|
+
| [Forms](/docs/template-forms) | Typeform |
|
|
53
|
+
| [Dispatch](/docs/template-dispatch) | Workspace control plane — secrets, routing, jobs |
|
|
54
|
+
| [Starter](/docs/template-starter) | Minimal scaffold — build from scratch |
|
|
52
55
|
|
|
53
|
-
Browse the [template gallery](/templates) for live demos and
|
|
56
|
+
Browse the [template gallery](/templates) for live demos, or see [Cloneable SaaS](/docs/cloneable-saas) for the full list and the clone → customize → deploy flow.
|
|
54
57
|
|
|
55
58
|
## Project Structure {#project-structure}
|
|
56
59
|
|
|
@@ -81,17 +84,29 @@ export default defineConfig();
|
|
|
81
84
|
{ "extends": "@agent-native/core/tsconfig.base.json" }
|
|
82
85
|
```
|
|
83
86
|
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
import
|
|
87
|
-
import
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
```css
|
|
88
|
+
/* app/global.css — Tailwind v4 (CSS-first, no tailwind.config.ts needed) */
|
|
89
|
+
@import "tailwindcss";
|
|
90
|
+
@import "@agent-native/core/styles/agent-native.css";
|
|
91
|
+
|
|
92
|
+
@source "./**/*.{ts,tsx}";
|
|
93
|
+
|
|
94
|
+
:root {
|
|
95
|
+
--background: 0 0% 100%;
|
|
96
|
+
--foreground: 220 10% 10%;
|
|
97
|
+
/* ...rest of your shadcn-style tokens */
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.dark {
|
|
101
|
+
--background: 220 6% 6%;
|
|
102
|
+
--foreground: 0 0% 90%;
|
|
103
|
+
/* ... */
|
|
104
|
+
}
|
|
93
105
|
```
|
|
94
106
|
|
|
107
|
+
The framework auto-injects `@tailwindcss/vite` from `defineConfig()`.
|
|
108
|
+
No `tailwind.config.ts`, `postcss.config.js`, or vite changes needed.
|
|
109
|
+
|
|
95
110
|
## Architecture Principles {#architecture-principles}
|
|
96
111
|
|
|
97
112
|
These principles apply to all agent-native apps. Understanding them helps you customize templates or build from scratch:
|
|
@@ -63,7 +63,7 @@ Subscribe to the `message.im` bot event (and optionally `app_mention` for channe
|
|
|
63
63
|
|
|
64
64
|
### 3. Set environment variables
|
|
65
65
|
|
|
66
|
-
```
|
|
66
|
+
```bash
|
|
67
67
|
SLACK_BOT_TOKEN=xoxb-your-bot-token
|
|
68
68
|
SLACK_SIGNING_SECRET=your-signing-secret
|
|
69
69
|
```
|
|
@@ -78,7 +78,7 @@ Message [@BotFather](https://t.me/BotFather) on Telegram and use the `/newbot` c
|
|
|
78
78
|
|
|
79
79
|
### 2. Set environment variables
|
|
80
80
|
|
|
81
|
-
```
|
|
81
|
+
```bash
|
|
82
82
|
TELEGRAM_BOT_TOKEN=your-bot-token
|
|
83
83
|
```
|
|
84
84
|
|
|
@@ -104,7 +104,7 @@ Go to the [Meta Developer Portal](https://developers.facebook.com/), create an a
|
|
|
104
104
|
|
|
105
105
|
### 2. Set environment variables
|
|
106
106
|
|
|
107
|
-
```
|
|
107
|
+
```bash
|
|
108
108
|
WHATSAPP_ACCESS_TOKEN=your-access-token
|
|
109
109
|
WHATSAPP_VERIFY_TOKEN=your-verify-token
|
|
110
110
|
WHATSAPP_PHONE_NUMBER_ID=your-phone-number-id
|
|
@@ -41,6 +41,23 @@ Six rules govern the architecture:
|
|
|
41
41
|
5. **The agent can modify code** — the app evolves as you use it
|
|
42
42
|
6. **Application state in SQL** — ephemeral UI state lives in the database, readable by both agent and UI
|
|
43
43
|
|
|
44
|
+
## What you get for free {#what-you-get-for-free}
|
|
45
|
+
|
|
46
|
+
Adopting the framework is valuable mostly because of what you stop having to build. The moment your app follows the six rules, you inherit:
|
|
47
|
+
|
|
48
|
+
- **One action = four surfaces.** Every action defined with `defineAction()` is simultaneously an agent tool, a typesafe frontend mutation (`useActionMutation("name")`), an HTTP endpoint at `/_agent-native/actions/:name`, and an MCP tool (when MCP is enabled). External agents can call it over [A2A](/docs/a2a-protocol) too. One implementation, four consumers.
|
|
49
|
+
- **A full workspace per user.** Skills, memory (`learnings.md`), `AGENTS.md`, custom sub-agents, scheduled jobs, connected MCP servers — all SQL-backed, per-user, no dev-box required. See [Workspace](/docs/workspace).
|
|
50
|
+
- **Drop-in React components.** `<AgentPanel />` and `<AgentSidebar />` render chat + workspace anywhere in your app. See [Drop-in Agent](/docs/drop-in-agent).
|
|
51
|
+
- **Live sync between agent and UI.** A 2-second poll invalidates React Query caches whenever the agent writes to the DB. No WebSockets, no serverless-unfriendly long-lived connections. See [Polling Sync](#polling-sync) below.
|
|
52
|
+
- **Auth, orgs, RBAC.** Better Auth with orgs/members/roles is wired in for every template. See [Authentication](/docs/authentication).
|
|
53
|
+
- **Context awareness.** The agent always knows what the user is looking at through the `navigation` app-state key. See [Context Awareness](/docs/context-awareness).
|
|
54
|
+
- **MCP client + server, both directions.** The app ingests MCP servers (local, remote, hub-shared) _and_ exposes its own actions as an MCP server. See [MCP Clients](/docs/mcp-clients) and [MCP Protocol](/docs/mcp-protocol).
|
|
55
|
+
- **Inter-app delegation.** Agents in different apps talk over [A2A](/docs/a2a-protocol). Same-origin deploys skip JWT; cross-origin uses a shared `A2A_SECRET`.
|
|
56
|
+
- **Sub-agent teams.** Spawn a sub-agent with its own thread and tools, surfaced as a chip inline in chat. See [Agent Teams](/docs/agent-teams).
|
|
57
|
+
- **Portability.** Any Drizzle-supported SQL database, any Nitro-compatible host (Node, Workers, Netlify, Vercel, Deno, Lambda, Bun).
|
|
58
|
+
|
|
59
|
+
That's the "and everything else" you'd otherwise be gluing together yourself.
|
|
60
|
+
|
|
44
61
|
## The four-area checklist {#four-area-checklist}
|
|
45
62
|
|
|
46
63
|
Every new feature must update all four areas. Skipping any one breaks the agent-native contract.
|
|
@@ -65,7 +82,7 @@ Core SQL stores are auto-created and available in every template:
|
|
|
65
82
|
- `oauth_tokens` — OAuth credentials
|
|
66
83
|
- `sessions` — auth sessions
|
|
67
84
|
|
|
68
|
-
```
|
|
85
|
+
```ts
|
|
69
86
|
// Drizzle schema for domain data
|
|
70
87
|
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
|
|
71
88
|
|
|
@@ -76,9 +93,11 @@ export const forms = sqliteTable("forms", {
|
|
|
76
93
|
ownerEmail: text("owner_email"),
|
|
77
94
|
createdAt: integer("created_at").notNull(),
|
|
78
95
|
});
|
|
96
|
+
```
|
|
79
97
|
|
|
80
|
-
|
|
81
|
-
|
|
98
|
+
```bash
|
|
99
|
+
# Core actions for quick database access
|
|
100
|
+
pnpm action db-schema # show all tables
|
|
82
101
|
pnpm action db-query --sql "SELECT * FROM forms"
|
|
83
102
|
pnpm action db-exec --sql "INSERT INTO forms ..."
|
|
84
103
|
# Surgical find/replace on a large text column — sends a diff, not the whole value
|
|
@@ -110,26 +129,34 @@ Why not call an LLM inline?
|
|
|
110
129
|
|
|
111
130
|
## Actions system {#actions-system}
|
|
112
131
|
|
|
113
|
-
When the agent needs to do something complex — call an API, process data, query the database — it runs an action
|
|
132
|
+
When the agent needs to do something complex — call an API, process data, query the database — it runs an **action**. Actions are TypeScript files in `actions/` that export a default `defineAction()`:
|
|
114
133
|
|
|
115
134
|
```ts
|
|
116
135
|
// actions/fetch-data.ts
|
|
117
|
-
import {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
136
|
+
import { defineAction } from "@agent-native/core";
|
|
137
|
+
import { z } from "zod";
|
|
138
|
+
|
|
139
|
+
export default defineAction({
|
|
140
|
+
description: "Fetch data from a source API.",
|
|
141
|
+
schema: z.object({
|
|
142
|
+
source: z.string().describe("Data source key, e.g. 'signups'"),
|
|
143
|
+
}),
|
|
144
|
+
run: async ({ source }) => {
|
|
145
|
+
const res = await fetch(`https://api.example.com/${source}`);
|
|
146
|
+
return await res.json();
|
|
147
|
+
},
|
|
148
|
+
});
|
|
125
149
|
```
|
|
126
150
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
151
|
+
One `defineAction()` call gives you:
|
|
152
|
+
|
|
153
|
+
- **Agent tool** — the agent sees it with the zod-derived JSON Schema and can call it.
|
|
154
|
+
- **Frontend mutation** — `useActionMutation("fetch-data")` with full TypeScript inference.
|
|
155
|
+
- **HTTP endpoint** — `POST /_agent-native/actions/fetch-data` (auto-mounted).
|
|
156
|
+
- **CLI** — `pnpm action fetch-data --source=signups` for scripting and agent dev loops.
|
|
157
|
+
- **MCP tool / A2A tool** — when MCP server or A2A is enabled, the same action shows up there too.
|
|
131
158
|
|
|
132
|
-
|
|
159
|
+
Same logic, one definition, wired to every consumer automatically. See [Actions](/docs/actions) for the full reference.
|
|
133
160
|
|
|
134
161
|
## Polling sync {#polling-sync}
|
|
135
162
|
|
|
@@ -169,14 +196,14 @@ The agent always knows what the user is looking at. The UI writes a `navigation`
|
|
|
169
196
|
|
|
170
197
|
See [Context Awareness](/docs/context-awareness) for the full pattern: navigation state, view-screen, navigate commands, and jitter prevention.
|
|
171
198
|
|
|
172
|
-
##
|
|
199
|
+
## Actions, MCP, and A2A — one surface, many protocols {#protocols}
|
|
173
200
|
|
|
174
|
-
|
|
201
|
+
Every action you define automatically becomes available over multiple protocols — you don't pick one. The framework runs both an MCP server and an A2A peer for your app, with actions feeding both.
|
|
175
202
|
|
|
176
|
-
- **
|
|
177
|
-
- **
|
|
178
|
-
- **
|
|
179
|
-
- **
|
|
203
|
+
- **Actions first.** Write the logic once as an action. Use `fetch()` and any SDK you want inside — no wrapper layer.
|
|
204
|
+
- **MCP for the outside world.** Your actions show up as MCP tools to Claude Desktop, ChatGPT's remote-MCP support, and any other MCP client. Your app also _consumes_ MCP servers — local, remote, or from a workspace hub. See [MCP Clients](/docs/mcp-clients) and [MCP Protocol](/docs/mcp-protocol).
|
|
205
|
+
- **A2A for other agents.** Other agent-native apps discover and call your actions over [A2A](/docs/a2a-protocol) — same-origin deploys skip JWT entirely.
|
|
206
|
+
- **CLIs still work.** `pnpm action <name>` and direct shell tools (`ffmpeg`, `gh`, `aws`) remain available whenever they're the simplest path.
|
|
180
207
|
|
|
181
208
|
## Agent modifies code {#agent-modifies-code}
|
|
182
209
|
|
|
@@ -9,6 +9,8 @@ Agent-native apps can also act as MCP **clients** — connecting to locally inst
|
|
|
9
9
|
|
|
10
10
|
With one config file, every agent-native app in your workspace gains access to tools provided by MCP servers on your machine: `claude-in-chrome` for browser automation, `@modelcontextprotocol/server-filesystem` for reading files, `@modelcontextprotocol/server-playwright` for browser testing, and anything else that speaks MCP.
|
|
11
11
|
|
|
12
|
+
You can also [connect remote (HTTP) MCP servers at runtime](#remote-via-ui) — individual users or whole organizations — without editing a config file.
|
|
13
|
+
|
|
12
14
|
## Adding a local MCP server {#adding-a-server}
|
|
13
15
|
|
|
14
16
|
Create `mcp.config.json` at your workspace root (or at an individual app root — workspace root wins when both exist):
|
|
@@ -73,6 +75,75 @@ If you have **no** `mcp.config.json` and the `claude-in-chrome-mcp` binary is on
|
|
|
73
75
|
|
|
74
76
|
This means users who've installed the claude-in-chrome extension get browser control across every agent-native app they open with no config changes.
|
|
75
77
|
|
|
78
|
+
## Remote MCP servers via the settings UI {#remote-via-ui}
|
|
79
|
+
|
|
80
|
+
Users don't have to edit `mcp.config.json` to add a remote, HTTP-based MCP server (Zapier, Cloudflare, Composio, an internal tool, etc). Open the settings panel → **MCP Servers** and paste the server's URL. Two scopes are supported:
|
|
81
|
+
|
|
82
|
+
- **Personal** — only the signed-in user gets the tools. Stored as a user-scope setting.
|
|
83
|
+
- **Team** — everyone in the active organization gets the tools. Owners and admins can add; members see the list read-only. Stored as an org-scope setting.
|
|
84
|
+
|
|
85
|
+
Adds and removes hot-reload into the running MCP manager — no process restart, and no server restart. The new `mcp__<scope>-<name>__*` tools appear to the agent on the next message.
|
|
86
|
+
|
|
87
|
+
HTTPS URLs are accepted everywhere; plain `http://` is only allowed for `localhost` during development. Optional auth goes in as a Bearer token that's sent via `Authorization: Bearer …` on every request.
|
|
88
|
+
|
|
89
|
+
Under the hood these servers are persisted in the framework's `settings` table under the key `u:<email>:mcp-servers-remote` (Personal) or `o:<orgId>:mcp-servers-remote` (Team) and merged with `mcp.config.json` on startup.
|
|
90
|
+
|
|
91
|
+
### HTTP endpoints
|
|
92
|
+
|
|
93
|
+
| Method | Route | Purpose |
|
|
94
|
+
| ------ | ----------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
95
|
+
| GET | `/_agent-native/mcp/servers` | List the current user's personal + org servers with live status. |
|
|
96
|
+
| POST | `/_agent-native/mcp/servers` | Add a server. Body: `{ scope, name, url, headers?, description? }`. |
|
|
97
|
+
| DELETE | `/_agent-native/mcp/servers/:id?scope=user\|org` | Remove a server and reconfigure the manager. |
|
|
98
|
+
| POST | `/_agent-native/mcp/servers/:id/test?scope=user\|org` | Dry-run the existing server's connect + list-tools. |
|
|
99
|
+
| POST | `/_agent-native/mcp/servers/test` | Dry-run an arbitrary URL before persisting. Body: `{ url, headers? }`. |
|
|
100
|
+
|
|
101
|
+
Stdio servers are still a no-op outside Node runtimes, but remote HTTP MCP servers work in any environment with `fetch` — including desktop production builds.
|
|
102
|
+
|
|
103
|
+
## Shared MCP servers via a hub {#hub}
|
|
104
|
+
|
|
105
|
+
If your workspace runs multiple agent-native apps (e.g. dispatch + mail + clips), you can configure **one** app as the hub and have the others pull its org-scope MCP servers automatically. No per-app copy-paste of URLs and bearer tokens.
|
|
106
|
+
|
|
107
|
+
Dispatch is the conventional hub — it already coordinates across apps.
|
|
108
|
+
|
|
109
|
+
### 1. Enable hub-serve on the hub app (dispatch)
|
|
110
|
+
|
|
111
|
+
Set an env var in dispatch's deployment:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
AGENT_NATIVE_MCP_HUB_TOKEN=<a-long-random-secret>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Dispatch now mounts `GET /_agent-native/mcp/hub/servers` which returns every org-scope MCP server stored in its `settings` table, with full URL + headers, authenticated by the token.
|
|
118
|
+
|
|
119
|
+
### 2. Point consuming apps at the hub
|
|
120
|
+
|
|
121
|
+
Set on every consumer (mail, clips, whatever):
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
AGENT_NATIVE_MCP_HUB_URL=https://dispatch.acme.com
|
|
125
|
+
AGENT_NATIVE_MCP_HUB_TOKEN=<the-same-secret>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
At startup, each consumer pulls the hub's server list and merges it into its own MCP manager. The tools appear to the agent as `mcp__hub_<orgId>_<name>__*` — distinct from the consumer's own local `mcp__org_…` so there's no collision.
|
|
129
|
+
|
|
130
|
+
### 3. What gets shared
|
|
131
|
+
|
|
132
|
+
Only **org-scope** servers are shared. User-scope (Personal) servers stay with the user who added them — the hub never re-exposes personal credentials across apps.
|
|
133
|
+
|
|
134
|
+
Hub responses include the full auth headers (Bearer tokens etc). The transport is HTTPS, the endpoint requires the shared secret, and it only returns org-scope rows — treat the hub URL + token like a database credential.
|
|
135
|
+
|
|
136
|
+
### 4. Hot reload vs restart
|
|
137
|
+
|
|
138
|
+
Local UI adds in each app hot-reload via `McpClientManager.reconfigure()` — no restart. Hub-sourced servers currently re-fetch only when a local mutation triggers a reconfigure (or when the app restarts), so if you add a new server in dispatch, other apps pick it up on their next restart or next local change. Periodic background refresh is on the roadmap.
|
|
139
|
+
|
|
140
|
+
### Endpoints summary
|
|
141
|
+
|
|
142
|
+
| Method | Route | Purpose |
|
|
143
|
+
| ------ | -------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
144
|
+
| GET | `/_agent-native/mcp/hub/servers` | Serve all org-scope servers with full creds (bearer-gated, only mounted when `AGENT_NATIVE_MCP_HUB_TOKEN` is set). |
|
|
145
|
+
| GET | `/_agent-native/mcp/hub/status` | Returns `{ serving, consuming, hubUrl }` for the settings UI card. |
|
|
146
|
+
|
|
76
147
|
## Status route {#status-route}
|
|
77
148
|
|
|
78
149
|
Every app exposes `GET /_agent-native/mcp/status` for tooling and onboarding:
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Pure-Agent Apps"
|
|
3
|
+
description: "Build an agent without a heavy UI — just the agent plus a minimal observability/management surface. All the framework benefits, none of the dashboard work."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Pure-Agent Apps
|
|
7
|
+
|
|
8
|
+
Not every agent-native app needs a full SaaS-style interface. Sometimes the agent _is_ the product. A support triage agent. A daily report generator. A research bot. An email auto-responder. An ops runbook executor.
|
|
9
|
+
|
|
10
|
+
For these, the "app" is mostly just the agent doing work in the background. You still want a UI — but a minimal one, focused on **observability, management, and steering** rather than hand-crafted dashboards and forms.
|
|
11
|
+
|
|
12
|
+
This is the "agents benefit from a UI even when there's no rich app around them" pattern. The hot take is "agents will replace apps." The reality is "every agent eventually needs a UI for humans to supervise, configure, and debug it." Agent-native gives you that UI for free.
|
|
13
|
+
|
|
14
|
+
## The minimum viable UI {#minimum-ui}
|
|
15
|
+
|
|
16
|
+
A pure-agent app ships with five surfaces, all provided by the framework — you don't build them:
|
|
17
|
+
|
|
18
|
+
1. **Chat** — the main input. Users talk to the agent, steer it, queue tasks. (`<AgentSidebar>` or `<AgentPanel>`)
|
|
19
|
+
2. **Workspace** — skills, memory (`learnings.md`), `AGENTS.md`, custom sub-agents, connected MCP servers, scheduled jobs. Customize the agent's behavior without shipping code. (Workspace tab in the sidebar)
|
|
20
|
+
3. **Job history** — which scheduled jobs ran, when, whether they succeeded, what they did. (Workspace tab → `jobs/`)
|
|
21
|
+
4. **Thread history** — every past conversation, each preserved with its tool calls and final output. (Chat tab)
|
|
22
|
+
5. **Settings** — API keys, connected accounts, onboarding status. (Sidebar settings)
|
|
23
|
+
|
|
24
|
+
Those five together are enough UI for most pure-agent use cases. No analytics dashboard. No Kanban. No forms. Just: talk to it, see what it's done, configure how it behaves.
|
|
25
|
+
|
|
26
|
+
## When to pick this pattern {#when-to-pick}
|
|
27
|
+
|
|
28
|
+
Pure-agent makes sense when:
|
|
29
|
+
|
|
30
|
+
- **The work happens in the background.** Scheduled jobs, webhook-triggered handlers, Slack/Telegram responders. Users rarely sit in the app.
|
|
31
|
+
- **The output leaves the app.** The agent posts to Slack, sends email, writes to a third-party system. There's nothing to view in-app; the value is elsewhere.
|
|
32
|
+
- **The domain is one-shot.** A research bot that returns a report. No persistent object to dashboard.
|
|
33
|
+
- **You're prototyping.** Ship the agent now; add a rich UI only when you've proven users need it.
|
|
34
|
+
|
|
35
|
+
Pick a full [cloneable SaaS](/docs/cloneable-saas) template instead when the app has real persistent objects (emails, events, documents, charts) users need to browse, pivot, and share.
|
|
36
|
+
|
|
37
|
+
## The minimal scaffold {#scaffold}
|
|
38
|
+
|
|
39
|
+
Start from the **Starter** template:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pnpm dlx @agent-native/core create my-agent --template starter
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Starter gives you the six-rules architecture, the agent panel, the workspace, auth, polling, and one example action — and nothing else. Add your own actions in `actions/`, connect any MCP servers you need, write the relevant skills into the workspace, and you're done. The "UI" is the agent sidebar — which is already complete.
|
|
46
|
+
|
|
47
|
+
If you really want _zero_ UI except the agent, `app/routes/index.tsx` can just render `<AgentPanel defaultMode="chat" />` fullscreen. The only thing the user sees is the chat. Everything else — job history, workspace, settings — is one click away in the panel's tabs.
|
|
48
|
+
|
|
49
|
+
## What you still get for free {#still-free}
|
|
50
|
+
|
|
51
|
+
Even with no custom UI, you still inherit every framework benefit:
|
|
52
|
+
|
|
53
|
+
- **Actions** as agent tools + HTTP endpoints + MCP tools + A2A tools. External agents, Claude Desktop, and your own HTTP clients can drive the agent without going through the chat UI.
|
|
54
|
+
- **Recurring jobs** for scheduled work — "every morning at 7 summarize my unread emails and post to Slack."
|
|
55
|
+
- **The workspace** for per-user customization, skills, memory, MCP connections.
|
|
56
|
+
- **Sub-agent delegation** via [agent teams](/docs/agent-teams).
|
|
57
|
+
- **Portability** — deploys to any serverless host, any SQL database.
|
|
58
|
+
- **Multi-tenant by default** — each user gets their own workspace without a dev-box.
|
|
59
|
+
|
|
60
|
+
## Adding a tiny bit of UI {#tiny-ui}
|
|
61
|
+
|
|
62
|
+
Most "pure-agent" apps eventually want a little bit of custom UI — not a dashboard, but maybe a status page, a job history, or a config screen. The [drop-in agent](/docs/drop-in-agent) components coexist with anything else you render. Add a single `/status` route that lists recent runs; keep everything else in the chat. That's usually enough.
|
|
63
|
+
|
|
64
|
+
## What's next
|
|
65
|
+
|
|
66
|
+
- [**Recurring Jobs**](/docs/recurring-jobs) — scheduled prompts the agent runs on its own
|
|
67
|
+
- [**Drop-in Agent**](/docs/drop-in-agent) — mounting `<AgentPanel>` fullscreen or in a sidebar
|
|
68
|
+
- [**Actions**](/docs/actions) — the tools your pure-agent will call
|
|
69
|
+
- [**Workspace**](/docs/workspace) — the customization surface for skills, memory, and MCP servers
|