@frase/mcp-server 0.3.6 → 0.3.8

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 (38) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/content-types-config-mirror.d.ts +75 -0
  3. package/dist/content-types-config-mirror.d.ts.map +1 -0
  4. package/dist/content-types-config-mirror.js +75 -0
  5. package/dist/content-types-config-mirror.js.map +1 -0
  6. package/dist/content-types.d.ts +3 -3
  7. package/dist/content-types.d.ts.map +1 -1
  8. package/dist/content-types.js +4 -2
  9. package/dist/content-types.js.map +1 -1
  10. package/dist/index.js +1 -1
  11. package/dist/lib/clean-render.d.ts +42 -0
  12. package/dist/lib/clean-render.d.ts.map +1 -0
  13. package/dist/lib/clean-render.js +126 -0
  14. package/dist/lib/clean-render.js.map +1 -0
  15. package/dist/prompts/content-pipeline.d.ts.map +1 -1
  16. package/dist/prompts/content-pipeline.js +5 -2
  17. package/dist/prompts/content-pipeline.js.map +1 -1
  18. package/dist/prompts/create-seo-article.d.ts.map +1 -1
  19. package/dist/prompts/create-seo-article.js +5 -2
  20. package/dist/prompts/create-seo-article.js.map +1 -1
  21. package/dist/tools/ai-visibility.d.ts +14 -0
  22. package/dist/tools/ai-visibility.d.ts.map +1 -1
  23. package/dist/tools/ai-visibility.js +296 -0
  24. package/dist/tools/ai-visibility.js.map +1 -1
  25. package/dist/tools/briefs.d.ts +6 -6
  26. package/dist/tools/cms-posts.d.ts +2 -0
  27. package/dist/tools/cms-posts.d.ts.map +1 -1
  28. package/dist/tools/cms-posts.js +62 -11
  29. package/dist/tools/cms-posts.js.map +1 -1
  30. package/dist/tools/index.d.ts +7 -1
  31. package/dist/tools/index.d.ts.map +1 -1
  32. package/dist/tools/index.js +16 -2
  33. package/dist/tools/index.js.map +1 -1
  34. package/dist/tools/serp.d.ts.map +1 -1
  35. package/dist/tools/serp.js +17 -13
  36. package/dist/tools/serp.js.map +1 -1
  37. package/package.json +12 -5
  38. package/server.json +2 -2
package/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.3.7] - 2026-06-04
9
+
10
+ ### Fixed
11
+ - `analyze_serp`: People Also Ask entries rendered as `[object Object]` and several fields showed `undefined`. PAA questions and result fields now render correctly.
12
+
13
+ ### Changed
14
+ - Bumped `@frase/core` dependency to `0.1.5`, which adds the `ToolResult.hidden`/`reason` hide-mirror fields and `McpToolDefinition.inputSchema.additionalProperties` that the AI-visibility tools rely on. (The tools had used these since late May, but core was never republished — the build only typechecks at publish time, so it surfaced now.)
15
+ - Updated runtime dependencies (`hono`, `@modelcontextprotocol/sdk`) and upgraded the test toolchain (`vitest` 2.x → 4.x) to clear a critical security advisory.
16
+ - `server.json` `version` (and its nested npm package `version`) corrected from `0.3.5` to track the package version — it had drifted behind `package.json`/`manifest.json` since 0.3.6.
17
+
8
18
  ## [0.3.6] - 2026-05-18
9
19
 
10
20
  ### Added
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Cross-package mirror of the per-content-type JSON Schemas emitted by
3
+ * `src/lib/content/content-type-configs/*` in the main Next.js app.
4
+ *
5
+ * Cross-package import is blocked: the MCP server publishes as its own
6
+ * npm package and cannot reach into the main app's Next.js source. This
7
+ * constant MUST stay in sync with `src/lib/content/content-type-configs/tool-review.ts`.
8
+ *
9
+ * A parity contract test asserts deep-equality against the live
10
+ * `contentTypeConfigRegistry.tool_review.jsonSchema` produced by zod 4's
11
+ * `z.toJSONSchema()`:
12
+ * src/lib/content/content-type-configs/__tests__/mcp-parity.test.ts
13
+ *
14
+ * If you change the Zod schema in the main app, regenerate this constant
15
+ * by running (from repo root):
16
+ * npx tsx -e "import('./src/lib/content/content-type-configs/tool-review').then(m => console.log(JSON.stringify((m.default ?? m).toolReviewConfigModule.jsonSchema, null, 2)))"
17
+ * and paste the output below verbatim. The contract test will fail until
18
+ * the mirror is updated.
19
+ */
20
+ export declare const TOOL_REVIEW_JSON_SCHEMA: {
21
+ readonly $schema: "https://json-schema.org/draft/2020-12/schema";
22
+ readonly type: "object";
23
+ readonly properties: {
24
+ readonly rating: {
25
+ readonly type: "number";
26
+ readonly minimum: 0;
27
+ readonly maximum: 5;
28
+ };
29
+ readonly prosList: {
30
+ readonly default: readonly [];
31
+ readonly type: "array";
32
+ readonly items: {
33
+ readonly type: "string";
34
+ readonly minLength: 1;
35
+ };
36
+ };
37
+ readonly consList: {
38
+ readonly default: readonly [];
39
+ readonly type: "array";
40
+ readonly items: {
41
+ readonly type: "string";
42
+ readonly minLength: 1;
43
+ };
44
+ };
45
+ readonly pricingNote: {
46
+ readonly type: "string";
47
+ readonly minLength: 1;
48
+ };
49
+ readonly verdictSummary: {
50
+ readonly type: "string";
51
+ readonly minLength: 1;
52
+ };
53
+ readonly toolCategory: {
54
+ readonly type: "string";
55
+ readonly minLength: 1;
56
+ };
57
+ readonly toolOS: {
58
+ readonly type: "string";
59
+ readonly minLength: 1;
60
+ };
61
+ readonly aggregateRatingValue: {
62
+ readonly type: "number";
63
+ readonly minimum: 0;
64
+ readonly maximum: 5;
65
+ };
66
+ readonly aggregateRatingCount: {
67
+ readonly type: "integer";
68
+ readonly minimum: 0;
69
+ readonly maximum: 9007199254740991;
70
+ };
71
+ };
72
+ readonly required: readonly ["rating", "prosList", "consList"];
73
+ readonly additionalProperties: false;
74
+ };
75
+ //# sourceMappingURL=content-types-config-mirror.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-types-config-mirror.d.ts","sourceRoot":"","sources":["../src/content-types-config-mirror.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsD1B,CAAC"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Cross-package mirror of the per-content-type JSON Schemas emitted by
3
+ * `src/lib/content/content-type-configs/*` in the main Next.js app.
4
+ *
5
+ * Cross-package import is blocked: the MCP server publishes as its own
6
+ * npm package and cannot reach into the main app's Next.js source. This
7
+ * constant MUST stay in sync with `src/lib/content/content-type-configs/tool-review.ts`.
8
+ *
9
+ * A parity contract test asserts deep-equality against the live
10
+ * `contentTypeConfigRegistry.tool_review.jsonSchema` produced by zod 4's
11
+ * `z.toJSONSchema()`:
12
+ * src/lib/content/content-type-configs/__tests__/mcp-parity.test.ts
13
+ *
14
+ * If you change the Zod schema in the main app, regenerate this constant
15
+ * by running (from repo root):
16
+ * npx tsx -e "import('./src/lib/content/content-type-configs/tool-review').then(m => console.log(JSON.stringify((m.default ?? m).toolReviewConfigModule.jsonSchema, null, 2)))"
17
+ * and paste the output below verbatim. The contract test will fail until
18
+ * the mirror is updated.
19
+ */
20
+ export const TOOL_REVIEW_JSON_SCHEMA = {
21
+ $schema: "https://json-schema.org/draft/2020-12/schema",
22
+ type: "object",
23
+ properties: {
24
+ rating: {
25
+ type: "number",
26
+ minimum: 0,
27
+ maximum: 5,
28
+ },
29
+ prosList: {
30
+ default: [],
31
+ type: "array",
32
+ items: {
33
+ type: "string",
34
+ minLength: 1,
35
+ },
36
+ },
37
+ consList: {
38
+ default: [],
39
+ type: "array",
40
+ items: {
41
+ type: "string",
42
+ minLength: 1,
43
+ },
44
+ },
45
+ pricingNote: {
46
+ type: "string",
47
+ minLength: 1,
48
+ },
49
+ verdictSummary: {
50
+ type: "string",
51
+ minLength: 1,
52
+ },
53
+ toolCategory: {
54
+ type: "string",
55
+ minLength: 1,
56
+ },
57
+ toolOS: {
58
+ type: "string",
59
+ minLength: 1,
60
+ },
61
+ aggregateRatingValue: {
62
+ type: "number",
63
+ minimum: 0,
64
+ maximum: 5,
65
+ },
66
+ aggregateRatingCount: {
67
+ type: "integer",
68
+ minimum: 0,
69
+ maximum: 9007199254740991,
70
+ },
71
+ },
72
+ required: ["rating", "prosList", "consList"],
73
+ additionalProperties: false,
74
+ };
75
+ //# sourceMappingURL=content-types-config-mirror.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-types-config-mirror.js","sourceRoot":"","sources":["../src/content-types-config-mirror.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,OAAO,EAAE,8CAA8C;IACvD,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,CAAC;SACX;QACD,QAAQ,EAAE;YACR,OAAO,EAAE,EAAE;YACX,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,SAAS,EAAE,CAAC;aACb;SACF;QACD,QAAQ,EAAE;YACR,OAAO,EAAE,EAAE;YACX,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,SAAS,EAAE,CAAC;aACb;SACF;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,CAAC;SACb;QACD,cAAc,EAAE;YACd,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,CAAC;SACb;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,CAAC;SACb;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,CAAC;SACb;QACD,oBAAoB,EAAE;YACpB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,CAAC;SACX;QACD,oBAAoB,EAAE;YACpB,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,gBAAgB;SAC1B;KACF;IACD,QAAQ,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,UAAU,CAAC;IAC5C,oBAAoB,EAAE,KAAK;CACnB,CAAC"}
@@ -1,16 +1,16 @@
1
1
  /**
2
- * The 16-type content taxonomy used by the Frase platform.
2
+ * The 18-type content taxonomy used by the Frase platform.
3
3
  *
4
4
  * This is the canonical list of values the `/api/v1/briefs` endpoint
5
5
  * accepts in `content_type`. The API also accepts legacy 5-bucket
6
6
  * values (`blog`, `guide`, `landing`, `product`, `comparison`) for
7
7
  * back-compat and normalizes them at the boundary, but new MCP
8
- * integrations should use these 16 values directly.
8
+ * integrations should use these 18 values directly.
9
9
  *
10
10
  * Keep this list in lockstep with `src/lib/core/content-types.ts`
11
11
  * in the main app. We can't import from there because the MCP server
12
12
  * publishes as its own npm package and can't reach into Next.js source.
13
13
  */
14
- export declare const CONTENT_TYPES: readonly ["blog_post", "page", "faq", "glossary", "comparison", "pillar", "how_to", "landing", "listicle", "case_study", "tutorial", "news", "product_update", "data_report", "event", "resource"];
14
+ export declare const CONTENT_TYPES: readonly ["blog_post", "page", "faq", "glossary", "comparison", "pillar", "how_to", "landing", "listicle", "case_study", "tutorial", "news", "product_update", "data_report", "event", "resource", "alternative", "tool_review"];
15
15
  export type ContentType = (typeof CONTENT_TYPES)[number];
16
16
  //# sourceMappingURL=content-types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"content-types.d.ts","sourceRoot":"","sources":["../src/content-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,oMAiBhB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"content-types.d.ts","sourceRoot":"","sources":["../src/content-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,kOAmBhB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -1,11 +1,11 @@
1
1
  /**
2
- * The 16-type content taxonomy used by the Frase platform.
2
+ * The 18-type content taxonomy used by the Frase platform.
3
3
  *
4
4
  * This is the canonical list of values the `/api/v1/briefs` endpoint
5
5
  * accepts in `content_type`. The API also accepts legacy 5-bucket
6
6
  * values (`blog`, `guide`, `landing`, `product`, `comparison`) for
7
7
  * back-compat and normalizes them at the boundary, but new MCP
8
- * integrations should use these 16 values directly.
8
+ * integrations should use these 18 values directly.
9
9
  *
10
10
  * Keep this list in lockstep with `src/lib/core/content-types.ts`
11
11
  * in the main app. We can't import from there because the MCP server
@@ -28,5 +28,7 @@ export const CONTENT_TYPES = [
28
28
  "data_report",
29
29
  "event",
30
30
  "resource",
31
+ "alternative",
32
+ "tool_review",
31
33
  ];
32
34
  //# sourceMappingURL=content-types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"content-types.js","sourceRoot":"","sources":["../src/content-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,WAAW;IACX,MAAM;IACN,KAAK;IACL,UAAU;IACV,YAAY;IACZ,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,UAAU;IACV,YAAY;IACZ,UAAU;IACV,MAAM;IACN,gBAAgB;IAChB,aAAa;IACb,OAAO;IACP,UAAU;CACF,CAAC"}
1
+ {"version":3,"file":"content-types.js","sourceRoot":"","sources":["../src/content-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,WAAW;IACX,MAAM;IACN,KAAK;IACL,UAAU;IACV,YAAY;IACZ,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,UAAU;IACV,YAAY;IACZ,UAAU;IACV,MAAM;IACN,gBAAgB;IAChB,aAAa;IACb,OAAO;IACP,UAAU;IACV,aAAa;IACb,aAAa;CACL,CAAC"}
package/dist/index.js CHANGED
@@ -65,7 +65,7 @@ import { ALL_RESOURCE_TEMPLATES, listAllResources, readResource, getRootResource
65
65
  import { ALL_PROMPTS, getPromptByName, getPromptMessages, } from "./prompts/index.js";
66
66
  // Server metadata
67
67
  const SERVER_NAME = "frase-mcp-server";
68
- const SERVER_VERSION = "0.3.6";
68
+ const SERVER_VERSION = "0.3.7";
69
69
  /**
70
70
  * Main MCP server class
71
71
  */
@@ -0,0 +1,42 @@
1
+ import type { ToolExecutor } from "../types.js";
2
+ /**
3
+ * Detects "the tool ran successfully but shipped garbage" — the class of bug
4
+ * where an object is coerced into markdown as `[object Object]`, or a leaked
5
+ * `undefined`/`NaN` lands in rendered prose. (Real example: People Also Ask
6
+ * entries rendered as `[object Object]` to every user, found only via a
7
+ * customer report.)
8
+ *
9
+ * In tests/CI a dirty render throws (pre-merge gate). In real traffic it never
10
+ * throws — it emits a structured warning and returns the result unchanged.
11
+ */
12
+ export interface RenderIssue {
13
+ /** The offending token, e.g. "[object Object]", "undefined", "empty-table". */
14
+ pattern: string;
15
+ /** A short slice of surrounding text, for the warning/error message. */
16
+ snippet: string;
17
+ }
18
+ export interface AssertCleanRenderOpts {
19
+ /**
20
+ * Set for `success: false` results — only the `[object …]` check runs, since
21
+ * error messages may legitimately mention "undefined"/"NaN".
22
+ */
23
+ errorResult?: boolean;
24
+ }
25
+ export declare class CleanRenderError extends Error {
26
+ readonly toolName: string;
27
+ readonly issues: RenderIssue[];
28
+ constructor(toolName: string, issues: RenderIssue[]);
29
+ }
30
+ /**
31
+ * Returns the render defects found in `markdown` (empty array = clean). Pure;
32
+ * conservative by design — tuned to catch the real bug class with near-zero
33
+ * false positives on legitimate empty-state output.
34
+ */
35
+ export declare function assertCleanRender(markdown: string, opts?: AssertCleanRenderOpts): RenderIssue[];
36
+ /**
37
+ * Wraps a tool executor so its rendered markdown is validated on every call.
38
+ * Applied at the `TOOL_EXECUTORS` chokepoint, so it covers every tool on both
39
+ * the stdio and in-app HTTP surfaces. Never alters the result.
40
+ */
41
+ export declare function withCleanRender(toolName: string, executor: ToolExecutor): ToolExecutor;
42
+ //# sourceMappingURL=clean-render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clean-render.d.ts","sourceRoot":"","sources":["../../src/lib/clean-render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;;;;;;GASG;AAEH,MAAM,WAAW,WAAW;IAC1B,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAgBD,qBAAa,gBAAiB,SAAQ,KAAK;aAEvB,QAAQ,EAAE,MAAM;aAChB,MAAM,EAAE,WAAW,EAAE;gBADrB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,WAAW,EAAE;CAQxC;AAyBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,qBAA0B,GAC/B,WAAW,EAAE,CA0Df;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,YAAY,GACrB,YAAY,CAmBd"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Throw on a dirty render instead of warning. Tests, CI, and the scheduled
3
+ * synthetic smoke opt in; real stdio (customer machine) and in-app HTTP traffic
4
+ * never throw — a bad render must not break a live tool call. Evaluated per
5
+ * call so the environment can be toggled (e.g. in tests).
6
+ */
7
+ function isRenderStrict() {
8
+ return (!!process.env.VITEST ||
9
+ process.env.NODE_ENV === "test" ||
10
+ process.env.FRASE_RENDER_STRICT === "1");
11
+ }
12
+ export class CleanRenderError extends Error {
13
+ toolName;
14
+ issues;
15
+ constructor(toolName, issues) {
16
+ super(`Tool "${toolName}" produced a dirty render: ` +
17
+ issues.map((i) => `${i.pattern} (…${i.snippet}…)`).join("; "));
18
+ this.toolName = toolName;
19
+ this.issues = issues;
20
+ this.name = "CleanRenderError";
21
+ }
22
+ }
23
+ /**
24
+ * Blank out spans where these tokens are legitimate so they don't trip the
25
+ * scanner: fenced code blocks, inline code, and italic placeholders (the
26
+ * `_No results found._` empty-state convention, which `hidden: true` branches
27
+ * also use). Replaced with a space to preserve word boundaries around them.
28
+ */
29
+ function stripSafeSpans(md) {
30
+ return md
31
+ .replace(/```[\s\S]*?```/g, " ")
32
+ .replace(/`[^`]*`/g, " ")
33
+ // NOTE: greedy `_…_` blanking can also blank a snake_case span in prose
34
+ // (e.g. `field_undefined_value`), which could mask a token sitting between
35
+ // two snake_case words. That's a false-negative only (we'd miss a defect),
36
+ // never a false-positive — acceptable for this conservative validator.
37
+ .replace(/_[^_]+_/g, " ");
38
+ }
39
+ function snippetAround(text, index, len) {
40
+ const start = Math.max(0, index - 30);
41
+ const end = Math.min(text.length, index + len + 30);
42
+ return text.slice(start, end).replace(/\s+/g, " ").trim();
43
+ }
44
+ /**
45
+ * Returns the render defects found in `markdown` (empty array = clean). Pure;
46
+ * conservative by design — tuned to catch the real bug class with near-zero
47
+ * false positives on legitimate empty-state output.
48
+ */
49
+ export function assertCleanRender(markdown, opts = {}) {
50
+ const issues = [];
51
+ if (!markdown)
52
+ return issues;
53
+ // A coerced object is always a bug — even inside code or error messages.
54
+ const objMatch = markdown.match(/\[object \w+\]/);
55
+ if (objMatch) {
56
+ issues.push({
57
+ pattern: objMatch[0],
58
+ snippet: snippetAround(markdown, objMatch.index ?? 0, objMatch[0].length),
59
+ });
60
+ }
61
+ // Error results legitimately mention "undefined"/"NaN"; stop after the
62
+ // object check above.
63
+ if (opts.errorResult)
64
+ return issues;
65
+ const stripped = stripSafeSpans(markdown);
66
+ // Leaked `undefined`/`NaN` — but ONLY in a formatted-value position, never in
67
+ // free prose. Many tools pass verbatim user/LLM text through (article bodies,
68
+ // brief sections, descriptions) that legitimately contains the words
69
+ // "undefined"/"NaN"; scanning prose would false-positive and, in strict mode,
70
+ // throw on a valid tool call. So we anchor to where the formatter emits a
71
+ // value: a table cell, a bold "key:" value, a colon-terminated heading/label,
72
+ // or a bare list item. Case-sensitive — JS coercion yields exactly these.
73
+ // `null` is deliberately not checked (pervasive in legit JSON/prose).
74
+ const SCAFFOLD_TOKEN_RES = [
75
+ /\|\s*(undefined|NaN)\s*(?=\|)/g, // | undefined | (table cell)
76
+ /:\*\*\s*(undefined|NaN)\b/g, // **Key:** undefined
77
+ /:[^\S\n]*(undefined|NaN)[^\S\n]*$/gm, // ## Heading: undefined / Label: undefined
78
+ /^[^\S\n]*[-*][^\S\n]+(undefined|NaN)[^\S\n]*$/gm, // - undefined (bare list value)
79
+ ];
80
+ for (const re of SCAFFOLD_TOKEN_RES) {
81
+ let m;
82
+ while ((m = re.exec(stripped)) !== null) {
83
+ issues.push({
84
+ pattern: m[1],
85
+ snippet: snippetAround(stripped, m.index, m[0].length),
86
+ });
87
+ }
88
+ }
89
+ // A markdown table separator row with no data row after it. `formatTable()`
90
+ // guards this, but a hand-rolled table can still emit an empty grid.
91
+ const lines = stripped.split("\n");
92
+ const separatorRe = /^\s*\|(?:\s*:?-+:?\s*\|)+\s*$/;
93
+ for (let i = 0; i < lines.length; i++) {
94
+ if (separatorRe.test(lines[i])) {
95
+ const next = lines[i + 1];
96
+ const nextIsRow = next !== undefined && /^\s*\|/.test(next);
97
+ if (!nextIsRow) {
98
+ issues.push({ pattern: "empty-table", snippet: lines[i].trim() });
99
+ }
100
+ }
101
+ }
102
+ return issues;
103
+ }
104
+ /**
105
+ * Wraps a tool executor so its rendered markdown is validated on every call.
106
+ * Applied at the `TOOL_EXECUTORS` chokepoint, so it covers every tool on both
107
+ * the stdio and in-app HTTP surfaces. Never alters the result.
108
+ */
109
+ export function withCleanRender(toolName, executor) {
110
+ return async (input, context) => {
111
+ const result = await executor(input, context);
112
+ const issues = assertCleanRender(result.markdown ?? "", {
113
+ errorResult: !result.success,
114
+ });
115
+ if (issues.length > 0) {
116
+ if (isRenderStrict()) {
117
+ throw new CleanRenderError(toolName, issues);
118
+ }
119
+ // Structured warning → Sentry Logs via consoleLoggingIntegration on the
120
+ // in-app surface; visible in stderr on the stdio surface.
121
+ console.warn("mcp_dirty_render", JSON.stringify({ tool: toolName, issues }));
122
+ }
123
+ return result;
124
+ };
125
+ }
126
+ //# sourceMappingURL=clean-render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clean-render.js","sourceRoot":"","sources":["../../src/lib/clean-render.ts"],"names":[],"mappings":"AA4BA;;;;;GAKG;AACH,SAAS,cAAc;IACrB,OAAO,CACL,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM;QACpB,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM;QAC/B,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,GAAG,CACxC,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAEvB;IACA;IAFlB,YACkB,QAAgB,EAChB,MAAqB;QAErC,KAAK,CACH,SAAS,QAAQ,6BAA6B;YAC5C,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAChE,CAAC;QANc,aAAQ,GAAR,QAAQ,CAAQ;QAChB,WAAM,GAAN,MAAM,CAAe;QAMrC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED;;;;;GAKG;AACH,SAAS,cAAc,CAAC,EAAU;IAChC,OAAO,EAAE;SACN,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC;SAC/B,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;QACzB,wEAAwE;QACxE,2EAA2E;QAC3E,2EAA2E;QAC3E,uEAAuE;SACtE,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,aAAa,CAAC,IAAY,EAAE,KAAa,EAAE,GAAW;IAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,EAAE,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC;IACpD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAC5D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAgB,EAChB,OAA8B,EAAE;IAEhC,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,IAAI,CAAC,QAAQ;QAAE,OAAO,MAAM,CAAC;IAE7B,yEAAyE;IACzE,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAClD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC;YACV,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;YACpB,OAAO,EAAE,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;SAC1E,CAAC,CAAC;IACL,CAAC;IAED,uEAAuE;IACvE,sBAAsB;IACtB,IAAI,IAAI,CAAC,WAAW;QAAE,OAAO,MAAM,CAAC;IAEpC,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAE1C,8EAA8E;IAC9E,8EAA8E;IAC9E,qEAAqE;IACrE,8EAA8E;IAC9E,0EAA0E;IAC1E,8EAA8E;IAC9E,0EAA0E;IAC1E,sEAAsE;IACtE,MAAM,kBAAkB,GAAa;QACnC,gCAAgC,EAAE,8BAA8B;QAChE,4BAA4B,EAAE,qBAAqB;QACnD,qCAAqC,EAAE,6CAA6C;QACpF,iDAAiD,EAAE,iCAAiC;KACrF,CAAC;IACF,KAAK,MAAM,EAAE,IAAI,kBAAkB,EAAE,CAAC;QACpC,IAAI,CAAyB,CAAC;QAC9B,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC;gBACV,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;gBACb,OAAO,EAAE,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;aACvD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,qEAAqE;IACrE,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,WAAW,GAAG,+BAA+B,CAAC;IACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC1B,MAAM,SAAS,GAAG,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5D,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACpE,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,QAAsB;IAEtB,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC9B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,EAAE;YACtD,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO;SAC7B,CAAC,CAAC;QACH,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,IAAI,cAAc,EAAE,EAAE,CAAC;gBACrB,MAAM,IAAI,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC/C,CAAC;YACD,wEAAwE;YACxE,0DAA0D;YAC1D,OAAO,CAAC,IAAI,CACV,kBAAkB,EAClB,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAC3C,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"content-pipeline.d.ts","sourceRoot":"","sources":["../../src/prompts/content-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,eAAO,MAAM,qBAAqB,EAAE,mBAoCnC,CAAC;AAEF,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;IAC9E,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACzC,CAAC,CAoDD"}
1
+ {"version":3,"file":"content-pipeline.d.ts","sourceRoot":"","sources":["../../src/prompts/content-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,eAAO,MAAM,qBAAqB,EAAE,mBAwCnC,CAAC;AAEF,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;IAC9E,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACzC,CAAC,CAoDD"}
@@ -34,7 +34,10 @@ export const contentPipelinePrompt = {
34
34
  },
35
35
  {
36
36
  name: "content_type",
37
- description: "Type of content: blog, guide, comparison, landing, product (default: blog)",
37
+ description: "Canonical content type (one of 18) e.g. blog_post, how_to, listicle, " +
38
+ "case_study, tutorial, comparison, alternative, tool_review, pillar, landing, " +
39
+ "faq, glossary, news, product_update, data_report, event, resource, page. " +
40
+ "Default: blog_post. See create_brief for the enum.",
38
41
  required: false,
39
42
  },
40
43
  {
@@ -53,7 +56,7 @@ export function getContentPipelineMessages(args) {
53
56
  const topic = args.topic || "the requested topic";
54
57
  const siteId = args.site_id || "";
55
58
  const targetScore = args.target_score || "70";
56
- const contentType = args.content_type || "blog";
59
+ const contentType = args.content_type || "blog_post";
57
60
  const targetLanguage = args.target_language || "en";
58
61
  const targetCountry = args.target_country || "us";
59
62
  return [
@@ -1 +1 @@
1
- {"version":3,"file":"content-pipeline.js","sourceRoot":"","sources":["../../src/prompts/content-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,MAAM,CAAC,MAAM,qBAAqB,GAAwB;IACxD,IAAI,EAAE,kBAAkB;IACxB,WAAW,EACT,mNAAmN;IACrN,SAAS,EAAE;QACT;YACE,IAAI,EAAE,OAAO;YACb,WAAW,EAAE,yDAAyD;YACtE,QAAQ,EAAE,IAAI;SACf;QACD;YACE,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,6DAA6D;YAC1E,QAAQ,EAAE,IAAI;SACf;QACD;YACE,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,0EAA0E;YACvF,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,4EAA4E;YACzF,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,IAAI,EAAE,iBAAiB;YACvB,WAAW,EAAE,iFAAiF;YAC9F,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,IAAI,EAAE,gBAAgB;YACtB,WAAW,EAAE,6EAA6E;YAC1F,QAAQ,EAAE,KAAK;SAChB;KACF;CACF,CAAC;AAEF,MAAM,UAAU,0BAA0B,CAAC,IAA4B;IAIrE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,qBAAqB,CAAC;IAClD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IAClC,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC;IAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,IAAI,MAAM,CAAC;IAChD,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC;IACpD,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC;IAElD,OAAO;QACL;YACE,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE;gBACP,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,sCAAsC,KAAK;;;aAG5C,MAAM;kBACD,WAAW;+BACE,WAAW;cAC5B,cAAc;aACf,aAAa;;;;wDAI8B,KAAK,kBAAkB,MAAM;;;;mBAIlE,WAAW;;;;;;0BAMJ,WAAW;;;;;+DAK0B,MAAM,iKAAiK,MAAM;;4FAEhJ,KAAK,wDAAwD,KAAK;;;;;;;gCAO9H;aACzB;SACF;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"content-pipeline.js","sourceRoot":"","sources":["../../src/prompts/content-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,MAAM,CAAC,MAAM,qBAAqB,GAAwB;IACxD,IAAI,EAAE,kBAAkB;IACxB,WAAW,EACT,mNAAmN;IACrN,SAAS,EAAE;QACT;YACE,IAAI,EAAE,OAAO;YACb,WAAW,EAAE,yDAAyD;YACtE,QAAQ,EAAE,IAAI;SACf;QACD;YACE,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,6DAA6D;YAC1E,QAAQ,EAAE,IAAI;SACf;QACD;YACE,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,0EAA0E;YACvF,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,IAAI,EAAE,cAAc;YACpB,WAAW,EACT,yEAAyE;gBACzE,+EAA+E;gBAC/E,2EAA2E;gBAC3E,oDAAoD;YACtD,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,IAAI,EAAE,iBAAiB;YACvB,WAAW,EAAE,iFAAiF;YAC9F,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,IAAI,EAAE,gBAAgB;YACtB,WAAW,EAAE,6EAA6E;YAC1F,QAAQ,EAAE,KAAK;SAChB;KACF;CACF,CAAC;AAEF,MAAM,UAAU,0BAA0B,CAAC,IAA4B;IAIrE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,qBAAqB,CAAC;IAClD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IAClC,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC;IAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,IAAI,WAAW,CAAC;IACrD,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC;IACpD,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC;IAElD,OAAO;QACL;YACE,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE;gBACP,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,sCAAsC,KAAK;;;aAG5C,MAAM;kBACD,WAAW;+BACE,WAAW;cAC5B,cAAc;aACf,aAAa;;;;wDAI8B,KAAK,kBAAkB,MAAM;;;;mBAIlE,WAAW;;;;;;0BAMJ,WAAW;;;;;+DAK0B,MAAM,iKAAiK,MAAM;;4FAEhJ,KAAK,wDAAwD,KAAK;;;;;;;gCAO9H;aACzB;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"create-seo-article.d.ts","sourceRoot":"","sources":["../../src/prompts/create-seo-article.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,eAAO,MAAM,sBAAsB,EAAE,mBA2BpC,CAAC;AAEF,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;IAC/E,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACzC,CAAC,CA4DD"}
1
+ {"version":3,"file":"create-seo-article.d.ts","sourceRoot":"","sources":["../../src/prompts/create-seo-article.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,eAAO,MAAM,sBAAsB,EAAE,mBA8BpC,CAAC;AAEF,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;IAC/E,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACzC,CAAC,CA4DD"}
@@ -26,7 +26,10 @@ export const createSeoArticlePrompt = {
26
26
  },
27
27
  {
28
28
  name: "content_type",
29
- description: "Type of content: blog, guide, comparison, landing, product (default: blog)",
29
+ description: "Canonical content type (one of 18) e.g. blog_post, how_to, listicle, " +
30
+ "case_study, tutorial, comparison, alternative, tool_review, pillar, landing, " +
31
+ "faq, glossary, news, product_update, data_report, event, resource, page. " +
32
+ "Default: blog_post. See create_brief for the enum.",
30
33
  required: false,
31
34
  },
32
35
  {
@@ -38,7 +41,7 @@ export const createSeoArticlePrompt = {
38
41
  };
39
42
  export function getCreateSeoArticleMessages(args) {
40
43
  const topic = args.topic || "the requested topic";
41
- const contentType = args.content_type || "blog";
44
+ const contentType = args.content_type || "blog_post";
42
45
  const siteId = args.site_id || "";
43
46
  const targetScore = args.target_score || "70";
44
47
  return [
@@ -1 +1 @@
1
- {"version":3,"file":"create-seo-article.js","sourceRoot":"","sources":["../../src/prompts/create-seo-article.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,MAAM,CAAC,MAAM,sBAAsB,GAAwB;IACzD,IAAI,EAAE,oBAAoB;IAC1B,WAAW,EACT,yPAAyP;IAC3P,SAAS,EAAE;QACT;YACE,IAAI,EAAE,OAAO;YACb,WAAW,EAAE,+CAA+C;YAC5D,QAAQ,EAAE,IAAI;SACf;QACD;YACE,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,iGAAiG;YAC9G,QAAQ,EAAE,IAAI;SACf;QACD;YACE,IAAI,EAAE,cAAc;YACpB,WAAW,EACT,4EAA4E;YAC9E,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,4DAA4D;YACzE,QAAQ,EAAE,KAAK;SAChB;KACF;CACF,CAAC;AAEF,MAAM,UAAU,2BAA2B,CAAC,IAA4B;IAItE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,qBAAqB,CAAC;IAClD,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,IAAI,MAAM,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IAClC,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC;IAE9C,OAAO;QACL;YACE,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE;gBACP,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,uDAAuD,KAAK;;;kBAGxD,WAAW;aAChB,MAAM;+BACY,WAAW;;;;6DAImB,KAAK,kBAAkB,MAAM;;;;sBAIpE,WAAW;;;;;;;;;;;;;;;;;;;6BAmBJ,WAAW;;;;;8CAKM,MAAM;0GACsD,MAAM;;;;4EAIpC,KAAK;;;uEAGV;aAChE;SACF;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"create-seo-article.js","sourceRoot":"","sources":["../../src/prompts/create-seo-article.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,MAAM,CAAC,MAAM,sBAAsB,GAAwB;IACzD,IAAI,EAAE,oBAAoB;IAC1B,WAAW,EACT,yPAAyP;IAC3P,SAAS,EAAE;QACT;YACE,IAAI,EAAE,OAAO;YACb,WAAW,EAAE,+CAA+C;YAC5D,QAAQ,EAAE,IAAI;SACf;QACD;YACE,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,iGAAiG;YAC9G,QAAQ,EAAE,IAAI;SACf;QACD;YACE,IAAI,EAAE,cAAc;YACpB,WAAW,EACT,yEAAyE;gBACzE,+EAA+E;gBAC/E,2EAA2E;gBAC3E,oDAAoD;YACtD,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,4DAA4D;YACzE,QAAQ,EAAE,KAAK;SAChB;KACF;CACF,CAAC;AAEF,MAAM,UAAU,2BAA2B,CAAC,IAA4B;IAItE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,qBAAqB,CAAC;IAClD,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,IAAI,WAAW,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IAClC,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC;IAE9C,OAAO;QACL;YACE,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE;gBACP,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,uDAAuD,KAAK;;;kBAGxD,WAAW;aAChB,MAAM;+BACY,WAAW;;;;6DAImB,KAAK,kBAAkB,MAAM;;;;sBAIpE,WAAW;;;;;;;;;;;;;;;;;;;6BAmBJ,WAAW;;;;;8CAKM,MAAM;0GACsD,MAAM;;;;4EAIpC,KAAK;;;uEAGV;aAChE;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -3,9 +3,12 @@
3
3
  *
4
4
  * Track how your content appears in AI-powered search results
5
5
  */
6
+ import { z } from "zod";
6
7
  import type { McpToolDefinition, ToolContext, ToolResult } from "../types.js";
7
8
  export declare const getAiVisibilityTool: McpToolDefinition;
8
9
  export declare function executeGetAiVisibility(input: unknown, context: ToolContext): Promise<ToolResult>;
10
+ export declare const getIndustryBenchmarkTool: McpToolDefinition;
11
+ export declare function executeGetIndustryBenchmark(input: unknown, context: ToolContext): Promise<ToolResult>;
9
12
  export declare const listPromptsTool: McpToolDefinition;
10
13
  export declare function executeListPrompts(input: unknown, context: ToolContext): Promise<ToolResult>;
11
14
  export declare const createPromptTool: McpToolDefinition;
@@ -22,6 +25,17 @@ export declare const getInsightsTool: McpToolDefinition;
22
25
  export declare function executeGetInsights(input: unknown, context: ToolContext): Promise<ToolResult>;
23
26
  export declare const getCrawlerLogsTool: McpToolDefinition;
24
27
  export declare function executeGetCrawlerLogs(input: unknown, context: ToolContext): Promise<ToolResult>;
28
+ export declare const CITATION_FORMULA_FEATURE_LABELS: Record<string, string>;
29
+ export declare function citationFormulaLabelFor(featureName: string): string;
30
+ export declare const getCitationFormulaInputSchema: z.ZodObject<{
31
+ flavor: z.ZodDefault<z.ZodEnum<["active", "full"]>>;
32
+ }, "strict", z.ZodTypeAny, {
33
+ flavor: "full" | "active";
34
+ }, {
35
+ flavor?: "full" | "active" | undefined;
36
+ }>;
37
+ export declare const getCitationFormulaTool: McpToolDefinition;
38
+ export declare function executeGetCitationFormula(input: unknown, context: ToolContext): Promise<ToolResult>;
25
39
  export declare const aiVisibilityTools: McpToolDefinition[];
26
40
  export declare const aiVisibilityExecutors: Record<string, (input: unknown, context: ToolContext) => Promise<ToolResult>>;
27
41
  //# sourceMappingURL=ai-visibility.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai-visibility.d.ts","sourceRoot":"","sources":["../../src/tools/ai-visibility.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EACV,iBAAiB,EACjB,WAAW,EACX,UAAU,EAGX,MAAM,aAAa,CAAC;AAwIrB,eAAO,MAAM,mBAAmB,EAAE,iBAiBjC,CAAC;AAEF,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CA8GrB;AAYD,eAAO,MAAM,eAAe,EAAE,iBAoB7B,CAAC;AAEF,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CA8CrB;AAiBD,eAAO,MAAM,gBAAgB,EAAE,iBA8C9B,CAAC;AAEF,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CA8CrB;AAUD,eAAO,MAAM,aAAa,EAAE,iBAa3B,CAAC;AAEF,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAiErB;AAcD,eAAO,MAAM,gBAAgB,EAAE,iBAiC9B,CAAC;AAEF,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAoCrB;AAaD,eAAO,MAAM,kBAAkB,EAAE,iBAwBhC,CAAC;AAEF,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAwDrB;AAWD,eAAO,MAAM,aAAa,EAAE,iBAgB3B,CAAC;AAEF,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAsDrB;AAYD,eAAO,MAAM,eAAe,EAAE,iBAoB7B,CAAC;AAEF,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAoErB;AAoBD,eAAO,MAAM,kBAAkB,EAAE,iBAqBhC,CAAC;AAEF,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAqDrB;AAMD,eAAO,MAAM,iBAAiB,EAAE,iBAAiB,EAUhD,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,MAAM,CACxC,MAAM,EACN,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,UAAU,CAAC,CAW9D,CAAC"}
1
+ {"version":3,"file":"ai-visibility.d.ts","sourceRoot":"","sources":["../../src/tools/ai-visibility.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EACV,iBAAiB,EACjB,WAAW,EACX,UAAU,EAGX,MAAM,aAAa,CAAC;AAwIrB,eAAO,MAAM,mBAAmB,EAAE,iBAiBjC,CAAC;AAEF,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAmHrB;AA2HD,eAAO,MAAM,wBAAwB,EAAE,iBAmBtC,CAAC;AAEF,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAoHrB;AAYD,eAAO,MAAM,eAAe,EAAE,iBAoB7B,CAAC;AAEF,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CA8CrB;AAiBD,eAAO,MAAM,gBAAgB,EAAE,iBA8C9B,CAAC;AAEF,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CA8CrB;AAUD,eAAO,MAAM,aAAa,EAAE,iBAa3B,CAAC;AAEF,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAiErB;AAcD,eAAO,MAAM,gBAAgB,EAAE,iBAiC9B,CAAC;AAEF,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAoCrB;AAaD,eAAO,MAAM,kBAAkB,EAAE,iBAwBhC,CAAC;AAEF,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAwDrB;AAWD,eAAO,MAAM,aAAa,EAAE,iBAgB3B,CAAC;AAEF,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAsDrB;AAYD,eAAO,MAAM,eAAe,EAAE,iBAoB7B,CAAC;AAEF,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAoErB;AAoBD,eAAO,MAAM,kBAAkB,EAAE,iBAqBhC,CAAC;AAEF,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAqDrB;AA8BD,eAAO,MAAM,+BAA+B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAUlE,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAQnE;AAED,eAAO,MAAM,6BAA6B;;;;;;EAI/B,CAAC;AAEZ,eAAO,MAAM,sBAAsB,EAAE,iBAiBpC,CAAC;AAEF,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CA2FrB;AAMD,eAAO,MAAM,iBAAiB,EAAE,iBAAiB,EAYhD,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,MAAM,CACxC,MAAM,EACN,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,UAAU,CAAC,CAa9D,CAAC"}