@xano/developer-mcp 1.0.20 → 1.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -19
- package/dist/index.js +4 -227
- package/dist/meta_api_docs/format.d.ts +16 -1
- package/dist/meta_api_docs/format.js +24 -6
- package/dist/meta_api_docs/format.test.d.ts +1 -0
- package/dist/meta_api_docs/format.test.js +274 -0
- package/dist/meta_api_docs/index.test.d.ts +1 -0
- package/dist/meta_api_docs/index.test.js +128 -0
- package/dist/meta_api_docs/types.test.d.ts +1 -0
- package/dist/meta_api_docs/types.test.js +132 -0
- package/dist/run_api_docs/format.d.ts +1 -0
- package/dist/run_api_docs/format.js +3 -170
- package/dist/run_api_docs/format.test.d.ts +1 -0
- package/dist/run_api_docs/format.test.js +86 -0
- package/dist/run_api_docs/index.test.d.ts +1 -0
- package/dist/run_api_docs/index.test.js +127 -0
- package/dist/templates/init-workspace.js +4 -4
- package/dist/templates/xanoscript-index.d.ts +3 -1
- package/dist/templates/xanoscript-index.js +54 -51
- package/dist/xanoscript.d.ts +41 -0
- package/dist/xanoscript.js +261 -0
- package/dist/xanoscript.test.d.ts +1 -0
- package/dist/xanoscript.test.js +303 -0
- package/dist/xanoscript_docs/README.md +53 -37
- package/dist/xanoscript_docs/agents.md +1 -1
- package/dist/xanoscript_docs/apis.md +6 -3
- package/dist/xanoscript_docs/branch.md +239 -0
- package/dist/xanoscript_docs/functions.md +6 -6
- package/dist/xanoscript_docs/integrations.md +43 -1
- package/dist/xanoscript_docs/middleware.md +321 -0
- package/dist/xanoscript_docs/performance.md +1 -1
- package/dist/xanoscript_docs/realtime.md +113 -1
- package/dist/xanoscript_docs/tasks.md +2 -2
- package/dist/xanoscript_docs/tools.md +3 -3
- package/dist/xanoscript_docs/types.md +25 -8
- package/dist/xanoscript_docs/workspace.md +209 -0
- package/dist/xanoscript_docs_auto/README.md +119 -0
- package/dist/xanoscript_docs_auto/agents.md +446 -0
- package/dist/xanoscript_docs_auto/apis.md +517 -0
- package/dist/xanoscript_docs_auto/control-flow.md +543 -0
- package/dist/xanoscript_docs_auto/database.md +551 -0
- package/dist/xanoscript_docs_auto/debugging.md +527 -0
- package/dist/xanoscript_docs_auto/filters.md +464 -0
- package/dist/xanoscript_docs_auto/functions.md +431 -0
- package/dist/xanoscript_docs_auto/integrations.md +657 -0
- package/dist/xanoscript_docs_auto/mcp-servers.md +408 -0
- package/dist/xanoscript_docs_auto/operators.md +368 -0
- package/dist/xanoscript_docs_auto/syntax.md +287 -0
- package/dist/xanoscript_docs_auto/tables.md +447 -0
- package/dist/xanoscript_docs_auto/tasks.md +479 -0
- package/dist/xanoscript_docs_auto/testing.md +574 -0
- package/dist/xanoscript_docs_auto/tools.md +485 -0
- package/dist/xanoscript_docs_auto/triggers.md +595 -0
- package/dist/xanoscript_docs_auto/types.md +323 -0
- package/dist/xanoscript_docs_auto/variables.md +462 -0
- package/dist/xanoscript_docs_auto/version.json +5 -0
- package/package.json +6 -2
|
@@ -1,175 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Formatting utilities for Run API documentation output
|
|
3
|
+
* Re-exports the shared formatter with Run API configuration
|
|
3
4
|
*/
|
|
4
|
-
|
|
5
|
-
* Base URL information included with any topic that has endpoints
|
|
6
|
-
* NOTE: The Run API uses a FIXED base URL, not the user's Xano instance URL
|
|
7
|
-
*/
|
|
8
|
-
const BASE_URL_INFO = `## Base URL
|
|
9
|
-
\`\`\`
|
|
10
|
-
https://app.dev.xano.com/api:run/<endpoint>
|
|
11
|
-
\`\`\`
|
|
12
|
-
|
|
13
|
-
**Important:** This is a fixed URL - NOT your Xano instance URL. All Run API requests go to this central endpoint.
|
|
14
|
-
|
|
15
|
-
Authorization: \`Bearer <your-access-token>\`
|
|
16
|
-
`;
|
|
17
|
-
function formatParameter(param) {
|
|
18
|
-
const required = param.required ? " (required)" : "";
|
|
19
|
-
const defaultVal = param.default !== undefined ? ` [default: ${param.default}]` : "";
|
|
20
|
-
const enumVals = param.enum ? ` [options: ${param.enum.join(", ")}]` : "";
|
|
21
|
-
return ` - \`${param.name}\`: ${param.type}${required}${defaultVal}${enumVals} - ${param.description}`;
|
|
22
|
-
}
|
|
23
|
-
function formatEndpoint(ep, detailLevel) {
|
|
24
|
-
const lines = [];
|
|
25
|
-
// Method and path
|
|
26
|
-
lines.push(`### ${ep.method} ${ep.path}`);
|
|
27
|
-
if (ep.tool_name) {
|
|
28
|
-
lines.push(`**Tool:** \`${ep.tool_name}\``);
|
|
29
|
-
}
|
|
30
|
-
lines.push("");
|
|
31
|
-
lines.push(ep.description);
|
|
32
|
-
if (detailLevel === "overview") {
|
|
33
|
-
return lines.join("\n");
|
|
34
|
-
}
|
|
35
|
-
// Parameters
|
|
36
|
-
if (ep.parameters?.length) {
|
|
37
|
-
lines.push("");
|
|
38
|
-
lines.push("**Parameters:**");
|
|
39
|
-
for (const param of ep.parameters) {
|
|
40
|
-
lines.push(formatParameter(param));
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
// Request body
|
|
44
|
-
if (ep.request_body) {
|
|
45
|
-
lines.push("");
|
|
46
|
-
lines.push(`**Request Body:** \`${ep.request_body.type}\``);
|
|
47
|
-
if (ep.request_body.properties) {
|
|
48
|
-
for (const [key, val] of Object.entries(ep.request_body.properties)) {
|
|
49
|
-
const req = val.required ? " (required)" : "";
|
|
50
|
-
lines.push(` - \`${key}\`: ${val.type}${req} - ${val.description || ""}`);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
// Example (only in detailed/examples mode)
|
|
55
|
-
if (detailLevel === "examples" && ep.example) {
|
|
56
|
-
lines.push("");
|
|
57
|
-
lines.push("**Example:**");
|
|
58
|
-
lines.push("```");
|
|
59
|
-
lines.push(`${ep.example.method} ${ep.example.path}`);
|
|
60
|
-
if (ep.example.body) {
|
|
61
|
-
lines.push(JSON.stringify(ep.example.body, null, 2));
|
|
62
|
-
}
|
|
63
|
-
lines.push("```");
|
|
64
|
-
}
|
|
65
|
-
return lines.join("\n");
|
|
66
|
-
}
|
|
67
|
-
function formatExample(ex) {
|
|
68
|
-
const lines = [];
|
|
69
|
-
lines.push(`### ${ex.title}`);
|
|
70
|
-
lines.push("");
|
|
71
|
-
lines.push(ex.description);
|
|
72
|
-
lines.push("");
|
|
73
|
-
lines.push("**Request:**");
|
|
74
|
-
lines.push("```");
|
|
75
|
-
lines.push(`${ex.request.method} ${ex.request.path}`);
|
|
76
|
-
if (ex.request.headers) {
|
|
77
|
-
for (const [key, val] of Object.entries(ex.request.headers)) {
|
|
78
|
-
lines.push(`${key}: ${val}`);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
if (ex.request.body) {
|
|
82
|
-
lines.push("");
|
|
83
|
-
lines.push(JSON.stringify(ex.request.body, null, 2));
|
|
84
|
-
}
|
|
85
|
-
lines.push("```");
|
|
86
|
-
if (ex.response !== undefined) {
|
|
87
|
-
lines.push("");
|
|
88
|
-
lines.push("**Response:**");
|
|
89
|
-
lines.push("```json");
|
|
90
|
-
lines.push(JSON.stringify(ex.response, null, 2));
|
|
91
|
-
lines.push("```");
|
|
92
|
-
}
|
|
93
|
-
return lines.join("\n");
|
|
94
|
-
}
|
|
95
|
-
function formatPattern(pattern) {
|
|
96
|
-
const lines = [];
|
|
97
|
-
lines.push(`### ${pattern.name}`);
|
|
98
|
-
if (pattern.description) {
|
|
99
|
-
lines.push("");
|
|
100
|
-
lines.push(pattern.description);
|
|
101
|
-
}
|
|
102
|
-
lines.push("");
|
|
103
|
-
lines.push("**Steps:**");
|
|
104
|
-
for (const step of pattern.steps) {
|
|
105
|
-
lines.push(step);
|
|
106
|
-
}
|
|
107
|
-
if (pattern.example) {
|
|
108
|
-
lines.push("");
|
|
109
|
-
lines.push("**Example:**");
|
|
110
|
-
lines.push("```");
|
|
111
|
-
lines.push(pattern.example);
|
|
112
|
-
lines.push("```");
|
|
113
|
-
}
|
|
114
|
-
return lines.join("\n");
|
|
115
|
-
}
|
|
5
|
+
import { formatDocumentation as formatDoc, RUN_API_CONFIG, } from "../meta_api_docs/format.js";
|
|
116
6
|
export function formatDocumentation(doc, detailLevel = "detailed", includeSchemas = true) {
|
|
117
|
-
|
|
118
|
-
// Header
|
|
119
|
-
sections.push(`# ${doc.title}`);
|
|
120
|
-
sections.push("");
|
|
121
|
-
sections.push(doc.description);
|
|
122
|
-
// AI Hints (always include for AI optimization)
|
|
123
|
-
if (doc.ai_hints) {
|
|
124
|
-
sections.push("");
|
|
125
|
-
sections.push("## AI Usage Hints");
|
|
126
|
-
sections.push(doc.ai_hints);
|
|
127
|
-
}
|
|
128
|
-
// Include base URL info if topic has endpoints or patterns (workflows)
|
|
129
|
-
if (doc.endpoints?.length || doc.patterns?.length) {
|
|
130
|
-
sections.push("");
|
|
131
|
-
sections.push(BASE_URL_INFO);
|
|
132
|
-
}
|
|
133
|
-
// Endpoints
|
|
134
|
-
if (doc.endpoints?.length) {
|
|
135
|
-
sections.push("## Endpoints");
|
|
136
|
-
for (const ep of doc.endpoints) {
|
|
137
|
-
sections.push("");
|
|
138
|
-
sections.push(formatEndpoint(ep, detailLevel));
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
// Patterns/Workflows
|
|
142
|
-
if (doc.patterns?.length) {
|
|
143
|
-
sections.push("");
|
|
144
|
-
sections.push("## Workflows");
|
|
145
|
-
for (const pattern of doc.patterns) {
|
|
146
|
-
sections.push("");
|
|
147
|
-
sections.push(formatPattern(pattern));
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
// Examples
|
|
151
|
-
if ((detailLevel === "detailed" || detailLevel === "examples") && doc.examples?.length) {
|
|
152
|
-
sections.push("");
|
|
153
|
-
sections.push("## Examples");
|
|
154
|
-
for (const ex of doc.examples) {
|
|
155
|
-
sections.push("");
|
|
156
|
-
sections.push(formatExample(ex));
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
// Schemas
|
|
160
|
-
if (includeSchemas && doc.schemas && Object.keys(doc.schemas).length > 0) {
|
|
161
|
-
sections.push("");
|
|
162
|
-
sections.push("## Schemas");
|
|
163
|
-
sections.push("");
|
|
164
|
-
sections.push("```json");
|
|
165
|
-
sections.push(JSON.stringify(doc.schemas, null, 2));
|
|
166
|
-
sections.push("```");
|
|
167
|
-
}
|
|
168
|
-
// Related topics
|
|
169
|
-
if (doc.related_topics?.length) {
|
|
170
|
-
sections.push("");
|
|
171
|
-
sections.push("## Related Topics");
|
|
172
|
-
sections.push(`Use \`run_api_docs\` with topic: ${doc.related_topics.join(", ")}`);
|
|
173
|
-
}
|
|
174
|
-
return sections.join("\n");
|
|
7
|
+
return formatDoc(doc, detailLevel, includeSchemas, RUN_API_CONFIG);
|
|
175
8
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { formatDocumentation } from "./format.js";
|
|
3
|
+
describe("run_api_docs/format", () => {
|
|
4
|
+
describe("formatDocumentation", () => {
|
|
5
|
+
const minimalDoc = {
|
|
6
|
+
topic: "test",
|
|
7
|
+
title: "Test Topic",
|
|
8
|
+
description: "A test topic description",
|
|
9
|
+
};
|
|
10
|
+
it("should use Run API config by default", () => {
|
|
11
|
+
const docWithEndpoints = {
|
|
12
|
+
...minimalDoc,
|
|
13
|
+
endpoints: [
|
|
14
|
+
{
|
|
15
|
+
method: "GET",
|
|
16
|
+
path: "/test",
|
|
17
|
+
description: "Test endpoint",
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
};
|
|
21
|
+
const result = formatDocumentation(docWithEndpoints);
|
|
22
|
+
expect(result).toContain("https://app.dev.xano.com/api:run/");
|
|
23
|
+
expect(result).toContain("NOT your Xano instance URL");
|
|
24
|
+
});
|
|
25
|
+
it("should format documentation with title", () => {
|
|
26
|
+
const result = formatDocumentation(minimalDoc);
|
|
27
|
+
expect(result).toContain("# Test Topic");
|
|
28
|
+
});
|
|
29
|
+
it("should format documentation with description", () => {
|
|
30
|
+
const result = formatDocumentation(minimalDoc);
|
|
31
|
+
expect(result).toContain("A test topic description");
|
|
32
|
+
});
|
|
33
|
+
it("should respect detail level", () => {
|
|
34
|
+
const docWithExamples = {
|
|
35
|
+
...minimalDoc,
|
|
36
|
+
examples: [
|
|
37
|
+
{
|
|
38
|
+
title: "Example",
|
|
39
|
+
description: "Test",
|
|
40
|
+
request: { method: "GET", path: "/test" },
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
const overviewResult = formatDocumentation(docWithExamples, "overview");
|
|
45
|
+
expect(overviewResult).not.toContain("## Examples");
|
|
46
|
+
const detailedResult = formatDocumentation(docWithExamples, "detailed");
|
|
47
|
+
expect(detailedResult).toContain("## Examples");
|
|
48
|
+
});
|
|
49
|
+
it("should use run_api_docs in related topics", () => {
|
|
50
|
+
const docWithRelated = {
|
|
51
|
+
...minimalDoc,
|
|
52
|
+
related_topics: ["session", "history"],
|
|
53
|
+
};
|
|
54
|
+
const result = formatDocumentation(docWithRelated);
|
|
55
|
+
expect(result).toContain("run_api_docs");
|
|
56
|
+
expect(result).toContain("session, history");
|
|
57
|
+
});
|
|
58
|
+
it("should default to detailed level", () => {
|
|
59
|
+
const docWithEndpoints = {
|
|
60
|
+
...minimalDoc,
|
|
61
|
+
endpoints: [
|
|
62
|
+
{
|
|
63
|
+
method: "GET",
|
|
64
|
+
path: "/test",
|
|
65
|
+
description: "Test",
|
|
66
|
+
parameters: [
|
|
67
|
+
{ name: "id", type: "string", description: "ID" },
|
|
68
|
+
],
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
};
|
|
72
|
+
const result = formatDocumentation(docWithEndpoints);
|
|
73
|
+
expect(result).toContain("**Parameters:**");
|
|
74
|
+
});
|
|
75
|
+
it("should default to including schemas", () => {
|
|
76
|
+
const docWithSchemas = {
|
|
77
|
+
...minimalDoc,
|
|
78
|
+
schemas: {
|
|
79
|
+
TestSchema: { type: "object" },
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
const result = formatDocumentation(docWithSchemas);
|
|
83
|
+
expect(result).toContain("## Schemas");
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { topics, getTopicNames, getTopicDescriptions, handleRunApiDocs, runApiDocsToolDefinition, } from "./index.js";
|
|
3
|
+
describe("run_api_docs/index", () => {
|
|
4
|
+
describe("topics", () => {
|
|
5
|
+
it("should have all expected topics", () => {
|
|
6
|
+
const expectedTopics = [
|
|
7
|
+
"start",
|
|
8
|
+
"run",
|
|
9
|
+
"session",
|
|
10
|
+
"history",
|
|
11
|
+
"data",
|
|
12
|
+
"workflows",
|
|
13
|
+
];
|
|
14
|
+
expect(Object.keys(topics)).toEqual(expectedTopics);
|
|
15
|
+
});
|
|
16
|
+
it("should have valid TopicDoc structure for each topic", () => {
|
|
17
|
+
for (const [key, doc] of Object.entries(topics)) {
|
|
18
|
+
expect(doc).toHaveProperty("topic");
|
|
19
|
+
expect(doc).toHaveProperty("title");
|
|
20
|
+
expect(doc).toHaveProperty("description");
|
|
21
|
+
expect(typeof doc.topic).toBe("string");
|
|
22
|
+
expect(typeof doc.title).toBe("string");
|
|
23
|
+
expect(typeof doc.description).toBe("string");
|
|
24
|
+
expect(doc.topic).toBe(key);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
describe("getTopicNames", () => {
|
|
29
|
+
it("should return all topic names", () => {
|
|
30
|
+
const names = getTopicNames();
|
|
31
|
+
expect(names).toEqual(Object.keys(topics));
|
|
32
|
+
});
|
|
33
|
+
it("should return an array of strings", () => {
|
|
34
|
+
const names = getTopicNames();
|
|
35
|
+
expect(Array.isArray(names)).toBe(true);
|
|
36
|
+
names.forEach((name) => {
|
|
37
|
+
expect(typeof name).toBe("string");
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe("getTopicDescriptions", () => {
|
|
42
|
+
it("should return formatted topic descriptions", () => {
|
|
43
|
+
const descriptions = getTopicDescriptions();
|
|
44
|
+
expect(typeof descriptions).toBe("string");
|
|
45
|
+
expect(descriptions).toContain("- start:");
|
|
46
|
+
expect(descriptions).toContain("- run:");
|
|
47
|
+
expect(descriptions).toContain("- session:");
|
|
48
|
+
});
|
|
49
|
+
it("should include all topics", () => {
|
|
50
|
+
const descriptions = getTopicDescriptions();
|
|
51
|
+
for (const key of Object.keys(topics)) {
|
|
52
|
+
expect(descriptions).toContain(`- ${key}:`);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
describe("handleRunApiDocs", () => {
|
|
57
|
+
it("should return error for undefined topic", () => {
|
|
58
|
+
const result = handleRunApiDocs(undefined);
|
|
59
|
+
expect(result).toContain('Error: Unknown topic "undefined"');
|
|
60
|
+
expect(result).toContain("Available topics:");
|
|
61
|
+
});
|
|
62
|
+
it("should return error for unknown topic", () => {
|
|
63
|
+
const result = handleRunApiDocs("nonexistent");
|
|
64
|
+
expect(result).toContain('Error: Unknown topic "nonexistent"');
|
|
65
|
+
expect(result).toContain("Available topics:");
|
|
66
|
+
});
|
|
67
|
+
it("should return documentation for valid topic", () => {
|
|
68
|
+
const result = handleRunApiDocs("start");
|
|
69
|
+
expect(result).not.toContain("Error:");
|
|
70
|
+
});
|
|
71
|
+
it("should return run documentation", () => {
|
|
72
|
+
const result = handleRunApiDocs("run");
|
|
73
|
+
expect(result).toContain("Run Execution");
|
|
74
|
+
expect(result).toContain("/run/exec");
|
|
75
|
+
});
|
|
76
|
+
it("should return session documentation", () => {
|
|
77
|
+
const result = handleRunApiDocs("session");
|
|
78
|
+
expect(result).toContain("Session");
|
|
79
|
+
});
|
|
80
|
+
it("should use default detail_level of detailed", () => {
|
|
81
|
+
const result = handleRunApiDocs("run");
|
|
82
|
+
expect(result).toContain("**Parameters:**");
|
|
83
|
+
});
|
|
84
|
+
it("should respect overview detail_level", () => {
|
|
85
|
+
const result = handleRunApiDocs("run", "overview");
|
|
86
|
+
expect(result).toContain("Run Execution");
|
|
87
|
+
});
|
|
88
|
+
it("should respect examples detail_level", () => {
|
|
89
|
+
const result = handleRunApiDocs("run", "examples");
|
|
90
|
+
expect(result).toContain("**Example:**");
|
|
91
|
+
});
|
|
92
|
+
it("should include schemas by default", () => {
|
|
93
|
+
const result = handleRunApiDocs("run");
|
|
94
|
+
expect(result).toContain("## Schemas");
|
|
95
|
+
});
|
|
96
|
+
it("should exclude schemas when includeSchemas is false", () => {
|
|
97
|
+
const result = handleRunApiDocs("run", "detailed", false);
|
|
98
|
+
expect(result).not.toContain("## Schemas");
|
|
99
|
+
});
|
|
100
|
+
it("should use Run API base URL", () => {
|
|
101
|
+
const result = handleRunApiDocs("run");
|
|
102
|
+
expect(result).toContain("https://app.dev.xano.com/api:run/");
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe("runApiDocsToolDefinition", () => {
|
|
106
|
+
it("should have required tool properties", () => {
|
|
107
|
+
expect(runApiDocsToolDefinition).toHaveProperty("name", "run_api_docs");
|
|
108
|
+
expect(runApiDocsToolDefinition).toHaveProperty("description");
|
|
109
|
+
expect(runApiDocsToolDefinition).toHaveProperty("inputSchema");
|
|
110
|
+
});
|
|
111
|
+
it("should mention fixed base URL in description", () => {
|
|
112
|
+
expect(runApiDocsToolDefinition.description).toContain("https://app.dev.xano.com/api:run/");
|
|
113
|
+
});
|
|
114
|
+
it("should have valid inputSchema", () => {
|
|
115
|
+
const schema = runApiDocsToolDefinition.inputSchema;
|
|
116
|
+
expect(schema.type).toBe("object");
|
|
117
|
+
expect(schema.properties).toHaveProperty("topic");
|
|
118
|
+
expect(schema.properties).toHaveProperty("detail_level");
|
|
119
|
+
expect(schema.properties).toHaveProperty("include_schemas");
|
|
120
|
+
expect(schema.required).toEqual(["topic"]);
|
|
121
|
+
});
|
|
122
|
+
it("should include all topic names in enum", () => {
|
|
123
|
+
const topicEnum = runApiDocsToolDefinition.inputSchema.properties.topic.enum;
|
|
124
|
+
expect(topicEnum).toEqual(getTopicNames());
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
});
|
|
@@ -260,10 +260,10 @@ const response = await fetch(
|
|
|
260
260
|
For writing XanoScript code, use:
|
|
261
261
|
|
|
262
262
|
- \`xanoscript_docs()\` - Full documentation index
|
|
263
|
-
- \`xanoscript_docs({
|
|
264
|
-
- \`xanoscript_docs({
|
|
265
|
-
- \`xanoscript_docs({
|
|
266
|
-
- \`xanoscript_docs({
|
|
263
|
+
- \`xanoscript_docs({ topic: "functions" })\` - Function syntax
|
|
264
|
+
- \`xanoscript_docs({ topic: "tables" })\` - Table schema syntax
|
|
265
|
+
- \`xanoscript_docs({ topic: "apis" })\` - API endpoint syntax
|
|
266
|
+
- \`xanoscript_docs({ topic: "syntax" })\` - Language reference
|
|
267
267
|
|
|
268
268
|
## Validating XanoScript
|
|
269
269
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Template for xanoscript_docs index documentation
|
|
3
3
|
* Edit this file to update the XanoScript documentation index
|
|
4
|
+
*
|
|
5
|
+
* NOTE: This template is currently unused. The actual documentation is served
|
|
6
|
+
* directly from the XANOSCRIPT_DOCS_V2 config in index.ts.
|
|
4
7
|
*/
|
|
5
8
|
export interface XanoscriptIndexParams {
|
|
6
9
|
version: string;
|
|
7
|
-
aliasLookup: Record<string, string[]>;
|
|
8
10
|
}
|
|
9
11
|
export declare function generateXanoscriptIndexTemplate(params: XanoscriptIndexParams): string;
|
|
@@ -1,69 +1,72 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Template for xanoscript_docs index documentation
|
|
3
3
|
* Edit this file to update the XanoScript documentation index
|
|
4
|
+
*
|
|
5
|
+
* NOTE: This template is currently unused. The actual documentation is served
|
|
6
|
+
* directly from the XANOSCRIPT_DOCS_V2 config in index.ts.
|
|
4
7
|
*/
|
|
5
8
|
export function generateXanoscriptIndexTemplate(params) {
|
|
6
|
-
const { version
|
|
7
|
-
const formatRow = (keyword, description) => {
|
|
8
|
-
const aliases = aliasLookup[keyword]?.slice(0, 3).join(", ") || "";
|
|
9
|
-
return `| \`${keyword}\` | ${aliases ? aliases : "-"} | ${description} |`;
|
|
10
|
-
};
|
|
9
|
+
const { version } = params;
|
|
11
10
|
return `# XanoScript Documentation Index
|
|
12
11
|
Version: ${version}
|
|
13
12
|
|
|
14
|
-
Use \`xanoscript_docs
|
|
13
|
+
Use \`xanoscript_docs({ topic: "<topic>" })\` to retrieve documentation.
|
|
15
14
|
|
|
16
|
-
## Core
|
|
17
|
-
|
|
15
|
+
## Core Language
|
|
16
|
+
| Topic | Description |
|
|
17
|
+
|-------|-------------|
|
|
18
|
+
| \`syntax\` | Expressions, operators, filters, system variables |
|
|
19
|
+
| \`types\` | Data types, validation, input blocks |
|
|
20
|
+
| \`functions\` | Reusable function stacks, async, loops |
|
|
21
|
+
| \`schema\` | Runtime schema parsing and validation |
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
${formatRow("tool", "AI-callable tools in `tools/`")}
|
|
27
|
-
${formatRow("agent", "AI agents in `agents/`")}
|
|
28
|
-
${formatRow("mcp_server", "MCP servers in `mcp_servers/`")}
|
|
23
|
+
## Data
|
|
24
|
+
| Topic | Description |
|
|
25
|
+
|-------|-------------|
|
|
26
|
+
| \`tables\` | Database schema definitions with indexes and relationships |
|
|
27
|
+
| \`database\` | All db.* operations: query, get, add, edit, patch, delete |
|
|
28
|
+
| \`addons\` | Reusable subqueries for fetching related data |
|
|
29
|
+
| \`streaming\` | Streaming data from files, requests, and responses |
|
|
29
30
|
|
|
30
|
-
##
|
|
31
|
-
|
|
31
|
+
## APIs & Endpoints
|
|
32
|
+
| Topic | Description |
|
|
33
|
+
|-------|-------------|
|
|
34
|
+
| \`apis\` | HTTP endpoint definitions with authentication and CRUD patterns |
|
|
35
|
+
| \`tasks\` | Scheduled and cron jobs |
|
|
36
|
+
| \`triggers\` | Event-driven handlers (table, realtime, workspace, agent, MCP) |
|
|
37
|
+
| \`realtime\` | Real-time channels and events for push updates |
|
|
32
38
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
${formatRow("query_filter", "WHERE clause and filter syntax")}
|
|
39
|
+
## AI & Agents
|
|
40
|
+
| Topic | Description |
|
|
41
|
+
|-------|-------------|
|
|
42
|
+
| \`agents\` | AI agent configuration with LLM providers and tools |
|
|
43
|
+
| \`tools\` | AI tools for agents and MCP servers |
|
|
44
|
+
| \`mcp-servers\` | MCP server definitions exposing tools |
|
|
40
45
|
|
|
41
|
-
##
|
|
42
|
-
|
|
46
|
+
## Integrations
|
|
47
|
+
| Topic | Description |
|
|
48
|
+
|-------|-------------|
|
|
49
|
+
| \`integrations\` | Cloud storage, Redis, security, and external APIs |
|
|
43
50
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
${formatRow("task_workflow", "AI workflow for creating tasks")}
|
|
51
|
+
## Configuration
|
|
52
|
+
| Topic | Description |
|
|
53
|
+
|-------|-------------|
|
|
54
|
+
| \`workspace\` | Workspace-level settings: environment variables, preferences, realtime |
|
|
55
|
+
| \`branch\` | Branch-level settings: middleware, history retention, visual styling |
|
|
56
|
+
| \`middleware\` | Request/response interceptors for functions, queries, tasks, and tools |
|
|
51
57
|
|
|
52
|
-
##
|
|
58
|
+
## Development
|
|
59
|
+
| Topic | Description |
|
|
60
|
+
|-------|-------------|
|
|
61
|
+
| \`testing\` | Unit tests, mocks, and assertions |
|
|
62
|
+
| \`debugging\` | Logging, inspecting, and debugging XanoScript execution |
|
|
63
|
+
| \`frontend\` | Static frontend development and deployment |
|
|
64
|
+
| \`run\` | Run job and service configurations for the Xano Job Runner |
|
|
53
65
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
${formatRow("lovable", "Building from Lovable-generated websites")}
|
|
60
|
-
${formatRow("performance", "Performance optimization best practices")}
|
|
61
|
-
${formatRow("realtime", "Real-time channels and events")}
|
|
62
|
-
${formatRow("schema", "Runtime schema parsing and validation")}
|
|
63
|
-
${formatRow("security", "Security best practices")}
|
|
64
|
-
${formatRow("streaming", "Streaming data from files and responses")}
|
|
65
|
-
${formatRow("testing", "Unit testing XanoScript code")}
|
|
66
|
-
${formatRow("tips", "Tips and tricks")}
|
|
67
|
-
${formatRow("run", "Run job and service configurations")}
|
|
66
|
+
## Best Practices
|
|
67
|
+
| Topic | Description |
|
|
68
|
+
|-------|-------------|
|
|
69
|
+
| \`performance\` | Performance optimization best practices |
|
|
70
|
+
| \`security\` | Security best practices for authentication and authorization |
|
|
68
71
|
`;
|
|
69
72
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XanoScript Documentation Module
|
|
3
|
+
*
|
|
4
|
+
* This module contains the core logic for XanoScript documentation
|
|
5
|
+
* handling, separated from the MCP server for testability.
|
|
6
|
+
*/
|
|
7
|
+
export interface DocConfig {
|
|
8
|
+
file: string;
|
|
9
|
+
applyTo: string[];
|
|
10
|
+
description: string;
|
|
11
|
+
}
|
|
12
|
+
export interface XanoscriptDocsArgs {
|
|
13
|
+
topic?: string;
|
|
14
|
+
file_path?: string;
|
|
15
|
+
mode?: "full" | "quick_reference";
|
|
16
|
+
}
|
|
17
|
+
export declare const XANOSCRIPT_DOCS_V2: Record<string, DocConfig>;
|
|
18
|
+
/**
|
|
19
|
+
* Get list of topics that apply to a given file path based on applyTo patterns
|
|
20
|
+
*/
|
|
21
|
+
export declare function getDocsForFilePath(filePath: string): string[];
|
|
22
|
+
/**
|
|
23
|
+
* Extract just the Quick Reference section from a doc
|
|
24
|
+
*/
|
|
25
|
+
export declare function extractQuickReference(content: string, topic: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Get the documentation version from the version.json file
|
|
28
|
+
*/
|
|
29
|
+
export declare function getXanoscriptDocsVersion(docsPath: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Read XanoScript documentation with v2 structure
|
|
32
|
+
*/
|
|
33
|
+
export declare function readXanoscriptDocsV2(docsPath: string, args?: XanoscriptDocsArgs): string;
|
|
34
|
+
/**
|
|
35
|
+
* Get available topic names
|
|
36
|
+
*/
|
|
37
|
+
export declare function getTopicNames(): string[];
|
|
38
|
+
/**
|
|
39
|
+
* Get topic descriptions for documentation
|
|
40
|
+
*/
|
|
41
|
+
export declare function getTopicDescriptions(): string;
|