@assistant-ui/mcp-docs-server 0.1.38 → 0.2.0

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 (258) hide show
  1. package/.docs/organized/code-examples/waterfall.md +11 -12
  2. package/.docs/organized/code-examples/with-a2a.md +18 -13
  3. package/.docs/organized/code-examples/with-ag-ui.md +19 -14
  4. package/.docs/organized/code-examples/{with-ai-sdk-v6.md → with-ai-sdk-v7.md} +34 -23
  5. package/.docs/organized/code-examples/with-artifacts.md +473 -141
  6. package/.docs/organized/code-examples/with-assistant-transport.md +17 -10
  7. package/.docs/organized/code-examples/with-browser-extension.md +17 -10
  8. package/.docs/organized/code-examples/with-chain-of-thought.md +21 -14
  9. package/.docs/organized/code-examples/with-cloud-standalone.md +12 -11
  10. package/.docs/organized/code-examples/with-cloud.md +20 -15
  11. package/.docs/organized/code-examples/with-custom-thread-list.md +19 -12
  12. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +22 -15
  13. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +22 -15
  14. package/.docs/organized/code-examples/with-eve.md +18 -11
  15. package/.docs/organized/code-examples/with-expo.md +35 -52
  16. package/.docs/organized/code-examples/with-external-store.md +18 -13
  17. package/.docs/organized/code-examples/with-ffmpeg.md +20 -15
  18. package/.docs/organized/code-examples/with-generative-ui.md +22 -17
  19. package/.docs/organized/code-examples/with-google-adk.md +18 -11
  20. package/.docs/organized/code-examples/with-heat-graph.md +10 -11
  21. package/.docs/organized/code-examples/with-image-generation.md +19 -12
  22. package/.docs/organized/code-examples/with-interactables.md +21 -17
  23. package/.docs/organized/code-examples/with-langchain.md +19 -12
  24. package/.docs/organized/code-examples/with-langgraph.md +19 -12
  25. package/.docs/organized/code-examples/with-livekit.md +23 -16
  26. package/.docs/organized/code-examples/with-mcp.md +46 -28
  27. package/.docs/organized/code-examples/with-opencode.md +25 -23
  28. package/.docs/organized/code-examples/with-pi.md +54 -19
  29. package/.docs/organized/code-examples/with-react-hook-form.md +21 -16
  30. package/.docs/organized/code-examples/with-react-ink-web.md +9 -9
  31. package/.docs/organized/code-examples/with-react-ink.md +4 -4
  32. package/.docs/organized/code-examples/with-react-router.md +22 -17
  33. package/.docs/organized/code-examples/with-resumable-stream.md +21 -14
  34. package/.docs/organized/code-examples/with-store.md +10 -11
  35. package/.docs/organized/code-examples/with-tanstack.md +19 -13
  36. package/.docs/organized/code-examples/with-tap-runtime.md +18 -13
  37. package/.docs/organized/code-examples/with-virtualized-thread.md +19 -14
  38. package/.docs/raw/docs/(docs)/base-ui.mdx +39 -0
  39. package/.docs/raw/docs/(docs)/cli.mdx +19 -1
  40. package/.docs/raw/docs/(docs)/devtools.mdx +7 -2
  41. package/.docs/raw/docs/(docs)/installation.mdx +15 -1
  42. package/.docs/raw/docs/(docs)/rtl.mdx +2 -4
  43. package/.docs/raw/docs/(reference)/api-reference/generative-ui/a2ui.mdx +40 -0
  44. package/.docs/raw/docs/(reference)/api-reference/generative-ui/actions.mdx +56 -0
  45. package/.docs/raw/docs/(reference)/api-reference/generative-ui/components.mdx +86 -0
  46. package/.docs/raw/docs/(reference)/api-reference/generative-ui/index.mdx +22 -1
  47. package/.docs/raw/docs/(reference)/api-reference/generative-ui/json-generative-ui.mdx +42 -0
  48. package/.docs/raw/docs/(reference)/api-reference/generative-ui/rendering.mdx +53 -2
  49. package/.docs/raw/docs/(reference)/api-reference/generative-ui/slack.mdx +81 -0
  50. package/.docs/raw/docs/(reference)/api-reference/generative-ui/teams.mdx +86 -0
  51. package/.docs/raw/docs/(reference)/api-reference/generative-ui/tokens.mdx +62 -0
  52. package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +19 -420
  53. package/.docs/raw/docs/(reference)/api-reference/hooks/state.mdx +4 -1
  54. package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +4 -1
  55. package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +25 -2
  56. package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +37 -0
  57. package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +1 -9
  58. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +1 -0
  59. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +14 -31
  60. package/.docs/raw/docs/(reference)/api-reference/primitives/composition.mdx +1 -0
  61. package/.docs/raw/docs/(reference)/api-reference/primitives/index.mdx +3 -0
  62. package/.docs/raw/docs/(reference)/api-reference/primitives/selection-toolbar.mdx +2 -0
  63. package/.docs/raw/docs/(reference)/api-reference/tools/status.mdx +0 -2
  64. package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +12 -9
  65. package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +4 -0
  66. package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +7 -1
  67. package/.docs/raw/docs/cloud/langgraph.mdx +4 -2
  68. package/.docs/raw/docs/copilots/model-context.mdx +1 -1
  69. package/.docs/raw/docs/copilots/motivation.mdx +1 -1
  70. package/.docs/raw/docs/guides/attachments.mdx +3 -3
  71. package/.docs/raw/docs/guides/branching.mdx +2 -2
  72. package/.docs/raw/docs/guides/chatgpt-subscription.mdx +108 -0
  73. package/.docs/raw/docs/guides/context-api.mdx +89 -111
  74. package/.docs/raw/docs/guides/dictation.mdx +185 -257
  75. package/.docs/raw/docs/guides/editing.mdx +5 -5
  76. package/.docs/raw/docs/guides/electron.mdx +369 -0
  77. package/.docs/raw/docs/guides/index.mdx +20 -0
  78. package/.docs/raw/docs/guides/mentions.mdx +31 -3
  79. package/.docs/raw/docs/guides/quoting.mdx +3 -3
  80. package/.docs/raw/docs/guides/resumable-stream-deployment.mdx +2 -2
  81. package/.docs/raw/docs/guides/resumable-streams.mdx +12 -1
  82. package/.docs/raw/docs/guides/speech.mdx +47 -29
  83. package/.docs/raw/docs/guides/suggestions.mdx +70 -1
  84. package/.docs/raw/docs/guides/voice.mdx +197 -267
  85. package/.docs/raw/docs/ink/hooks.mdx +3 -3
  86. package/.docs/raw/docs/ink/primitives.mdx +49 -8
  87. package/.docs/raw/docs/integrations/auth/better-auth.mdx +2 -2
  88. package/.docs/raw/docs/integrations/auth/clerk.mdx +2 -2
  89. package/.docs/raw/docs/integrations/auth/next-auth.mdx +3 -3
  90. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +10 -4
  91. package/.docs/raw/docs/integrations/frameworks/cloudflare-agents/overview.mdx +3 -3
  92. package/.docs/raw/docs/integrations/frameworks/mastra/full-stack.mdx +1 -1
  93. package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +3 -3
  94. package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +1 -1
  95. package/.docs/raw/docs/integrations/gateways/index.mdx +2 -2
  96. package/.docs/raw/docs/integrations/observability/helicone.mdx +1 -1
  97. package/.docs/raw/docs/integrations/observability/langfuse.mdx +1 -1
  98. package/.docs/raw/docs/integrations/observability/langsmith.mdx +2 -2
  99. package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +36 -9
  100. package/.docs/raw/docs/migrations/index.mdx +50 -0
  101. package/.docs/raw/docs/migrations/toolkit-tools.mdx +4 -2
  102. package/.docs/raw/docs/migrations/v0-15.mdx +156 -0
  103. package/.docs/raw/docs/primitives/chain-of-thought.mdx +6 -1
  104. package/.docs/raw/docs/primitives/composer.mdx +17 -1
  105. package/.docs/raw/docs/primitives/selection-toolbar.mdx +25 -0
  106. package/.docs/raw/docs/primitives/thread-list.mdx +2 -2
  107. package/.docs/raw/docs/react-native/hooks.mdx +3 -3
  108. package/.docs/raw/docs/react-native/index.mdx +2 -2
  109. package/.docs/raw/docs/react-native/primitives.mdx +62 -5
  110. package/.docs/raw/docs/runtimes/ag-ui/agent-state.mdx +124 -0
  111. package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +10 -1
  112. package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +14 -5
  113. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +15 -15
  114. package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +8 -8
  115. package/.docs/raw/docs/runtimes/ai-sdk/{v6.mdx → v6-legacy.mdx} +11 -9
  116. package/.docs/raw/docs/runtimes/ai-sdk/v7.mdx +717 -0
  117. package/.docs/raw/docs/runtimes/concepts/adapters.mdx +1 -1
  118. package/.docs/raw/docs/runtimes/concepts/architecture.mdx +1 -1
  119. package/.docs/raw/docs/runtimes/concepts/threads.mdx +10 -10
  120. package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +2 -2
  121. package/.docs/raw/docs/runtimes/custom/data-stream.mdx +10 -19
  122. package/.docs/raw/docs/runtimes/custom/external-store.mdx +2 -2
  123. package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +5 -3
  124. package/.docs/raw/docs/runtimes/eve/overview.mdx +1 -1
  125. package/.docs/raw/docs/runtimes/langchain.mdx +2 -2
  126. package/.docs/raw/docs/runtimes/langgraph/agent-state.mdx +181 -0
  127. package/.docs/raw/docs/runtimes/langgraph/overview.mdx +1 -1
  128. package/.docs/raw/docs/runtimes/opencode/hooks.mdx +3 -1
  129. package/.docs/raw/docs/tools/a2ui.mdx +107 -0
  130. package/.docs/raw/docs/tools/backend.mdx +6 -3
  131. package/.docs/raw/docs/tools/defining-tools.mdx +7 -1
  132. package/.docs/raw/docs/tools/generative-ui.mdx +60 -2
  133. package/.docs/raw/docs/tools/interactables-legacy.mdx +4 -4
  134. package/.docs/raw/docs/tools/interactables.mdx +3 -3
  135. package/.docs/raw/docs/tools/mcp-apps.mdx +90 -13
  136. package/.docs/raw/docs/tools/mcp.mdx +100 -3
  137. package/.docs/raw/docs/tools/tool-ui.mdx +6 -4
  138. package/.docs/raw/docs/tools/user-managed-mcp.mdx +77 -9
  139. package/.docs/raw/docs/ui/accordion.mdx +16 -10
  140. package/.docs/raw/docs/ui/assistant-modal.mdx +8 -4
  141. package/.docs/raw/docs/ui/attachment.mdx +5 -1
  142. package/.docs/raw/docs/ui/badge.mdx +23 -12
  143. package/.docs/raw/docs/ui/follow-up-suggestions.mdx +4 -2
  144. package/.docs/raw/docs/ui/model-selector.mdx +33 -3
  145. package/.docs/raw/docs/ui/part-grouping.mdx +0 -4
  146. package/.docs/raw/docs/ui/reasoning.mdx +1 -1
  147. package/.docs/raw/docs/ui/select.mdx +22 -14
  148. package/.docs/raw/docs/ui/sources.mdx +1 -1
  149. package/.docs/raw/docs/ui/tabs.mdx +25 -14
  150. package/.docs/raw/docs/utilities/heat-graph.mdx +2 -2
  151. package/dist/constants.d.ts.map +1 -1
  152. package/dist/index.d.ts +1 -2
  153. package/dist/index.d.ts.map +1 -1
  154. package/dist/index.js +41 -2
  155. package/dist/index.js.map +1 -1
  156. package/dist/prepare-docs/code-examples.d.ts.map +1 -1
  157. package/dist/prepare-docs/code-examples.js.map +1 -1
  158. package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
  159. package/dist/prepare-docs/prepare.d.ts +1 -1
  160. package/dist/prompts/xulux-playground.d.ts +12 -0
  161. package/dist/prompts/xulux-playground.d.ts.map +1 -0
  162. package/dist/prompts/xulux-playground.js +33 -0
  163. package/dist/prompts/xulux-playground.js.map +1 -0
  164. package/dist/stdio.d.ts +1 -1
  165. package/dist/tools/docs.d.ts +8 -14
  166. package/dist/tools/docs.d.ts.map +1 -1
  167. package/dist/tools/docs.js +26 -10
  168. package/dist/tools/docs.js.map +1 -1
  169. package/dist/tools/examples.d.ts +6 -12
  170. package/dist/tools/examples.d.ts.map +1 -1
  171. package/dist/tools/examples.js +11 -8
  172. package/dist/tools/examples.js.map +1 -1
  173. package/dist/tools/resources.d.ts +1 -2
  174. package/dist/tools/resources.d.ts.map +1 -1
  175. package/dist/tools/resources.js +1 -1
  176. package/dist/tools/resources.js.map +1 -1
  177. package/dist/tools/search.d.ts +6 -15
  178. package/dist/tools/search.d.ts.map +1 -1
  179. package/dist/tools/search.js +2 -2
  180. package/dist/tools/search.js.map +1 -1
  181. package/dist/tools/tests/mcp-test-client.d.ts +15 -0
  182. package/dist/tools/tests/mcp-test-client.d.ts.map +1 -0
  183. package/dist/tools/tests/mcp-test-client.js +68 -0
  184. package/dist/tools/tests/mcp-test-client.js.map +1 -0
  185. package/dist/tools/tests/test-setup.d.ts.map +1 -1
  186. package/dist/tools/tests/test-setup.js +5 -1
  187. package/dist/tools/tests/test-setup.js.map +1 -1
  188. package/dist/tools/xulux-templates.d.ts +58 -0
  189. package/dist/tools/xulux-templates.d.ts.map +1 -0
  190. package/dist/tools/xulux-templates.js +82 -0
  191. package/dist/tools/xulux-templates.js.map +1 -0
  192. package/dist/utils/cache.d.ts +5 -0
  193. package/dist/utils/cache.d.ts.map +1 -0
  194. package/dist/utils/cache.js +18 -0
  195. package/dist/utils/cache.js.map +1 -0
  196. package/dist/utils/logger.d.ts.map +1 -1
  197. package/dist/utils/mcp-format.d.ts +1 -0
  198. package/dist/utils/mcp-format.d.ts.map +1 -1
  199. package/dist/utils/mcp-format.js +7 -4
  200. package/dist/utils/mcp-format.js.map +1 -1
  201. package/dist/utils/mdx.d.ts.map +1 -1
  202. package/dist/utils/paths.d.ts +1 -1
  203. package/dist/utils/paths.d.ts.map +1 -1
  204. package/dist/utils/paths.js +3 -1
  205. package/dist/utils/paths.js.map +1 -1
  206. package/dist/utils/search.d.ts.map +1 -1
  207. package/dist/utils/security.d.ts.map +1 -1
  208. package/dist/utils/security.js.map +1 -1
  209. package/dist/xulux/catalog-client.d.ts +14 -0
  210. package/dist/xulux/catalog-client.d.ts.map +1 -0
  211. package/dist/xulux/catalog-client.js +67 -0
  212. package/dist/xulux/catalog-client.js.map +1 -0
  213. package/dist/xulux/fallback-catalog.d.ts +7 -0
  214. package/dist/xulux/fallback-catalog.d.ts.map +1 -0
  215. package/dist/xulux/fallback-catalog.js +47 -0
  216. package/dist/xulux/fallback-catalog.js.map +1 -0
  217. package/dist/xulux/fetch-sandbox.d.ts +5 -0
  218. package/dist/xulux/fetch-sandbox.d.ts.map +1 -0
  219. package/dist/xulux/fetch-sandbox.js +40 -0
  220. package/dist/xulux/fetch-sandbox.js.map +1 -0
  221. package/dist/xulux/template-service.d.ts +84 -0
  222. package/dist/xulux/template-service.d.ts.map +1 -0
  223. package/dist/xulux/template-service.js +223 -0
  224. package/dist/xulux/template-service.js.map +1 -0
  225. package/dist/xulux/types.d.ts +55 -0
  226. package/dist/xulux/types.d.ts.map +1 -0
  227. package/dist/xulux/types.js +6 -0
  228. package/dist/xulux/types.js.map +1 -0
  229. package/package.json +7 -6
  230. package/src/index.ts +55 -2
  231. package/src/prompts/xulux-playground.ts +36 -0
  232. package/src/tools/docs.ts +27 -5
  233. package/src/tools/examples.ts +17 -12
  234. package/src/tools/resources.ts +1 -4
  235. package/src/tools/search.ts +2 -2
  236. package/src/tools/tests/completions.test.ts +40 -26
  237. package/src/tools/tests/docs.test.ts +20 -0
  238. package/src/tools/tests/examples.test.ts +5 -5
  239. package/src/tools/tests/integration.test.ts +3 -4
  240. package/src/tools/tests/listings-cache.test.ts +19 -0
  241. package/src/tools/tests/mcp-protocol.test.ts +173 -108
  242. package/src/tools/tests/mcp-test-client.ts +111 -0
  243. package/src/tools/tests/resources.test.ts +97 -66
  244. package/src/tools/tests/test-setup.ts +8 -0
  245. package/src/tools/tests/xulux-templates.test.ts +262 -0
  246. package/src/tools/xulux-templates.ts +141 -0
  247. package/src/utils/cache.ts +20 -0
  248. package/src/utils/mcp-format.ts +8 -6
  249. package/src/utils/paths.ts +4 -1
  250. package/src/utils/tests/cache.test.ts +51 -0
  251. package/src/utils/tests/mcp-format.test.ts +22 -0
  252. package/src/utils/tests/security.test.ts +1 -1
  253. package/src/xulux/catalog-client.ts +105 -0
  254. package/src/xulux/fallback-catalog.ts +63 -0
  255. package/src/xulux/fetch-sandbox.ts +56 -0
  256. package/src/xulux/template-service.ts +406 -0
  257. package/src/xulux/types.ts +60 -0
  258. package/.docs/raw/docs/(reference)/api-reference/hooks/utilities.mdx +0 -464
package/src/tools/docs.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { z } from "zod/v3";
1
+ import { z } from "zod";
2
2
  import { stat, lstat } from "node:fs/promises";
3
3
  import { join, extname } from "node:path";
4
4
  import {
@@ -34,6 +34,9 @@ interface DocResult {
34
34
  content?: string;
35
35
  files?: string[];
36
36
  directories?: string[];
37
+ summaries?: Array<{ name: string; title?: string; excerpt?: string }>;
38
+ title?: string;
39
+ excerpt?: string;
37
40
  suggestions?: string[];
38
41
  hint?: string;
39
42
  error?: string;
@@ -85,6 +88,11 @@ async function readDocumentation(docPath: string): Promise<DocResult> {
85
88
  const { directories, files } = await listDirContents(fullPath);
86
89
 
87
90
  const contents: Record<string, string> = {};
91
+ const summaries: Array<{
92
+ name: string;
93
+ title?: string;
94
+ excerpt?: string;
95
+ }> = [];
88
96
  let aggregateSize = 0;
89
97
  let truncated = false;
90
98
  for (const file of files) {
@@ -105,8 +113,16 @@ async function readDocumentation(docPath: string): Promise<DocResult> {
105
113
  }
106
114
  const mdxContent = await readMDXFile(join(fullPath, file));
107
115
  if (mdxContent) {
108
- contents[file.replace(MDX_EXTENSION, "")] =
109
- formatMDXContent(mdxContent);
116
+ const name = file.replace(MDX_EXTENSION, "");
117
+ contents[name] = formatMDXContent(mdxContent);
118
+ const title = mdxContent.frontmatter["title"];
119
+ summaries.push({
120
+ name,
121
+ ...(typeof title === "string" && { title }),
122
+ ...(mdxContent.excerpt !== undefined && {
123
+ excerpt: mdxContent.excerpt,
124
+ }),
125
+ });
110
126
  }
111
127
  }
112
128
 
@@ -120,9 +136,10 @@ async function readDocumentation(docPath: string): Promise<DocResult> {
120
136
  type: "directory",
121
137
  directories,
122
138
  files: files.map((f) => f.replace(MDX_EXTENSION, "")),
139
+ ...(summaries.length > 0 && { summaries }),
123
140
  ...(content !== undefined && { content }),
124
141
  ...(truncated && {
125
- hint: `Directory content exceeds ${MAX_DIRECTORY_CONTENT_SIZE} bytes and was omitted; request individual files by path to retrieve their content.`,
142
+ hint: `Directory content exceeds ${MAX_DIRECTORY_CONTENT_SIZE} bytes and was omitted; summaries cover only the files read before the limit. Request individual files by path to retrieve their content.`,
126
143
  }),
127
144
  };
128
145
  }
@@ -158,11 +175,16 @@ async function readDocumentation(docPath: string): Promise<DocResult> {
158
175
  const mdxContent = await readMDXFile(mdxPath);
159
176
 
160
177
  if (mdxContent) {
178
+ const title = mdxContent.frontmatter["title"];
161
179
  return {
162
180
  path: docPath,
163
181
  found: true,
164
182
  type: "file",
165
183
  content: formatMDXContent(mdxContent),
184
+ ...(typeof title === "string" && { title }),
185
+ ...(mdxContent.excerpt !== undefined && {
186
+ excerpt: mdxContent.excerpt,
187
+ }),
166
188
  };
167
189
  }
168
190
  }
@@ -191,7 +213,7 @@ export const docsTools = {
191
213
  name: "assistantUIDocs",
192
214
  description:
193
215
  'Retrieve assistant-ui documentation by path. Use "/" to list all sections. Supports multiple paths in a single request.',
194
- parameters: docsInputSchema.shape,
216
+ parameters: docsInputSchema,
195
217
  execute: async ({ paths }: z.infer<typeof docsInputSchema>) => {
196
218
  logger.info(`Retrieving documentation for paths: ${paths.join(", ")}`);
197
219
 
@@ -1,7 +1,8 @@
1
- import { z } from "zod/v3";
1
+ import { z } from "zod";
2
2
  import { readFile, readdir, lstat } from "node:fs/promises";
3
3
  import { join, extname } from "node:path";
4
4
  import { CODE_EXAMPLES_PATH, MAX_FILE_SIZE } from "../constants.js";
5
+ import { cacheListing } from "../utils/cache.js";
5
6
  import { logger } from "../utils/logger.js";
6
7
  import { formatMCPResponse } from "../utils/mcp-format.js";
7
8
  import { sanitizePath } from "../utils/security.js";
@@ -11,21 +12,25 @@ const examplesInputSchema = z.object({
11
12
  .string()
12
13
  .optional()
13
14
  .describe(
14
- 'Example name (e.g., "with-ai-sdk-v6"). Leave empty to list all examples.',
15
+ 'Example name (e.g., "with-ai-sdk-v7"). Leave empty to list all examples.',
15
16
  ),
16
17
  });
17
18
 
18
- export async function listCodeExamples(): Promise<string[]> {
19
- try {
20
- const files = await readdir(CODE_EXAMPLES_PATH);
21
- return files
22
- .filter((file) => extname(file) === ".md")
23
- .map((file) => file.replace(".md", ""))
24
- .sort();
25
- } catch (error) {
19
+ const loadCodeExamples = cacheListing(scanCodeExamples);
20
+
21
+ export function listCodeExamples(): Promise<string[]> {
22
+ return loadCodeExamples().catch((error) => {
26
23
  logger.error("Failed to list code examples", error);
27
24
  return [];
28
- }
25
+ });
26
+ }
27
+
28
+ async function scanCodeExamples(): Promise<string[]> {
29
+ const files = await readdir(CODE_EXAMPLES_PATH);
30
+ return files
31
+ .filter((file) => extname(file) === ".md")
32
+ .map((file) => file.replace(".md", ""))
33
+ .sort();
29
34
  }
30
35
 
31
36
  export async function readCodeExample(
@@ -58,7 +63,7 @@ export const examplesTools = {
58
63
  name: "assistantUIExamples",
59
64
  description:
60
65
  "List available examples or retrieve complete code for a specific example",
61
- parameters: examplesInputSchema.shape,
66
+ parameters: examplesInputSchema,
62
67
  execute: async ({ example }: z.infer<typeof examplesInputSchema>) => {
63
68
  try {
64
69
  if (!example) {
@@ -1,7 +1,4 @@
1
- import {
2
- McpServer,
3
- ResourceTemplate,
4
- } from "@modelcontextprotocol/sdk/server/mcp.js";
1
+ import { type McpServer, ResourceTemplate } from "@modelcontextprotocol/server";
5
2
  import { join } from "node:path";
6
3
  import { DOCS_PATH, MDX_EXTENSION } from "../constants.js";
7
4
  import { getAvailableDocFiles } from "../utils/paths.js";
@@ -1,4 +1,4 @@
1
- import { z } from "zod/v3";
1
+ import { z } from "zod";
2
2
  import { logger } from "../utils/logger.js";
3
3
  import { formatMCPResponse } from "../utils/mcp-format.js";
4
4
  import { searchDocs } from "../utils/search.js";
@@ -21,7 +21,7 @@ export const searchTools = {
21
21
  name: "assistantUISearch",
22
22
  description:
23
23
  "Search assistant-ui documentation by keyword. Returns ranked matches with their doc path, title, and a snippet. Fetch full content with assistantUIDocs using a returned path.",
24
- parameters: searchInputSchema.shape,
24
+ parameters: searchInputSchema,
25
25
  execute: async ({ query, limit }: z.infer<typeof searchInputSchema>) => {
26
26
  logger.info(`Searching documentation for: ${query}`);
27
27
  try {
@@ -1,46 +1,60 @@
1
- import { describe, it, expect } from "vitest";
1
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
2
2
  import { server } from "../../index.js";
3
+ import { createMcpTestClient, type McpTestClient } from "./mcp-test-client.js";
3
4
 
4
- function handler(method: string) {
5
- const handlers = (server as any).server._requestHandlers;
6
- const h = handlers.get(method);
7
- if (!h) throw new Error(`No handler for ${method}`);
8
- return h;
9
- }
5
+ type CompletionResult = {
6
+ completion: {
7
+ values: string[];
8
+ };
9
+ };
10
10
 
11
- async function complete(uri: string, name: string, value: string) {
12
- return handler("completion/complete")(
13
- {
11
+ describe("resource argument completions", () => {
12
+ let client: McpTestClient;
13
+
14
+ beforeEach(async () => {
15
+ client = await createMcpTestClient(server);
16
+ await client.initialize();
17
+ });
18
+
19
+ afterEach(async () => {
20
+ await client?.close();
21
+ });
22
+
23
+ async function complete(uri: string, name: string, value: string) {
24
+ return client.request<CompletionResult>({
14
25
  method: "completion/complete",
15
- params: { ref: { type: "ref/resource", uri }, argument: { name, value } },
16
- },
17
- {},
18
- );
19
- }
26
+ params: {
27
+ ref: { type: "ref/resource", uri },
28
+ argument: { name, value },
29
+ },
30
+ });
31
+ }
20
32
 
21
- describe("resource argument completions", () => {
22
33
  it("suggests doc paths matching the partial value", async () => {
23
- const res = await complete("aui-docs:///{+path}", "path", "api");
24
- expect(res.completion.values.length).toBeGreaterThan(0);
34
+ const result = await complete("aui-docs:///{+path}", "path", "api");
35
+
36
+ expect(result.completion.values.length).toBeGreaterThan(0);
25
37
  expect(
26
- res.completion.values.every((v: string) =>
27
- v.toLowerCase().includes("api"),
38
+ result.completion.values.every((value) =>
39
+ value.toLowerCase().includes("api"),
28
40
  ),
29
41
  ).toBe(true);
30
42
  });
31
43
 
32
44
  it("suggests example names matching the partial value", async () => {
33
- const res = await complete("aui-example:///{+name}", "name", "with");
34
- expect(res.completion.values.length).toBeGreaterThan(0);
45
+ const result = await complete("aui-example:///{+name}", "name", "with");
46
+
47
+ expect(result.completion.values.length).toBeGreaterThan(0);
35
48
  expect(
36
- res.completion.values.every((v: string) =>
37
- v.toLowerCase().includes("with"),
49
+ result.completion.values.every((value) =>
50
+ value.toLowerCase().includes("with"),
38
51
  ),
39
52
  ).toBe(true);
40
53
  });
41
54
 
42
55
  it("returns no values for a nonsense partial", async () => {
43
- const res = await complete("aui-docs:///{+path}", "path", "zzzqqxnope");
44
- expect(res.completion.values).toHaveLength(0);
56
+ const result = await complete("aui-docs:///{+path}", "path", "zzzqqxnope");
57
+
58
+ expect(result.completion.values).toHaveLength(0);
45
59
  });
46
60
  });
@@ -91,6 +91,26 @@ describe("assistantUIDocs", () => {
91
91
  expect(result.content).toContain("assistant-ui");
92
92
  });
93
93
 
94
+ it("includes title and excerpt on a file response", async () => {
95
+ const result = await testContext.callTool("assistantUIDocs", {
96
+ paths: ["(docs)/index"],
97
+ });
98
+ expect(result.type).toBe("file");
99
+ expect(result.title ?? result.excerpt).toBeDefined();
100
+ });
101
+
102
+ it("includes per-file summaries on a directory listing", async () => {
103
+ const result = await testContext.callTool("assistantUIDocs", {
104
+ paths: ["(reference)/api-reference/primitives"],
105
+ });
106
+ expect(result.type).toBe("directory");
107
+ expect(Array.isArray(result.summaries)).toBe(true);
108
+ expect(result.summaries.length).toBeGreaterThan(0);
109
+ const summary = result.summaries[0];
110
+ expect(summary.name).toBeDefined();
111
+ expect(summary.title ?? summary.excerpt).toBeDefined();
112
+ });
113
+
94
114
  it("should skip symlinks and large files", async () => {
95
115
  const mockedLstat = vi.mocked(fs.lstat);
96
116
 
@@ -19,20 +19,20 @@ describe("assistantUIExamples", () => {
19
19
  expect(result.examples).toBeDefined();
20
20
  expect(Array.isArray(result.examples)).toBe(true);
21
21
  expect(result.examples.length).toBeGreaterThan(0);
22
- expect(result.examples).toContain("with-ai-sdk-v6");
22
+ expect(result.examples).toContain("with-ai-sdk-v7");
23
23
  expect(result.examples).toContain("with-langgraph");
24
24
  expect(result.total).toBe(result.examples.length);
25
25
  });
26
26
 
27
27
  it("should retrieve specific example code", async () => {
28
28
  const result = await testContext.callTool("assistantUIExamples", {
29
- example: "with-ai-sdk-v6",
29
+ example: "with-ai-sdk-v7",
30
30
  });
31
31
 
32
32
  expect(result.type).toBe("example");
33
- expect(result.name).toBe("with-ai-sdk-v6");
33
+ expect(result.name).toBe("with-ai-sdk-v7");
34
34
  expect(result.content).toBeDefined();
35
- expect(result.content).toContain("# Example: with-ai-sdk-v6");
35
+ expect(result.content).toContain("# Example: with-ai-sdk-v7");
36
36
  expect(result.content).toContain("app/api/chat/route.ts");
37
37
  expect(result.content).toContain("streamText");
38
38
  });
@@ -50,7 +50,7 @@ describe("assistantUIExamples", () => {
50
50
 
51
51
  it("should include all files in example", async () => {
52
52
  const result = await testContext.callTool("assistantUIExamples", {
53
- example: "with-ai-sdk-v6",
53
+ example: "with-ai-sdk-v7",
54
54
  });
55
55
 
56
56
  expect(result.content).toContain("package.json");
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
  import { server } from "../../index.js";
3
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { McpServer } from "@modelcontextprotocol/server";
4
4
  import { docsTools } from "../docs.js";
5
5
  import { examplesTools } from "../examples.js";
6
6
 
@@ -24,12 +24,11 @@ describe("MCP Server Integration", () => {
24
24
  });
25
25
 
26
26
  it("should have valid input schemas", () => {
27
- // docsTools.parameters is the Zod schema shape
28
27
  expect(docsTools.parameters).toBeDefined();
29
- expect(Object.keys(docsTools.parameters)).toContain("paths");
28
+ expect(docsTools.parameters.shape.paths).toBeDefined();
30
29
 
31
30
  expect(examplesTools.parameters).toBeDefined();
32
- expect(Object.keys(examplesTools.parameters)).toContain("example");
31
+ expect(examplesTools.parameters.shape.example).toBeDefined();
33
32
  });
34
33
 
35
34
  it("should execute tools successfully", async () => {
@@ -0,0 +1,19 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { getAvailableDocFiles } from "../../utils/paths.js";
3
+ import { listCodeExamples } from "../examples.js";
4
+
5
+ describe("listing caches", () => {
6
+ it("caches the doc file listing (same instance on repeat calls)", async () => {
7
+ const first = await getAvailableDocFiles();
8
+ const second = await getAvailableDocFiles();
9
+ expect(second).toBe(first);
10
+ expect(first.length).toBeGreaterThan(0);
11
+ });
12
+
13
+ it("caches the example listing (same instance on repeat calls)", async () => {
14
+ const first = await listCodeExamples();
15
+ const second = await listCodeExamples();
16
+ expect(second).toBe(first);
17
+ expect(first.length).toBeGreaterThan(0);
18
+ });
19
+ });