@thallylabs/mcp 0.7.4 → 0.8.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.
package/dist/index.js CHANGED
@@ -18,18 +18,21 @@ import { Readable, pipeline } from "stream";
18
18
  import { promisify } from "util";
19
19
  import tar from "tar";
20
20
  var pipelineAsync = promisify(pipeline);
21
- var TARBALL_URL = "https://codeload.github.com/thallylabs/thally/tar.gz/main";
22
- var EXCLUDE_PATHS = [
21
+ var MCP_TEMPLATE_REPOSITORY = "thallylabs/docs";
22
+ var TARBALL_URL = `https://codeload.github.com/${MCP_TEMPLATE_REPOSITORY}/tar.gz/main`;
23
+ var MCP_EXCLUDE_PATHS = [
23
24
  "/cli/",
24
25
  "/packages/",
25
26
  "/node_modules/",
26
27
  "/.git/",
27
- "/thally-agent.yml",
28
28
  "/thally-track.yml",
29
29
  "/CODEOWNERS",
30
30
  "/CLAUDE.md",
31
31
  "/notes/"
32
32
  ];
33
+ function shouldIncludeMcpTemplatePath(path) {
34
+ return !MCP_EXCLUDE_PATHS.some((excluded) => path.includes(excluded));
35
+ }
33
36
  var STARTER_PAGES = {
34
37
  "introduction.mdx": `---
35
38
  title: Introduction
@@ -115,12 +118,7 @@ async function downloadTemplate(targetDir) {
115
118
  tar.extract({
116
119
  cwd: targetDir,
117
120
  strip: 1,
118
- filter: (path) => {
119
- for (const excluded of EXCLUDE_PATHS) {
120
- if (path.includes(excluded)) return false;
121
- }
122
- return true;
123
- }
121
+ filter: shouldIncludeMcpTemplatePath
124
122
  })
125
123
  );
126
124
  }
@@ -331,6 +329,34 @@ function writeDocsJson(projectDir, config) {
331
329
  writeFileSync2(docsPath, JSON.stringify(config, null, 2) + "\n", "utf8");
332
330
  }
333
331
 
332
+ // src/lib/page-echo.ts
333
+ var BODY_DELIMITER = "--- MDX body ---";
334
+ function readPageBodyDelimiter() {
335
+ return BODY_DELIMITER;
336
+ }
337
+ function stripEchoedPageHeader(content, pageId) {
338
+ const lines = content.split("\n");
339
+ const delimiterIndex = lines.findIndex((line) => line.trim() === BODY_DELIMITER);
340
+ if (delimiterIndex !== -1 && delimiterIndex <= 6) {
341
+ return lines.slice(delimiterIndex + 1).join("\n").replace(/^\n+/, "");
342
+ }
343
+ const first = lines[0]?.trim() ?? "";
344
+ const second = lines[1]?.trim() ?? "";
345
+ if (first.startsWith("# ") && second === `*${pageId}*`) {
346
+ let index = 2;
347
+ while (index < lines.length && lines[index].trim() === "") index += 1;
348
+ if (lines[index]?.trim().startsWith("> ")) {
349
+ index += 1;
350
+ while (index < lines.length && lines[index].trim() === "") index += 1;
351
+ }
352
+ if (lines[index]?.trim() === "---") {
353
+ index += 1;
354
+ }
355
+ return lines.slice(index).join("\n").replace(/^\n+/, "");
356
+ }
357
+ return content;
358
+ }
359
+
334
360
  // src/tools/add-page.ts
335
361
  var addPageSchema = z2.object({
336
362
  projectDir: z2.string().describe("Path to the Thally project root"),
@@ -361,7 +387,7 @@ async function handleAddPage(input) {
361
387
  if (description) {
362
388
  frontmatterLines.push(`description: ${description}`);
363
389
  }
364
- const bodyContent = content ?? `## ${title}
390
+ const bodyContent = content ? stripEchoedPageHeader(content, pageId) : `## ${title}
365
391
 
366
392
  Add your content here.`;
367
393
  const mdxContent = `---
@@ -522,7 +548,7 @@ async function handleUpdatePage(input) {
522
548
  if (input.mergeFrontmatter) {
523
549
  Object.assign(newFm, input.mergeFrontmatter);
524
550
  }
525
- const newBody = input.content !== void 0 ? input.content : parsed.content;
551
+ const newBody = input.content !== void 0 ? stripEchoedPageHeader(input.content, pageId) : parsed.content;
526
552
  const newContent = matter.stringify(newBody.trim(), newFm);
527
553
  writeFileSync4(filePath, newContent, "utf8");
528
554
  return [
@@ -544,7 +570,8 @@ var migrateDocsSchema = z6.object({
544
570
  branch: z6.string().optional().describe("Git branch (default: auto-detect)"),
545
571
  docsDir: z6.string().optional().describe("Docs subdirectory in repo (default: auto-detect)"),
546
572
  apiKey: z6.string().optional().describe("Anthropic API key for non-Markdown file conversion"),
547
- maxPages: z6.number().int().min(1).max(1e3).optional().describe("Maximum public URL pages to import")
573
+ maxPages: z6.number().int().min(1).max(1e3).optional().describe("Maximum public URL pages to import"),
574
+ platform: z6.enum(["mintlify", "docusaurus"]).optional().describe("Source platform (default: auto-detect)")
548
575
  });
549
576
  async function handleMigrateDocs(input) {
550
577
  const apiKey = input.apiKey ?? process.env.ANTHROPIC_API_KEY;
@@ -556,6 +583,7 @@ async function handleMigrateDocs(input) {
556
583
  branch: input.branch,
557
584
  docsDir: input.docsDir,
558
585
  maxPages: input.maxPages,
586
+ platform: input.platform,
559
587
  yes: true
560
588
  });
561
589
  return `Migration complete! ${result.pagesWritten} pages written to ${result.projectDir}/src/content/`;
@@ -746,12 +774,9 @@ async function handleReadPage(input) {
746
774
  const { data, content } = matter3(raw);
747
775
  const title = data.title ?? pageId;
748
776
  const description = data.description ?? "";
749
- const lines = [`# ${title}`, `*${pageId}*`, ""];
750
- if (description) {
751
- lines.push(`> ${description}`);
752
- lines.push("");
753
- }
754
- lines.push("---", "", content.trim());
777
+ const lines = [`id: ${pageId}`, `title: ${title}`];
778
+ if (description) lines.push(`description: ${description}`);
779
+ lines.push("", readPageBodyDelimiter(), "", content.trim());
755
780
  return lines.join("\n");
756
781
  }
757
782
 
package/dist/tools.js CHANGED
@@ -9,18 +9,21 @@ import { Readable, pipeline } from "stream";
9
9
  import { promisify } from "util";
10
10
  import tar from "tar";
11
11
  var pipelineAsync = promisify(pipeline);
12
- var TARBALL_URL = "https://codeload.github.com/thallylabs/thally/tar.gz/main";
13
- var EXCLUDE_PATHS = [
12
+ var MCP_TEMPLATE_REPOSITORY = "thallylabs/docs";
13
+ var TARBALL_URL = `https://codeload.github.com/${MCP_TEMPLATE_REPOSITORY}/tar.gz/main`;
14
+ var MCP_EXCLUDE_PATHS = [
14
15
  "/cli/",
15
16
  "/packages/",
16
17
  "/node_modules/",
17
18
  "/.git/",
18
- "/thally-agent.yml",
19
19
  "/thally-track.yml",
20
20
  "/CODEOWNERS",
21
21
  "/CLAUDE.md",
22
22
  "/notes/"
23
23
  ];
24
+ function shouldIncludeMcpTemplatePath(path) {
25
+ return !MCP_EXCLUDE_PATHS.some((excluded) => path.includes(excluded));
26
+ }
24
27
  var STARTER_PAGES = {
25
28
  "introduction.mdx": `---
26
29
  title: Introduction
@@ -106,12 +109,7 @@ async function downloadTemplate(targetDir) {
106
109
  tar.extract({
107
110
  cwd: targetDir,
108
111
  strip: 1,
109
- filter: (path) => {
110
- for (const excluded of EXCLUDE_PATHS) {
111
- if (path.includes(excluded)) return false;
112
- }
113
- return true;
114
- }
112
+ filter: shouldIncludeMcpTemplatePath
115
113
  })
116
114
  );
117
115
  }
@@ -322,6 +320,34 @@ function writeDocsJson(projectDir, config) {
322
320
  writeFileSync2(docsPath, JSON.stringify(config, null, 2) + "\n", "utf8");
323
321
  }
324
322
 
323
+ // src/lib/page-echo.ts
324
+ var BODY_DELIMITER = "--- MDX body ---";
325
+ function readPageBodyDelimiter() {
326
+ return BODY_DELIMITER;
327
+ }
328
+ function stripEchoedPageHeader(content, pageId) {
329
+ const lines = content.split("\n");
330
+ const delimiterIndex = lines.findIndex((line) => line.trim() === BODY_DELIMITER);
331
+ if (delimiterIndex !== -1 && delimiterIndex <= 6) {
332
+ return lines.slice(delimiterIndex + 1).join("\n").replace(/^\n+/, "");
333
+ }
334
+ const first = lines[0]?.trim() ?? "";
335
+ const second = lines[1]?.trim() ?? "";
336
+ if (first.startsWith("# ") && second === `*${pageId}*`) {
337
+ let index = 2;
338
+ while (index < lines.length && lines[index].trim() === "") index += 1;
339
+ if (lines[index]?.trim().startsWith("> ")) {
340
+ index += 1;
341
+ while (index < lines.length && lines[index].trim() === "") index += 1;
342
+ }
343
+ if (lines[index]?.trim() === "---") {
344
+ index += 1;
345
+ }
346
+ return lines.slice(index).join("\n").replace(/^\n+/, "");
347
+ }
348
+ return content;
349
+ }
350
+
325
351
  // src/tools/add-page.ts
326
352
  var addPageSchema = z2.object({
327
353
  projectDir: z2.string().describe("Path to the Thally project root"),
@@ -352,7 +378,7 @@ async function handleAddPage(input) {
352
378
  if (description) {
353
379
  frontmatterLines.push(`description: ${description}`);
354
380
  }
355
- const bodyContent = content ?? `## ${title}
381
+ const bodyContent = content ? stripEchoedPageHeader(content, pageId) : `## ${title}
356
382
 
357
383
  Add your content here.`;
358
384
  const mdxContent = `---
@@ -513,7 +539,7 @@ async function handleUpdatePage(input) {
513
539
  if (input.mergeFrontmatter) {
514
540
  Object.assign(newFm, input.mergeFrontmatter);
515
541
  }
516
- const newBody = input.content !== void 0 ? input.content : parsed.content;
542
+ const newBody = input.content !== void 0 ? stripEchoedPageHeader(input.content, pageId) : parsed.content;
517
543
  const newContent = matter.stringify(newBody.trim(), newFm);
518
544
  writeFileSync4(filePath, newContent, "utf8");
519
545
  return [
@@ -535,7 +561,8 @@ var migrateDocsSchema = z6.object({
535
561
  branch: z6.string().optional().describe("Git branch (default: auto-detect)"),
536
562
  docsDir: z6.string().optional().describe("Docs subdirectory in repo (default: auto-detect)"),
537
563
  apiKey: z6.string().optional().describe("Anthropic API key for non-Markdown file conversion"),
538
- maxPages: z6.number().int().min(1).max(1e3).optional().describe("Maximum public URL pages to import")
564
+ maxPages: z6.number().int().min(1).max(1e3).optional().describe("Maximum public URL pages to import"),
565
+ platform: z6.enum(["mintlify", "docusaurus"]).optional().describe("Source platform (default: auto-detect)")
539
566
  });
540
567
  async function handleMigrateDocs(input) {
541
568
  const apiKey = input.apiKey ?? process.env.ANTHROPIC_API_KEY;
@@ -547,6 +574,7 @@ async function handleMigrateDocs(input) {
547
574
  branch: input.branch,
548
575
  docsDir: input.docsDir,
549
576
  maxPages: input.maxPages,
577
+ platform: input.platform,
550
578
  yes: true
551
579
  });
552
580
  return `Migration complete! ${result.pagesWritten} pages written to ${result.projectDir}/src/content/`;
@@ -737,12 +765,9 @@ async function handleReadPage(input) {
737
765
  const { data, content } = matter3(raw);
738
766
  const title = data.title ?? pageId;
739
767
  const description = data.description ?? "";
740
- const lines = [`# ${title}`, `*${pageId}*`, ""];
741
- if (description) {
742
- lines.push(`> ${description}`);
743
- lines.push("");
744
- }
745
- lines.push("---", "", content.trim());
768
+ const lines = [`id: ${pageId}`, `title: ${title}`];
769
+ if (description) lines.push(`description: ${description}`);
770
+ lines.push("", readPageBodyDelimiter(), "", content.trim());
746
771
  return lines.join("\n");
747
772
  }
748
773
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thallylabs/mcp",
3
- "version": "0.7.4",
3
+ "version": "0.8.0",
4
4
  "description": "MCP server for scaffolding and managing Thally documentation projects",
5
5
  "type": "module",
6
6
  "engines": {
@@ -34,7 +34,7 @@
34
34
  "dependencies": {
35
35
  "@anthropic-ai/sdk": "^0.36.0",
36
36
  "@modelcontextprotocol/sdk": "^1.15.0",
37
- "create-thally-docs": "0.7.8",
37
+ "create-thally-docs": "0.8.0",
38
38
  "gray-matter": "^4.0.3",
39
39
  "p-limit": "^6.1.0",
40
40
  "tar": "^6.2.0",