@assistant-ui/mcp-docs-server 0.1.31 → 0.1.32

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 (247) hide show
  1. package/.docs/organized/code-examples/waterfall.md +8 -8
  2. package/.docs/organized/code-examples/with-a2a.md +10 -10
  3. package/.docs/organized/code-examples/with-ag-ui.md +11 -11
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +13 -13
  5. package/.docs/organized/code-examples/with-artifacts.md +13 -13
  6. package/.docs/organized/code-examples/with-assistant-transport.md +10 -10
  7. package/.docs/organized/code-examples/with-browser-extension.md +345 -0
  8. package/.docs/organized/code-examples/with-chain-of-thought.md +54 -17
  9. package/.docs/organized/code-examples/with-cloud-standalone.md +13 -13
  10. package/.docs/organized/code-examples/with-cloud.md +13 -13
  11. package/.docs/organized/code-examples/with-custom-thread-list.md +13 -13
  12. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +17 -16
  13. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +17 -16
  14. package/.docs/organized/code-examples/with-expo.md +24 -24
  15. package/.docs/organized/code-examples/with-external-store.md +10 -10
  16. package/.docs/organized/code-examples/with-ffmpeg.md +13 -13
  17. package/.docs/organized/code-examples/with-generative-ui.md +210 -13
  18. package/.docs/organized/code-examples/with-google-adk.md +10 -10
  19. package/.docs/organized/code-examples/with-heat-graph.md +8 -8
  20. package/.docs/organized/code-examples/with-image-generation.md +454 -0
  21. package/.docs/organized/code-examples/with-interactables.md +13 -13
  22. package/.docs/organized/code-examples/with-langchain.md +12 -12
  23. package/.docs/organized/code-examples/with-langgraph.md +15 -12
  24. package/.docs/organized/code-examples/with-livekit.md +18 -17
  25. package/.docs/organized/code-examples/with-mcp.md +748 -0
  26. package/.docs/organized/code-examples/with-opencode.md +11 -11
  27. package/.docs/organized/code-examples/with-parent-id-grouping.md +11 -11
  28. package/.docs/organized/code-examples/with-react-hook-form.md +14 -14
  29. package/.docs/organized/code-examples/with-react-ink.md +4 -4
  30. package/.docs/organized/code-examples/with-react-router.md +15 -15
  31. package/.docs/organized/code-examples/with-resumable-stream.md +660 -0
  32. package/.docs/organized/code-examples/with-store.md +8 -8
  33. package/.docs/organized/code-examples/with-tanstack.md +14 -14
  34. package/.docs/organized/code-examples/with-tap-runtime.md +11 -10
  35. package/.docs/raw/docs/(docs)/cli.mdx +1 -0
  36. package/.docs/raw/docs/(docs)/index.mdx +2 -2
  37. package/.docs/raw/docs/(docs)/installation.mdx +1 -1
  38. package/.docs/raw/docs/(reference)/api-reference/adapters/attachments.mdx +26 -24
  39. package/.docs/raw/docs/(reference)/api-reference/adapters/feedback.mdx +20 -0
  40. package/.docs/raw/docs/(reference)/api-reference/adapters/index.mdx +20 -12
  41. package/.docs/raw/docs/(reference)/api-reference/adapters/model.mdx +44 -0
  42. package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +37 -16
  43. package/.docs/raw/docs/(reference)/api-reference/adapters/runtime.mdx +12 -23
  44. package/.docs/raw/docs/(reference)/api-reference/adapters/suggestions.mdx +20 -0
  45. package/.docs/raw/docs/(reference)/api-reference/context-providers/assistant-runtime-provider.mdx +37 -8
  46. package/.docs/raw/docs/(reference)/api-reference/context-providers/index.mdx +11 -9
  47. package/.docs/raw/docs/(reference)/api-reference/context-providers/scoped-providers.mdx +64 -0
  48. package/.docs/raw/docs/(reference)/api-reference/external-store/index.mdx +22 -0
  49. package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +52 -0
  50. package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +36 -0
  51. package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +98 -0
  52. package/.docs/raw/docs/(reference)/api-reference/hooks/index.mdx +18 -13
  53. package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +18 -57
  54. package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +640 -0
  55. package/.docs/raw/docs/(reference)/api-reference/hooks/runtimes.mdx +15 -28
  56. package/.docs/raw/docs/(reference)/api-reference/hooks/state.mdx +64 -18
  57. package/.docs/raw/docs/(reference)/api-reference/hooks/utilities.mdx +434 -0
  58. package/.docs/raw/docs/(reference)/api-reference/integrations/cloud-ai-sdk.mdx +24 -0
  59. package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +11 -12
  60. package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +79 -0
  61. package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +52 -0
  62. package/.docs/raw/docs/(reference)/api-reference/model-context/index.mdx +22 -0
  63. package/.docs/raw/docs/(reference)/api-reference/model-context/registry.mdx +20 -0
  64. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +110 -131
  65. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar-more.mdx +78 -221
  66. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +127 -242
  67. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +39 -20
  68. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +66 -87
  69. package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +50 -58
  70. package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +80 -48
  71. package/.docs/raw/docs/(reference)/api-reference/primitives/chain-of-thought.mdx +67 -0
  72. package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +323 -461
  73. package/.docs/raw/docs/(reference)/api-reference/primitives/error.mdx +36 -43
  74. package/.docs/raw/docs/(reference)/api-reference/primitives/index.mdx +29 -24
  75. package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +63 -245
  76. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +175 -591
  77. package/.docs/raw/docs/(reference)/api-reference/primitives/queue-item.mdx +65 -0
  78. package/.docs/raw/docs/(reference)/api-reference/primitives/selection-toolbar.mdx +35 -22
  79. package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +57 -140
  80. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item-more.mdx +70 -161
  81. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +84 -108
  82. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +77 -96
  83. package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +173 -349
  84. package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +9 -21
  85. package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +10 -21
  86. package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +15 -70
  87. package/.docs/raw/docs/(reference)/api-reference/runtimes/index.mdx +18 -13
  88. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +25 -28
  89. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +11 -63
  90. package/.docs/raw/docs/(reference)/api-reference/runtimes/queue-state.mdx +20 -0
  91. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +11 -48
  92. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +10 -47
  93. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +18 -30
  94. package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +68 -0
  95. package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +39 -0
  96. package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +79 -0
  97. package/.docs/raw/docs/(reference)/api-reference/tools/status.mdx +42 -0
  98. package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +92 -0
  99. package/.docs/raw/docs/(reference)/api-reference/transport/assistant-transport.mdx +48 -0
  100. package/.docs/raw/docs/(reference)/api-reference/transport/frame.mdx +62 -0
  101. package/.docs/raw/docs/(reference)/api-reference/transport/index.mdx +22 -0
  102. package/.docs/raw/docs/(reference)/api-reference/utilities/index.mdx +19 -0
  103. package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +131 -0
  104. package/.docs/raw/docs/(reference)/api-reference/voice/index.mdx +22 -0
  105. package/.docs/raw/docs/(reference)/api-reference/voice/session.mdx +54 -0
  106. package/.docs/raw/docs/(reference)/api-reference/voice/speech-dictation.mdx +36 -0
  107. package/.docs/raw/docs/cloud/ai-sdk.mdx +1 -1
  108. package/.docs/raw/docs/cloud/index.mdx +2 -2
  109. package/.docs/raw/docs/guides/attachments.mdx +4 -4
  110. package/.docs/raw/docs/guides/branching.mdx +1 -1
  111. package/.docs/raw/docs/guides/chain-of-thought.mdx +5 -5
  112. package/.docs/raw/docs/guides/context-api.mdx +4 -4
  113. package/.docs/raw/docs/guides/dictation.mdx +2 -2
  114. package/.docs/raw/docs/guides/editing.mdx +1 -1
  115. package/.docs/raw/docs/guides/generative-ui.mdx +142 -0
  116. package/.docs/raw/docs/guides/image-generation.mdx +74 -0
  117. package/.docs/raw/docs/guides/index.mdx +2 -2
  118. package/.docs/raw/docs/guides/interactables.mdx +2 -2
  119. package/.docs/raw/docs/guides/latex.mdx +2 -2
  120. package/.docs/raw/docs/guides/mcp-apps.mdx +231 -0
  121. package/.docs/raw/docs/guides/mentions.mdx +2 -2
  122. package/.docs/raw/docs/guides/message-timing.mdx +38 -5
  123. package/.docs/raw/docs/guides/multi-agent.mdx +2 -2
  124. package/.docs/raw/docs/guides/quoting.mdx +1 -1
  125. package/.docs/raw/docs/guides/resumable-stream-deployment.mdx +212 -0
  126. package/.docs/raw/docs/guides/resumable-stream-stores.mdx +152 -0
  127. package/.docs/raw/docs/guides/resumable-streams.mdx +210 -0
  128. package/.docs/raw/docs/guides/slash-commands.mdx +1 -1
  129. package/.docs/raw/docs/guides/speech.mdx +2 -2
  130. package/.docs/raw/docs/guides/suggestions.mdx +88 -4
  131. package/.docs/raw/docs/guides/tool-ui.mdx +2 -2
  132. package/.docs/raw/docs/guides/tools.mdx +66 -5
  133. package/.docs/raw/docs/guides/voice.mdx +2 -2
  134. package/.docs/raw/docs/ink/adapters.mdx +37 -1
  135. package/.docs/raw/docs/ink/custom-backend.mdx +59 -8
  136. package/.docs/raw/docs/ink/index.mdx +10 -11
  137. package/.docs/raw/docs/ink/primitives.mdx +349 -8
  138. package/.docs/raw/docs/integrations/auth/better-auth.mdx +1 -1
  139. package/.docs/raw/docs/integrations/auth/clerk.mdx +1 -1
  140. package/.docs/raw/docs/integrations/auth/next-auth.mdx +1 -1
  141. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +2 -2
  142. package/.docs/raw/docs/integrations/frameworks/cloudflare-agents/overview.mdx +282 -0
  143. package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +2 -2
  144. package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +1 -1
  145. package/.docs/raw/docs/integrations/gateways/index.mdx +9 -4
  146. package/.docs/raw/docs/integrations/index.mdx +15 -3
  147. package/.docs/raw/docs/integrations/observability/langfuse.mdx +8 -1
  148. package/.docs/raw/docs/integrations/observability/langsmith.mdx +8 -4
  149. package/.docs/raw/docs/integrations/tools/react-mcp.mdx +337 -0
  150. package/.docs/raw/docs/primitives/composer.mdx +53 -0
  151. package/.docs/raw/docs/primitives/index.mdx +2 -2
  152. package/.docs/raw/docs/primitives/suggestion.mdx +9 -0
  153. package/.docs/raw/docs/react-native/hooks.mdx +2 -2
  154. package/.docs/raw/docs/react-native/index.mdx +4 -4
  155. package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +4 -4
  156. package/.docs/raw/docs/runtimes/a2a/overview.mdx +2 -2
  157. package/.docs/raw/docs/runtimes/ag-ui/overview.mdx +2 -2
  158. package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +32 -1
  159. package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +2 -2
  160. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +7 -2
  161. package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +1 -1
  162. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +7 -0
  163. package/.docs/raw/docs/runtimes/custom/data-stream.mdx +27 -2
  164. package/.docs/raw/docs/runtimes/custom/external-store.mdx +9 -1
  165. package/.docs/raw/docs/runtimes/custom/overview.mdx +2 -2
  166. package/.docs/raw/docs/runtimes/google-adk/overview.mdx +2 -2
  167. package/.docs/raw/docs/runtimes/langchain.mdx +2 -2
  168. package/.docs/raw/docs/runtimes/langgraph/overview.mdx +2 -2
  169. package/.docs/raw/docs/runtimes/opencode/overview.mdx +2 -2
  170. package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +1 -1
  171. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +12 -5
  172. package/.docs/raw/docs/ui/composer-trigger-popover.mdx +11 -1
  173. package/.docs/raw/docs/ui/mcp-config.mdx +102 -0
  174. package/.docs/raw/docs/ui/model-selector.mdx +8 -8
  175. package/.docs/raw/docs/ui/sources.mdx +17 -0
  176. package/.docs/raw/docs/ui/streamdown.mdx +34 -2
  177. package/.docs/raw/docs/ui/thread-list.mdx +2 -2
  178. package/.docs/raw/docs/ui/thread.mdx +2 -2
  179. package/README.md +14 -72
  180. package/dist/constants.d.ts +12 -9
  181. package/dist/constants.d.ts.map +1 -1
  182. package/dist/constants.js +13 -9
  183. package/dist/constants.js.map +1 -1
  184. package/dist/index.d.ts +7 -3
  185. package/dist/index.d.ts.map +1 -1
  186. package/dist/index.js +25 -24
  187. package/dist/index.js.map +1 -1
  188. package/dist/prepare-docs/code-examples.d.ts +4 -1
  189. package/dist/prepare-docs/code-examples.d.ts.map +1 -1
  190. package/dist/prepare-docs/code-examples.js +109 -121
  191. package/dist/prepare-docs/code-examples.js.map +1 -1
  192. package/dist/prepare-docs/copy-raw.d.ts +4 -1
  193. package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
  194. package/dist/prepare-docs/copy-raw.js +45 -42
  195. package/dist/prepare-docs/copy-raw.js.map +1 -1
  196. package/dist/prepare-docs/prepare.d.ts +1 -2
  197. package/dist/prepare-docs/prepare.js +17 -17
  198. package/dist/prepare-docs/prepare.js.map +1 -1
  199. package/dist/stdio.d.ts +1 -3
  200. package/dist/stdio.js +6 -3
  201. package/dist/stdio.js.map +1 -1
  202. package/dist/tools/docs.d.ts +20 -15
  203. package/dist/tools/docs.d.ts.map +1 -1
  204. package/dist/tools/docs.js +140 -161
  205. package/dist/tools/docs.js.map +1 -1
  206. package/dist/tools/examples.d.ts +20 -15
  207. package/dist/tools/examples.d.ts.map +1 -1
  208. package/dist/tools/examples.js +74 -86
  209. package/dist/tools/examples.js.map +1 -1
  210. package/dist/tools/tests/test-setup.d.ts +5 -2
  211. package/dist/tools/tests/test-setup.d.ts.map +1 -1
  212. package/dist/tools/tests/test-setup.js +21 -28
  213. package/dist/tools/tests/test-setup.js.map +1 -1
  214. package/dist/utils/logger.d.ts +8 -5
  215. package/dist/utils/logger.d.ts.map +1 -1
  216. package/dist/utils/logger.js +17 -17
  217. package/dist/utils/logger.js.map +1 -1
  218. package/dist/utils/mcp-format.d.ts +8 -5
  219. package/dist/utils/mcp-format.d.ts.map +1 -1
  220. package/dist/utils/mcp-format.js +9 -9
  221. package/dist/utils/mcp-format.js.map +1 -1
  222. package/dist/utils/mdx.d.ts +8 -6
  223. package/dist/utils/mdx.d.ts.map +1 -1
  224. package/dist/utils/mdx.js +22 -22
  225. package/dist/utils/mdx.js.map +1 -1
  226. package/dist/utils/paths.d.ts +9 -6
  227. package/dist/utils/paths.d.ts.map +1 -1
  228. package/dist/utils/paths.js +66 -76
  229. package/dist/utils/paths.js.map +1 -1
  230. package/dist/utils/security.d.ts +4 -1
  231. package/dist/utils/security.d.ts.map +1 -1
  232. package/dist/utils/security.js +19 -40
  233. package/dist/utils/security.js.map +1 -1
  234. package/package.json +5 -5
  235. package/.docs/raw/docs/(reference)/api-reference/adapters/feedback-speech.mdx +0 -41
  236. package/.docs/raw/docs/(reference)/api-reference/context-providers/text-message-part-provider.mdx +0 -40
  237. package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +0 -260
  238. package/.docs/raw/docs/(reference)/api-reference/integrations/react-hook-form.mdx +0 -103
  239. package/.docs/raw/docs/(reference)/api-reference/integrations/vercel-ai-sdk.mdx +0 -254
  240. package/dist/prepare-docs/prepare.d.ts.map +0 -1
  241. package/dist/stdio.d.ts.map +0 -1
  242. /package/.docs/raw/docs/{(reference)/migrations → migrations}/deprecation-policy.mdx +0 -0
  243. /package/.docs/raw/docs/{(reference) → migrations}/react-compatibility.mdx +0 -0
  244. /package/.docs/raw/docs/{(reference)/migrations → migrations}/react-langgraph-v0-7.mdx +0 -0
  245. /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-11.mdx +0 -0
  246. /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-12.mdx +0 -0
  247. /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-14.mdx +0 -0
@@ -0,0 +1,748 @@
1
+ # Example: with-mcp
2
+
3
+ ## app/app/api/chat/route.ts
4
+
5
+ ```typescript
6
+ import { openai } from "@ai-sdk/openai";
7
+ import { frontendTools } from "@assistant-ui/react-ai-sdk";
8
+ import { convertToModelMessages, streamText } from "ai";
9
+
10
+ export const maxDuration = 30;
11
+
12
+ export async function POST(req: Request) {
13
+ const { messages, system, tools } = await req.json();
14
+ const result = streamText({
15
+ model: openai("gpt-5.4-nano"),
16
+ messages: await convertToModelMessages(messages),
17
+ system,
18
+ tools: { ...frontendTools(tools) },
19
+ });
20
+ return result.toUIMessageStreamResponse();
21
+ }
22
+
23
+ ```
24
+
25
+ ## app/app/globals.css
26
+
27
+ ```css
28
+ @import "tailwindcss";
29
+ @import "tw-animate-css";
30
+
31
+ @source "../../../../packages/ui/src";
32
+
33
+ @custom-variant dark (&:is(.dark *));
34
+
35
+ @theme inline {
36
+ --radius-sm: calc(var(--radius) - 4px);
37
+ --radius-md: calc(var(--radius) - 2px);
38
+ --radius-lg: var(--radius);
39
+ --radius-xl: calc(var(--radius) + 4px);
40
+ --color-background: var(--background);
41
+ --color-foreground: var(--foreground);
42
+ --color-card: var(--card);
43
+ --color-card-foreground: var(--card-foreground);
44
+ --color-popover: var(--popover);
45
+ --color-popover-foreground: var(--popover-foreground);
46
+ --color-primary: var(--primary);
47
+ --color-primary-foreground: var(--primary-foreground);
48
+ --color-secondary: var(--secondary);
49
+ --color-secondary-foreground: var(--secondary-foreground);
50
+ --color-muted: var(--muted);
51
+ --color-muted-foreground: var(--muted-foreground);
52
+ --color-accent: var(--accent);
53
+ --color-accent-foreground: var(--accent-foreground);
54
+ --color-destructive: var(--destructive);
55
+ --color-border: var(--border);
56
+ --color-input: var(--input);
57
+ --color-ring: var(--ring);
58
+ --color-chart-1: var(--chart-1);
59
+ --color-chart-2: var(--chart-2);
60
+ --color-chart-3: var(--chart-3);
61
+ --color-chart-4: var(--chart-4);
62
+ --color-chart-5: var(--chart-5);
63
+ --color-sidebar: var(--sidebar);
64
+ --color-sidebar-foreground: var(--sidebar-foreground);
65
+ --color-sidebar-primary: var(--sidebar-primary);
66
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
67
+ --color-sidebar-accent: var(--sidebar-accent);
68
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
69
+ --color-sidebar-border: var(--sidebar-border);
70
+ --color-sidebar-ring: var(--sidebar-ring);
71
+ }
72
+
73
+ :root {
74
+ --radius: 0.625rem;
75
+ --background: oklch(1 0 0);
76
+ --foreground: oklch(0.141 0.005 285.823);
77
+ --card: oklch(1 0 0);
78
+ --card-foreground: oklch(0.141 0.005 285.823);
79
+ --popover: oklch(1 0 0);
80
+ --popover-foreground: oklch(0.141 0.005 285.823);
81
+ --primary: oklch(0.21 0.006 285.885);
82
+ --primary-foreground: oklch(0.985 0 0);
83
+ --secondary: oklch(0.967 0.001 286.375);
84
+ --secondary-foreground: oklch(0.21 0.006 285.885);
85
+ --muted: oklch(0.967 0.001 286.375);
86
+ --muted-foreground: oklch(0.552 0.016 285.938);
87
+ --accent: oklch(0.967 0.001 286.375);
88
+ --accent-foreground: oklch(0.21 0.006 285.885);
89
+ --destructive: oklch(0.577 0.245 27.325);
90
+ --border: oklch(0.92 0.004 286.32);
91
+ --input: oklch(0.92 0.004 286.32);
92
+ --ring: oklch(0.705 0.015 286.067);
93
+ --chart-1: oklch(0.646 0.222 41.116);
94
+ --chart-2: oklch(0.6 0.118 184.704);
95
+ --chart-3: oklch(0.398 0.07 227.392);
96
+ --chart-4: oklch(0.828 0.189 84.429);
97
+ --chart-5: oklch(0.769 0.188 70.08);
98
+ --sidebar: oklch(0.985 0 0);
99
+ --sidebar-foreground: oklch(0.141 0.005 285.823);
100
+ --sidebar-primary: oklch(0.21 0.006 285.885);
101
+ --sidebar-primary-foreground: oklch(0.985 0 0);
102
+ --sidebar-accent: oklch(0.967 0.001 286.375);
103
+ --sidebar-accent-foreground: oklch(0.21 0.006 285.885);
104
+ --sidebar-border: oklch(0.92 0.004 286.32);
105
+ --sidebar-ring: oklch(0.705 0.015 286.067);
106
+ }
107
+
108
+ .dark {
109
+ --background: oklch(0.141 0.005 285.823);
110
+ --foreground: oklch(0.985 0 0);
111
+ --card: oklch(0.21 0.006 285.885);
112
+ --card-foreground: oklch(0.985 0 0);
113
+ --popover: oklch(0.21 0.006 285.885);
114
+ --popover-foreground: oklch(0.985 0 0);
115
+ --primary: oklch(0.92 0.004 286.32);
116
+ --primary-foreground: oklch(0.21 0.006 285.885);
117
+ --secondary: oklch(0.274 0.006 286.033);
118
+ --secondary-foreground: oklch(0.985 0 0);
119
+ --muted: oklch(0.274 0.006 286.033);
120
+ --muted-foreground: oklch(0.705 0.015 286.067);
121
+ --accent: oklch(0.274 0.006 286.033);
122
+ --accent-foreground: oklch(0.985 0 0);
123
+ --destructive: oklch(0.704 0.191 22.216);
124
+ --border: oklch(1 0 0 / 10%);
125
+ --input: oklch(1 0 0 / 15%);
126
+ --ring: oklch(0.552 0.016 285.938);
127
+ --chart-1: oklch(0.488 0.243 264.376);
128
+ --chart-2: oklch(0.696 0.17 162.48);
129
+ --chart-3: oklch(0.769 0.188 70.08);
130
+ --chart-4: oklch(0.627 0.265 303.9);
131
+ --chart-5: oklch(0.645 0.246 16.439);
132
+ --sidebar: oklch(0.21 0.006 285.885);
133
+ --sidebar-foreground: oklch(0.985 0 0);
134
+ --sidebar-primary: oklch(0.488 0.243 264.376);
135
+ --sidebar-primary-foreground: oklch(0.985 0 0);
136
+ --sidebar-accent: oklch(0.274 0.006 286.033);
137
+ --sidebar-accent-foreground: oklch(0.985 0 0);
138
+ --sidebar-border: oklch(1 0 0 / 10%);
139
+ --sidebar-ring: oklch(0.552 0.016 285.938);
140
+ }
141
+
142
+ @layer base {
143
+ * {
144
+ @apply border-border outline-ring/50;
145
+ }
146
+ body {
147
+ @apply bg-background text-foreground;
148
+ }
149
+ }
150
+
151
+ ```
152
+
153
+ ## app/app/layout.tsx
154
+
155
+ ```tsx
156
+ import type { ReactNode } from "react";
157
+ import "./globals.css";
158
+
159
+ export const metadata = {
160
+ title: "react-mcp",
161
+ };
162
+
163
+ export default function RootLayout({ children }: { children: ReactNode }) {
164
+ return (
165
+ <html lang="en" className="h-full">
166
+ <body className="min-h-full bg-background text-foreground antialiased">
167
+ {children}
168
+ </body>
169
+ </html>
170
+ );
171
+ }
172
+
173
+ ```
174
+
175
+ ## app/app/mcp/callback/page.tsx
176
+
177
+ ```tsx
178
+ "use client";
179
+
180
+ import { useRouter } from "next/navigation";
181
+ import { McpOAuthCallback } from "@assistant-ui/react-mcp";
182
+ import { Providers } from "../../providers";
183
+
184
+ export default function CallbackPage() {
185
+ const router = useRouter();
186
+ return (
187
+ <Providers>
188
+ <h1>Completing OAuth…</h1>
189
+ <McpOAuthCallback
190
+ onComplete={() => router.replace("/")}
191
+ onError={(err) => {
192
+ console.error("OAuth callback failed:", err);
193
+ }}
194
+ >
195
+ {(result) => (
196
+ <pre>
197
+ {JSON.stringify(
198
+ {
199
+ status: result.status,
200
+ serverId: result.serverId,
201
+ error: result.error?.message ?? null,
202
+ },
203
+ null,
204
+ 2,
205
+ )}
206
+ </pre>
207
+ )}
208
+ </McpOAuthCallback>
209
+ </Providers>
210
+ );
211
+ }
212
+
213
+ ```
214
+
215
+ ## app/app/page.tsx
216
+
217
+ ```tsx
218
+ "use client";
219
+
220
+ import { Thread } from "@/components/assistant-ui/thread";
221
+ import { McpConfigDialog } from "@/components/assistant-ui/mcp-config";
222
+ import { Providers } from "./providers";
223
+
224
+ export default function Home() {
225
+ return (
226
+ <Providers>
227
+ <main className="grid h-dvh grid-rows-[auto_1fr]">
228
+ <header className="flex items-center justify-between gap-3 border-b px-4 py-3">
229
+ <div className="flex flex-col">
230
+ <h1 className="font-semibold text-base tracking-tight">
231
+ react-mcp
232
+ </h1>
233
+ <p className="text-muted-foreground text-xs">
234
+ Connect MCP servers, then chat — connected tools are exposed to
235
+ the model automatically.
236
+ </p>
237
+ </div>
238
+ <McpConfigDialog />
239
+ </header>
240
+ <Thread />
241
+ </main>
242
+ </Providers>
243
+ );
244
+ }
245
+
246
+ ```
247
+
248
+ ## app/app/providers.tsx
249
+
250
+ ```tsx
251
+ "use client";
252
+
253
+ import type { ReactNode } from "react";
254
+ import { AssistantRuntimeProvider, useAui } from "@assistant-ui/react";
255
+ import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
256
+ import { McpManagerResource, defineConnector } from "@assistant-ui/react-mcp";
257
+
258
+ const connectors = [
259
+ defineConnector({
260
+ id: "local-test",
261
+ name: "Local test MCP",
262
+ url: "http://localhost:8787/mcp",
263
+ auth: { type: "oauth", scopes: ["mcp"] },
264
+ }),
265
+ ];
266
+
267
+ export function Providers({ children }: { children: ReactNode }) {
268
+ const aui = useAui({ mcp: McpManagerResource({ connectors }) });
269
+ const runtime = useChatRuntime();
270
+ return (
271
+ <AssistantRuntimeProvider runtime={runtime} aui={aui}>
272
+ {children}
273
+ </AssistantRuntimeProvider>
274
+ );
275
+ }
276
+
277
+ ```
278
+
279
+ ## app/next.config.ts
280
+
281
+ ```typescript
282
+ import type { NextConfig } from "next";
283
+
284
+ const nextConfig: NextConfig = {
285
+ transpilePackages: [
286
+ "@assistant-ui/react-mcp",
287
+ "@assistant-ui/store",
288
+ "@assistant-ui/tap",
289
+ "@assistant-ui/ui",
290
+ ],
291
+ allowedDevOrigins: ["*"],
292
+ };
293
+
294
+ export default nextConfig;
295
+
296
+ ```
297
+
298
+ ## app/tsconfig.json
299
+
300
+ ```json
301
+ {
302
+ "extends": "@assistant-ui/x-buildutils/ts/next",
303
+ "compilerOptions": {
304
+ "typeRoots": [
305
+ "./node_modules/@types",
306
+ "../node_modules/@types",
307
+ "../../../node_modules/@types",
308
+ "../node_modules/@assistant-ui/x-buildutils/types"
309
+ ],
310
+ "paths": {
311
+ "@/*": ["./*"],
312
+ "@/components/assistant-ui/*": [
313
+ "../../../packages/ui/src/components/assistant-ui/*"
314
+ ],
315
+ "@/components/ui/*": ["../../../packages/ui/src/components/ui/*"],
316
+ "@/lib/utils": ["../../../packages/ui/src/lib/utils"],
317
+ "@assistant-ui/ui/*": ["../../../packages/ui/src/*"]
318
+ }
319
+ },
320
+ "include": [
321
+ "next-env.d.ts",
322
+ ".next/types/**/*.ts",
323
+ ".next/dev/types/**/*.ts",
324
+ "**/*.mts",
325
+ "**/*.ts",
326
+ "**/*.tsx"
327
+ ],
328
+ "exclude": ["node_modules"]
329
+ }
330
+
331
+ ```
332
+
333
+ ## components.json
334
+
335
+ ```json
336
+ {
337
+ "$schema": "https://ui.shadcn.com/schema.json",
338
+ "style": "new-york",
339
+ "rsc": true,
340
+ "tsx": true,
341
+ "tailwind": {
342
+ "config": "",
343
+ "css": "app/app/globals.css",
344
+ "baseColor": "zinc",
345
+ "cssVariables": true,
346
+ "prefix": ""
347
+ },
348
+ "aliases": {
349
+ "components": "@/components",
350
+ "utils": "@/lib/utils",
351
+ "ui": "@/components/ui",
352
+ "lib": "@/lib",
353
+ "hooks": "@/hooks"
354
+ },
355
+ "iconLibrary": "lucide",
356
+ "registries": {
357
+ "@assistant-ui": "https://r.assistant-ui.com/{name}.json"
358
+ }
359
+ }
360
+
361
+ ```
362
+
363
+ ## package.json
364
+
365
+ ```json
366
+ {
367
+ "name": "with-mcp",
368
+ "version": "0.0.0",
369
+ "private": true,
370
+ "type": "module",
371
+ "scripts": {
372
+ "dev": "concurrently -n server,app -c blue,magenta \"pnpm dev:server\" \"pnpm dev:app\"",
373
+ "dev:server": "tsx watch server/server.ts",
374
+ "dev:app": "next dev app --port 3010",
375
+ "build": "next build app",
376
+ "start:server": "tsx server/server.ts"
377
+ },
378
+ "dependencies": {
379
+ "@ai-sdk/openai": "^3.0.64",
380
+ "@assistant-ui/react": "workspace:*",
381
+ "@assistant-ui/react-ai-sdk": "workspace:*",
382
+ "@assistant-ui/react-markdown": "workspace:*",
383
+ "@assistant-ui/react-mcp": "workspace:*",
384
+ "@assistant-ui/store": "workspace:*",
385
+ "@assistant-ui/tap": "workspace:*",
386
+ "@assistant-ui/ui": "workspace:*",
387
+ "@modelcontextprotocol/sdk": "^1.29.0",
388
+ "ai": "^6.0.188",
389
+ "assistant-stream": "workspace:*",
390
+ "class-variance-authority": "^0.7.1",
391
+ "clsx": "^2.1.1",
392
+ "cors": "^2.8.6",
393
+ "express": "^5.2.1",
394
+ "lucide-react": "^1.16.0",
395
+ "next": "^16.2.6",
396
+ "react": "^19.2.6",
397
+ "react-dom": "^19.2.6",
398
+ "tailwind-merge": "^3.6.0",
399
+ "zod": "^4.4.3"
400
+ },
401
+ "devDependencies": {
402
+ "@assistant-ui/x-buildutils": "workspace:*",
403
+ "@tailwindcss/postcss": "^4.3.0",
404
+ "@types/cors": "^2.8.19",
405
+ "@types/express": "^5.0.6",
406
+ "@types/node": "^25.9.1",
407
+ "@types/react": "^19.2.15",
408
+ "@types/react-dom": "^19.2.3",
409
+ "concurrently": "^9.2.1",
410
+ "postcss": "^8.5.15",
411
+ "tailwindcss": "^4.3.0",
412
+ "tsx": "^4.22.3",
413
+ "tw-animate-css": "^1.4.0",
414
+ "typescript": "^6.0.3"
415
+ }
416
+ }
417
+
418
+ ```
419
+
420
+ ## README.md
421
+
422
+ ```markdown
423
+ # with-mcp
424
+
425
+ Minimal harness for `@assistant-ui/react-mcp`. Runs a local MCP server with
426
+ OAuth (PKCE + DCR) under `server/`, and a Next.js client under `app/` that
427
+ uses the package's primitives.
428
+
429
+ ## Run
430
+
431
+ ```sh
432
+ cd examples/with-mcp
433
+ pnpm dev
434
+ ```
435
+
436
+ This starts both the server (`http://localhost:8787`) and the Next.js app
437
+ (`http://localhost:3010`).
438
+
439
+ Open the app, click **Connect** on the "Local test MCP" connector, then
440
+ **Authorize ↗** to walk through the OAuth flow. After redirect the server
441
+ transitions to `connected` and the `echo` / `fingerprint` tools appear.
442
+
443
+ ## Notes
444
+
445
+ - The test server is in-memory: tokens, clients, and codes don't persist
446
+ across restarts.
447
+ - OAuth auto-approves (no consent screen). PKCE verification, DCR, and
448
+ refresh-token rotation still run end-to-end.
449
+ - This example is intentionally unstyled; primitives are unstyled. See
450
+ `app/app/McpUI.tsx` for raw composition.
451
+
452
+ ```
453
+
454
+ ## server/server.ts
455
+
456
+ ```typescript
457
+ /**
458
+ * Standalone test MCP server with OAuth.
459
+ *
460
+ * - OAuth 2.1 authorization server (PKCE + DCR) via @modelcontextprotocol/sdk auth router.
461
+ * - One MCP tool, `echo`, that returns its input.
462
+ * - All state in memory; for local development / E2E only.
463
+ *
464
+ * Run: `pnpm dev:server` (defaults to http://localhost:8787)
465
+ */
466
+ import express from "express";
467
+ import cors from "cors";
468
+ import { randomBytes, randomUUID, createHash } from "node:crypto";
469
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
470
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
471
+ import { mcpAuthRouter } from "@modelcontextprotocol/sdk/server/auth/router.js";
472
+ import { requireBearerAuth } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";
473
+ import type { OAuthServerProvider } from "@modelcontextprotocol/sdk/server/auth/provider.js";
474
+ import type { OAuthRegisteredClientsStore } from "@modelcontextprotocol/sdk/server/auth/clients.js";
475
+ import type {
476
+ OAuthClientInformationFull,
477
+ OAuthTokens,
478
+ } from "@modelcontextprotocol/sdk/shared/auth.js";
479
+ import type { AuthInfo } from "@modelcontextprotocol/sdk/server/auth/types.js";
480
+ import { z } from "zod";
481
+
482
+ const PORT = Number(process.env.PORT ?? 8787);
483
+ const ISSUER = process.env.ISSUER ?? `http://localhost:${PORT}`;
484
+
485
+ // ───────────────────────────────────────────────────────────────────────────
486
+ // In-memory OAuth provider
487
+ // ───────────────────────────────────────────────────────────────────────────
488
+
489
+ type AuthorizationGrant = {
490
+ clientId: string;
491
+ redirectUri: string;
492
+ codeChallenge: string;
493
+ scopes: string[];
494
+ state?: string;
495
+ };
496
+
497
+ const clients = new Map<string, OAuthClientInformationFull>();
498
+ const authCodes = new Map<string, AuthorizationGrant>();
499
+ const tokens = new Map<string, AuthInfo>();
500
+ const refreshTokens = new Map<string, { clientId: string; scopes: string[] }>();
501
+
502
+ const clientsStore: OAuthRegisteredClientsStore = {
503
+ async getClient(clientId) {
504
+ return clients.get(clientId);
505
+ },
506
+ async registerClient(client) {
507
+ const clientId = `client_${randomUUID()}`;
508
+ const full: OAuthClientInformationFull = {
509
+ ...client,
510
+ client_id: clientId,
511
+ client_id_issued_at: Math.floor(Date.now() / 1000),
512
+ };
513
+ clients.set(clientId, full);
514
+ return full;
515
+ },
516
+ };
517
+
518
+ const provider: OAuthServerProvider = {
519
+ get clientsStore() {
520
+ return clientsStore;
521
+ },
522
+
523
+ async authorize(client, params, res) {
524
+ // Auto-approve for the test server.
525
+ const code = randomBytes(24).toString("base64url");
526
+ authCodes.set(code, {
527
+ clientId: client.client_id,
528
+ redirectUri: params.redirectUri,
529
+ codeChallenge: params.codeChallenge,
530
+ scopes: params.scopes ?? [],
531
+ ...(params.state !== undefined ? { state: params.state } : {}),
532
+ });
533
+
534
+ const target = new URL(params.redirectUri);
535
+ target.searchParams.set("code", code);
536
+ if (params.state) target.searchParams.set("state", params.state);
537
+ res.redirect(target.toString());
538
+ },
539
+
540
+ async challengeForAuthorizationCode(_client, authorizationCode) {
541
+ const grant = authCodes.get(authorizationCode);
542
+ if (!grant) throw new Error("invalid authorization code");
543
+ return grant.codeChallenge;
544
+ },
545
+
546
+ async exchangeAuthorizationCode(
547
+ client,
548
+ authorizationCode,
549
+ ): Promise<OAuthTokens> {
550
+ const grant = authCodes.get(authorizationCode);
551
+ if (!grant) throw new Error("invalid authorization code");
552
+ if (grant.clientId !== client.client_id) {
553
+ throw new Error("authorization code/client mismatch");
554
+ }
555
+ authCodes.delete(authorizationCode);
556
+
557
+ const accessToken = randomBytes(32).toString("base64url");
558
+ const refreshToken = randomBytes(32).toString("base64url");
559
+ tokens.set(accessToken, {
560
+ token: accessToken,
561
+ clientId: client.client_id,
562
+ scopes: grant.scopes,
563
+ expiresAt: Math.floor(Date.now() / 1000) + 60 * 60,
564
+ });
565
+ refreshTokens.set(refreshToken, {
566
+ clientId: client.client_id,
567
+ scopes: grant.scopes,
568
+ });
569
+ return {
570
+ access_token: accessToken,
571
+ refresh_token: refreshToken,
572
+ token_type: "Bearer",
573
+ expires_in: 60 * 60,
574
+ scope: grant.scopes.join(" "),
575
+ };
576
+ },
577
+
578
+ async exchangeRefreshToken(
579
+ client,
580
+ refreshToken,
581
+ scopes,
582
+ ): Promise<OAuthTokens> {
583
+ const grant = refreshTokens.get(refreshToken);
584
+ if (!grant) throw new Error("invalid refresh token");
585
+ if (grant.clientId !== client.client_id) {
586
+ throw new Error("refresh token/client mismatch");
587
+ }
588
+ const newAccess = randomBytes(32).toString("base64url");
589
+ const newRefresh = randomBytes(32).toString("base64url");
590
+ const effectiveScopes = scopes ?? grant.scopes;
591
+ refreshTokens.delete(refreshToken);
592
+ tokens.set(newAccess, {
593
+ token: newAccess,
594
+ clientId: client.client_id,
595
+ scopes: effectiveScopes,
596
+ expiresAt: Math.floor(Date.now() / 1000) + 60 * 60,
597
+ });
598
+ refreshTokens.set(newRefresh, {
599
+ clientId: client.client_id,
600
+ scopes: effectiveScopes,
601
+ });
602
+ return {
603
+ access_token: newAccess,
604
+ refresh_token: newRefresh,
605
+ token_type: "Bearer",
606
+ expires_in: 60 * 60,
607
+ scope: effectiveScopes.join(" "),
608
+ };
609
+ },
610
+
611
+ async verifyAccessToken(token): Promise<AuthInfo> {
612
+ const info = tokens.get(token);
613
+ if (!info) throw new Error("invalid access token");
614
+ return info;
615
+ },
616
+ };
617
+
618
+ // ───────────────────────────────────────────────────────────────────────────
619
+ // MCP server
620
+ // ───────────────────────────────────────────────────────────────────────────
621
+
622
+ function buildMcpServer(): McpServer {
623
+ const server = new McpServer({ name: "aui-mcp-test", version: "0.0.1" });
624
+ server.tool(
625
+ "echo",
626
+ "Echo back the provided text.",
627
+ { text: z.string().describe("Text to echo back") },
628
+ async ({ text }) => ({
629
+ content: [{ type: "text" as const, text: `echo: ${text}` }],
630
+ }),
631
+ );
632
+ server.tool(
633
+ "fingerprint",
634
+ "Return a deterministic fingerprint of a string (sha256 hex).",
635
+ { input: z.string() },
636
+ async ({ input }) => ({
637
+ content: [
638
+ {
639
+ type: "text" as const,
640
+ text: createHash("sha256").update(input).digest("hex"),
641
+ },
642
+ ],
643
+ }),
644
+ );
645
+ return server;
646
+ }
647
+
648
+ // ───────────────────────────────────────────────────────────────────────────
649
+ // Express wiring
650
+ // ───────────────────────────────────────────────────────────────────────────
651
+
652
+ async function main() {
653
+ const app = express();
654
+
655
+ app.use(
656
+ cors({
657
+ origin: true,
658
+ credentials: false,
659
+ // Without these the browser won't expose MCP session/auth headers.
660
+ exposedHeaders: ["Mcp-Session-Id", "WWW-Authenticate"],
661
+ allowedHeaders: [
662
+ "Authorization",
663
+ "Content-Type",
664
+ "Mcp-Session-Id",
665
+ "Accept",
666
+ "mcp-protocol-version",
667
+ ],
668
+ }),
669
+ );
670
+
671
+ app.use(
672
+ mcpAuthRouter({
673
+ provider,
674
+ issuerUrl: new URL(ISSUER),
675
+ scopesSupported: ["mcp"],
676
+ resourceName: "aui-mcp-test",
677
+ }),
678
+ );
679
+
680
+ const bearer = requireBearerAuth({ verifier: provider });
681
+
682
+ app.post("/mcp", bearer, async (req, res) => {
683
+ try {
684
+ const transport = new StreamableHTTPServerTransport({
685
+ sessionIdGenerator: undefined,
686
+ });
687
+ res.on("close", () => transport.close());
688
+ const server = buildMcpServer();
689
+ await server.connect(transport);
690
+ await transport.handleRequest(req, res);
691
+ } catch (err) {
692
+ console.error("MCP request error:", err);
693
+ if (!res.headersSent) res.status(500).end();
694
+ }
695
+ });
696
+
697
+ app.get("/health", (_req, res) => res.json({ ok: true }));
698
+
699
+ app.listen(PORT, () => {
700
+ console.log(`MCP test server listening on ${ISSUER}`);
701
+ console.log(
702
+ ` - OAuth metadata: ${ISSUER}/.well-known/oauth-authorization-server`,
703
+ );
704
+ console.log(` - MCP endpoint: ${ISSUER}/mcp`);
705
+ });
706
+ }
707
+
708
+ main().catch((err) => {
709
+ console.error(err);
710
+ process.exit(1);
711
+ });
712
+
713
+ ```
714
+
715
+ ## tsconfig.json
716
+
717
+ ```json
718
+ {
719
+ "compilerOptions": {
720
+ "target": "ES2022",
721
+ "lib": ["dom", "dom.iterable", "esnext"],
722
+ "skipLibCheck": true,
723
+ "strict": true,
724
+ "noEmit": true,
725
+ "esModuleInterop": true,
726
+ "module": "esnext",
727
+ "moduleResolution": "bundler",
728
+ "resolveJsonModule": true,
729
+ "isolatedModules": true,
730
+ "jsx": "preserve",
731
+ "incremental": true,
732
+ "types": ["node"],
733
+ "paths": {
734
+ "@/*": ["./app/*"]
735
+ }
736
+ },
737
+ "include": [
738
+ "app/next-env.d.ts",
739
+ "app/**/*.ts",
740
+ "app/**/*.tsx",
741
+ "server/**/*.ts",
742
+ "app/.next/types/**/*.ts"
743
+ ],
744
+ "exclude": ["node_modules"]
745
+ }
746
+
747
+ ```
748
+