@xano/developer-mcp 1.0.57 → 1.0.59
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 +15 -0
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/xanoscript_docs.d.ts +9 -0
- package/dist/tools/xanoscript_docs.js +27 -0
- package/dist/xanoscript.d.ts +5 -1
- package/dist/xanoscript.js +70 -6
- package/dist/xanoscript.test.js +5 -3
- package/dist/xanoscript_docs/README.md +9 -43
- package/dist/xanoscript_docs/addons.md +0 -2
- package/dist/xanoscript_docs/agents.md +2 -35
- package/dist/xanoscript_docs/apis.md +3 -6
- package/dist/xanoscript_docs/branch.md +0 -2
- package/dist/xanoscript_docs/database.md +3 -7
- package/dist/xanoscript_docs/debugging.md +1 -264
- package/dist/xanoscript_docs/docs_index.json +22 -0
- package/dist/xanoscript_docs/essentials.md +1 -9
- package/dist/xanoscript_docs/frontend.md +1 -138
- package/dist/xanoscript_docs/functions.md +3 -7
- package/dist/xanoscript_docs/mcp-servers.md +1 -2
- package/dist/xanoscript_docs/middleware.md +1 -3
- package/dist/xanoscript_docs/performance.md +8 -198
- package/dist/xanoscript_docs/realtime.md +11 -161
- package/dist/xanoscript_docs/run.md +2 -184
- package/dist/xanoscript_docs/schema.md +1 -3
- package/dist/xanoscript_docs/security.md +82 -313
- package/dist/xanoscript_docs/streaming.md +2 -37
- package/dist/xanoscript_docs/survival.md +161 -0
- package/dist/xanoscript_docs/syntax.md +0 -6
- package/dist/xanoscript_docs/tables.md +3 -5
- package/dist/xanoscript_docs/tasks.md +1 -3
- package/dist/xanoscript_docs/tools.md +1 -3
- package/dist/xanoscript_docs/triggers.md +3 -69
- package/dist/xanoscript_docs/types.md +3 -4
- package/dist/xanoscript_docs/unit-testing.md +1 -55
- package/dist/xanoscript_docs/workflow-tests.md +8 -35
- package/dist/xanoscript_docs/working.md +667 -0
- package/dist/xanoscript_docs/workspace.md +0 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -339,12 +339,16 @@ Retrieves XanoScript programming language documentation with context-aware suppo
|
|
|
339
339
|
| `topic` | string | No | Specific documentation topic to retrieve |
|
|
340
340
|
| `file_path` | string | No | File path being edited for context-aware docs (e.g., `api/users/create_post.xs`) |
|
|
341
341
|
| `mode` | string | No | `full` (default), `quick_reference` for compact syntax reference, or `index` for topic listing with sizes |
|
|
342
|
+
| `tier` | string | No | Pre-packaged documentation tier for context-limited models: `survival` (~800 tokens) or `working` (~3500 tokens). Overrides topic/file_path/mode when set |
|
|
343
|
+
| `max_tokens` | number | No | Maximum estimated token budget. Loads topics in priority order until budget is reached. Helps prevent context overflow for small-window models |
|
|
342
344
|
| `exclude_topics` | string[] | No | Topic names to exclude from `file_path` results (e.g., topics already loaded) |
|
|
343
345
|
|
|
344
346
|
**Available Topics:**
|
|
345
347
|
|
|
346
348
|
| Topic | Description |
|
|
347
349
|
|-------|-------------|
|
|
350
|
+
| `survival` | Minimal syntax survival kit (~3KB, ~800 tokens) for models with <16K context |
|
|
351
|
+
| `working` | Complete working reference (~12KB, ~3500 tokens) for models with 16-64K context |
|
|
348
352
|
| `readme` | XanoScript overview, workspace structure, and quick reference |
|
|
349
353
|
| `essentials` | Common patterns, quick reference, and common mistakes to avoid |
|
|
350
354
|
| `syntax` | Expressions, operators, and filters for all XanoScript code |
|
|
@@ -387,6 +391,12 @@ Retrieves XanoScript programming language documentation with context-aware suppo
|
|
|
387
391
|
// Get overview
|
|
388
392
|
xanoscript_docs()
|
|
389
393
|
|
|
394
|
+
// Get survival kit for small context models (~800 tokens)
|
|
395
|
+
xanoscript_docs({ tier: "survival" })
|
|
396
|
+
|
|
397
|
+
// Get working reference for medium context models (~3500 tokens)
|
|
398
|
+
xanoscript_docs({ tier: "working" })
|
|
399
|
+
|
|
390
400
|
// Get essentials (recommended first stop)
|
|
391
401
|
xanoscript_docs({ topic: "essentials" })
|
|
392
402
|
|
|
@@ -396,6 +406,9 @@ xanoscript_docs({ topic: "functions" })
|
|
|
396
406
|
// Discover available topics with sizes
|
|
397
407
|
xanoscript_docs({ mode: "index" })
|
|
398
408
|
|
|
409
|
+
// Budget-aware: load docs up to token limit
|
|
410
|
+
xanoscript_docs({ file_path: "api/users/create_post.xs", max_tokens: 2000 })
|
|
411
|
+
|
|
399
412
|
// Context-aware: get all docs relevant to file being edited
|
|
400
413
|
xanoscript_docs({ file_path: "api/users/create_post.xs" })
|
|
401
414
|
|
|
@@ -516,6 +529,8 @@ The server also exposes XanoScript documentation as MCP resources for direct acc
|
|
|
516
529
|
|
|
517
530
|
| Resource URI | Description |
|
|
518
531
|
|--------------|-------------|
|
|
532
|
+
| `xanoscript://docs/survival` | Minimal syntax survival kit (~800 tokens) |
|
|
533
|
+
| `xanoscript://docs/working` | Complete working reference (~3500 tokens) |
|
|
519
534
|
| `xanoscript://docs/readme` | Overview and quick reference |
|
|
520
535
|
| `xanoscript://docs/essentials` | Common patterns, quick reference, and common mistakes to avoid |
|
|
521
536
|
| `xanoscript://docs/syntax` | Expressions, operators, and filters |
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -118,6 +118,15 @@ export declare const toolDefinitions: ({
|
|
|
118
118
|
enum: string[];
|
|
119
119
|
description: string;
|
|
120
120
|
};
|
|
121
|
+
tier: {
|
|
122
|
+
type: string;
|
|
123
|
+
enum: string[];
|
|
124
|
+
description: string;
|
|
125
|
+
};
|
|
126
|
+
max_tokens: {
|
|
127
|
+
type: string;
|
|
128
|
+
description: string;
|
|
129
|
+
};
|
|
121
130
|
exclude_topics: {
|
|
122
131
|
type: string;
|
|
123
132
|
items: {
|
|
@@ -76,6 +76,15 @@ export declare const xanoscriptDocsToolDefinition: {
|
|
|
76
76
|
enum: string[];
|
|
77
77
|
description: string;
|
|
78
78
|
};
|
|
79
|
+
tier: {
|
|
80
|
+
type: string;
|
|
81
|
+
enum: string[];
|
|
82
|
+
description: string;
|
|
83
|
+
};
|
|
84
|
+
max_tokens: {
|
|
85
|
+
type: string;
|
|
86
|
+
description: string;
|
|
87
|
+
};
|
|
79
88
|
exclude_topics: {
|
|
80
89
|
type: string;
|
|
81
90
|
items: {
|
|
@@ -92,6 +92,15 @@ export function xanoscriptDocs(args) {
|
|
|
92
92
|
export function xanoscriptDocsTool(args) {
|
|
93
93
|
try {
|
|
94
94
|
const docsPath = getXanoscriptDocsPath();
|
|
95
|
+
// Tier mode: return single content block for pre-built tiers
|
|
96
|
+
if (args?.tier) {
|
|
97
|
+
const result = xanoscriptDocs(args);
|
|
98
|
+
return {
|
|
99
|
+
success: true,
|
|
100
|
+
data: result.documentation,
|
|
101
|
+
structuredContent: { tier: args.tier, documentation: result.documentation },
|
|
102
|
+
};
|
|
103
|
+
}
|
|
95
104
|
// file_path mode: return structured multi-content (one block per topic)
|
|
96
105
|
if (args?.file_path) {
|
|
97
106
|
const version = getXanoscriptDocsVersion(docsPath);
|
|
@@ -139,8 +148,10 @@ export const xanoscriptDocsToolDefinition = {
|
|
|
139
148
|
name: "xanoscript_docs",
|
|
140
149
|
description: "Get XanoScript programming language documentation for AI code generation. " +
|
|
141
150
|
"Call without parameters for overview (README). " +
|
|
151
|
+
"For context-limited models: use tier='survival' (~800 tokens) or tier='working' (~3500 tokens). " +
|
|
142
152
|
"Use 'topic' for specific documentation, or 'file_path' for context-aware docs based on the file you're editing. " +
|
|
143
153
|
"Use mode='quick_reference' for compact syntax reference (recommended for context efficiency). " +
|
|
154
|
+
"Use max_tokens to limit documentation size to fit your context budget. " +
|
|
144
155
|
"file_path mode defaults to 'quick_reference' to reduce context size; use mode='full' to get complete docs.",
|
|
145
156
|
annotations: {
|
|
146
157
|
readOnlyHint: true,
|
|
@@ -175,6 +186,22 @@ export const xanoscriptDocsToolDefinition = {
|
|
|
175
186
|
"Use 'quick_reference' to save context window space when you just need a reminder. " +
|
|
176
187
|
"Default: 'full' for topic mode, 'quick_reference' for file_path mode.",
|
|
177
188
|
},
|
|
189
|
+
tier: {
|
|
190
|
+
type: "string",
|
|
191
|
+
enum: ["survival", "working"],
|
|
192
|
+
description: "Pre-packaged documentation tier for context-limited models. " +
|
|
193
|
+
"'survival' (~3KB, ~800 tokens): minimum syntax to write valid XanoScript. " +
|
|
194
|
+
"'working' (~12KB, ~3500 tokens): complete reference for common tasks. " +
|
|
195
|
+
"Overrides topic/file_path/mode when set. " +
|
|
196
|
+
"Use 'survival' for models with <16K context, 'working' for 16-64K context.",
|
|
197
|
+
},
|
|
198
|
+
max_tokens: {
|
|
199
|
+
type: "number",
|
|
200
|
+
description: "Maximum estimated token budget for documentation. " +
|
|
201
|
+
"When used with file_path, loads topics in priority order until budget is reached. " +
|
|
202
|
+
"Helps prevent context overflow for small-window models. " +
|
|
203
|
+
"Estimate: 1KB of docs ≈ 250 tokens.",
|
|
204
|
+
},
|
|
178
205
|
exclude_topics: {
|
|
179
206
|
type: "array",
|
|
180
207
|
items: { type: "string" },
|
package/dist/xanoscript.d.ts
CHANGED
|
@@ -8,11 +8,14 @@ export interface DocConfig {
|
|
|
8
8
|
file: string;
|
|
9
9
|
applyTo: string[];
|
|
10
10
|
description: string;
|
|
11
|
+
priority?: number;
|
|
11
12
|
}
|
|
12
13
|
export interface XanoscriptDocsArgs {
|
|
13
14
|
topic?: string;
|
|
14
15
|
file_path?: string;
|
|
15
16
|
mode?: "full" | "quick_reference" | "index";
|
|
17
|
+
tier?: "survival" | "working";
|
|
18
|
+
max_tokens?: number;
|
|
16
19
|
exclude_topics?: string[];
|
|
17
20
|
}
|
|
18
21
|
export declare const XANOSCRIPT_DOCS_V2: Record<string, DocConfig>;
|
|
@@ -26,7 +29,8 @@ export declare function clearDocsCache(): void;
|
|
|
26
29
|
*/
|
|
27
30
|
export declare function getDocsForFilePath(filePath: string): string[];
|
|
28
31
|
/**
|
|
29
|
-
* Extract
|
|
32
|
+
* Extract the Quick Reference section plus critical sections
|
|
33
|
+
* (Common Mistakes, Decision/Choosing trees) from a doc.
|
|
30
34
|
*/
|
|
31
35
|
export declare function extractQuickReference(content: string, topic: string): string;
|
|
32
36
|
/**
|
package/dist/xanoscript.js
CHANGED
|
@@ -18,6 +18,7 @@ function buildDocsConfig() {
|
|
|
18
18
|
file: topic.file,
|
|
19
19
|
applyTo: topic.applyTo,
|
|
20
20
|
description: topic.description,
|
|
21
|
+
priority: topic.priority,
|
|
21
22
|
};
|
|
22
23
|
}
|
|
23
24
|
return config;
|
|
@@ -69,7 +70,8 @@ export function getDocsForFilePath(filePath) {
|
|
|
69
70
|
return matches;
|
|
70
71
|
}
|
|
71
72
|
/**
|
|
72
|
-
* Extract
|
|
73
|
+
* Extract the Quick Reference section plus critical sections
|
|
74
|
+
* (Common Mistakes, Decision/Choosing trees) from a doc.
|
|
73
75
|
*/
|
|
74
76
|
export function extractQuickReference(content, topic) {
|
|
75
77
|
const lines = content.split("\n");
|
|
@@ -83,9 +85,21 @@ export function extractQuickReference(content, topic) {
|
|
|
83
85
|
let endIdx = lines.findIndex((l, i) => i > startIdx && l.startsWith("## "));
|
|
84
86
|
if (endIdx === -1)
|
|
85
87
|
endIdx = lines.length;
|
|
88
|
+
const sections = [lines.slice(startIdx, endIdx).join("\n")];
|
|
89
|
+
// Also extract Common Mistakes and Decision/Choosing sections if present
|
|
90
|
+
const bonusSections = ["## Common Mistakes", "## Choosing", "## Decision"];
|
|
91
|
+
for (const sectionName of bonusSections) {
|
|
92
|
+
const sIdx = lines.findIndex((l) => l.startsWith(sectionName));
|
|
93
|
+
if (sIdx !== -1 && sIdx !== startIdx) {
|
|
94
|
+
let eIdx = lines.findIndex((l, i) => i > sIdx && l.startsWith("## "));
|
|
95
|
+
if (eIdx === -1)
|
|
96
|
+
eIdx = lines.length;
|
|
97
|
+
sections.push(lines.slice(sIdx, eIdx).join("\n"));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
86
100
|
// Include topic header for context
|
|
87
101
|
const header = `# ${topic}\n\n`;
|
|
88
|
-
return header +
|
|
102
|
+
return header + sections.join("\n\n---\n\n");
|
|
89
103
|
}
|
|
90
104
|
/**
|
|
91
105
|
* Get the documentation version from the version.json file
|
|
@@ -109,7 +123,13 @@ export function getXanoscriptDocsVersion(docsPath) {
|
|
|
109
123
|
*/
|
|
110
124
|
export function readXanoscriptDocsV2(docsPath, args) {
|
|
111
125
|
const version = getXanoscriptDocsVersion(docsPath);
|
|
112
|
-
//
|
|
126
|
+
// Tier mode: return pre-built documentation tier
|
|
127
|
+
if (args?.tier) {
|
|
128
|
+
const tierFile = args.tier === "survival" ? "survival.md" : "working.md";
|
|
129
|
+
const content = cachedReadFile(join(docsPath, tierFile));
|
|
130
|
+
return `${content}\n\n---\nDocumentation version: ${version}`;
|
|
131
|
+
}
|
|
132
|
+
// Index mode: return compact topic listing with byte sizes and token estimates
|
|
113
133
|
if (args?.mode === "index") {
|
|
114
134
|
const rows = Object.entries(XANOSCRIPT_DOCS_V2).map(([name, config]) => {
|
|
115
135
|
let size;
|
|
@@ -120,7 +140,8 @@ export function readXanoscriptDocsV2(docsPath, args) {
|
|
|
120
140
|
size = 0;
|
|
121
141
|
}
|
|
122
142
|
const sizeKb = (size / 1024).toFixed(1);
|
|
123
|
-
|
|
143
|
+
const estTokens = Math.ceil(size / 4);
|
|
144
|
+
return `| ${name} | ${config.description} | ${sizeKb} KB | ~${estTokens} |`;
|
|
124
145
|
});
|
|
125
146
|
return [
|
|
126
147
|
`# XanoScript Documentation Index`,
|
|
@@ -128,11 +149,12 @@ export function readXanoscriptDocsV2(docsPath, args) {
|
|
|
128
149
|
`Version: ${version}`,
|
|
129
150
|
`Topics: ${rows.length}`,
|
|
130
151
|
``,
|
|
131
|
-
`| Topic | Description | Size |`,
|
|
132
|
-
|
|
152
|
+
`| Topic | Description | Size | Est. Tokens |`,
|
|
153
|
+
`|-------|-------------|------|-------------|`,
|
|
133
154
|
...rows,
|
|
134
155
|
``,
|
|
135
156
|
`Use topic='<name>' to load a specific topic. Use mode='quick_reference' for compact output.`,
|
|
157
|
+
`Use tier='survival' (~800 tokens) or tier='working' (~3500 tokens) for context-limited models.`,
|
|
136
158
|
].join("\n");
|
|
137
159
|
}
|
|
138
160
|
// Default to quick_reference for file_path mode (loads many topics),
|
|
@@ -150,6 +172,27 @@ export function readXanoscriptDocsV2(docsPath, args) {
|
|
|
150
172
|
if (args.exclude_topics && args.exclude_topics.length > 0) {
|
|
151
173
|
topics = topics.filter((t) => !args.exclude_topics.includes(t));
|
|
152
174
|
}
|
|
175
|
+
// Budget-aware loading: sort by priority and stop when budget is exceeded
|
|
176
|
+
if (args.max_tokens) {
|
|
177
|
+
let tokenBudget = args.max_tokens;
|
|
178
|
+
const sortedTopics = [...topics].sort((a, b) => {
|
|
179
|
+
const pa = XANOSCRIPT_DOCS_V2[a]?.priority ?? 99;
|
|
180
|
+
const pb = XANOSCRIPT_DOCS_V2[b]?.priority ?? 99;
|
|
181
|
+
return pa - pb;
|
|
182
|
+
});
|
|
183
|
+
const filteredTopics = [];
|
|
184
|
+
for (const t of sortedTopics) {
|
|
185
|
+
const config = XANOSCRIPT_DOCS_V2[t];
|
|
186
|
+
const content = cachedReadFile(join(docsPath, config.file));
|
|
187
|
+
const topicContent = mode === "quick_reference" ? extractQuickReference(content, t) : content;
|
|
188
|
+
const estimatedTokens = Math.ceil(topicContent.length / 4);
|
|
189
|
+
if (tokenBudget - estimatedTokens < 0 && filteredTopics.length > 0)
|
|
190
|
+
break;
|
|
191
|
+
filteredTopics.push(t);
|
|
192
|
+
tokenBudget -= estimatedTokens;
|
|
193
|
+
}
|
|
194
|
+
topics = filteredTopics;
|
|
195
|
+
}
|
|
153
196
|
if (topics.length === 0) {
|
|
154
197
|
throw new Error(`No documentation found for file pattern: ${args.file_path}\n\nAvailable topics: ${Object.keys(XANOSCRIPT_DOCS_V2).join(", ")}`);
|
|
155
198
|
}
|
|
@@ -185,6 +228,27 @@ export function readXanoscriptDocsStructured(docsPath, args) {
|
|
|
185
228
|
if (args.exclude_topics && args.exclude_topics.length > 0) {
|
|
186
229
|
topics = topics.filter((t) => !args.exclude_topics.includes(t));
|
|
187
230
|
}
|
|
231
|
+
// Budget-aware loading
|
|
232
|
+
if (args.max_tokens) {
|
|
233
|
+
let tokenBudget = args.max_tokens;
|
|
234
|
+
const sortedTopics = [...topics].sort((a, b) => {
|
|
235
|
+
const pa = XANOSCRIPT_DOCS_V2[a]?.priority ?? 99;
|
|
236
|
+
const pb = XANOSCRIPT_DOCS_V2[b]?.priority ?? 99;
|
|
237
|
+
return pa - pb;
|
|
238
|
+
});
|
|
239
|
+
const filteredTopics = [];
|
|
240
|
+
for (const t of sortedTopics) {
|
|
241
|
+
const config = XANOSCRIPT_DOCS_V2[t];
|
|
242
|
+
const content = cachedReadFile(join(docsPath, config.file));
|
|
243
|
+
const topicContent = mode === "quick_reference" ? extractQuickReference(content, t) : content;
|
|
244
|
+
const estimatedTokens = Math.ceil(topicContent.length / 4);
|
|
245
|
+
if (tokenBudget - estimatedTokens < 0 && filteredTopics.length > 0)
|
|
246
|
+
break;
|
|
247
|
+
filteredTopics.push(t);
|
|
248
|
+
tokenBudget -= estimatedTokens;
|
|
249
|
+
}
|
|
250
|
+
topics = filteredTopics;
|
|
251
|
+
}
|
|
188
252
|
if (topics.length === 0) {
|
|
189
253
|
throw new Error(`No documentation found for file pattern: ${args.file_path}\n\nAvailable topics: ${Object.keys(XANOSCRIPT_DOCS_V2).join(", ")}`);
|
|
190
254
|
}
|
package/dist/xanoscript.test.js
CHANGED
|
@@ -9,6 +9,8 @@ describe("xanoscript module", () => {
|
|
|
9
9
|
describe("XANOSCRIPT_DOCS_V2", () => {
|
|
10
10
|
it("should have all expected topics", () => {
|
|
11
11
|
const expectedTopics = [
|
|
12
|
+
"survival",
|
|
13
|
+
"working",
|
|
12
14
|
"readme",
|
|
13
15
|
"essentials",
|
|
14
16
|
"syntax",
|
|
@@ -310,7 +312,7 @@ Even more content.
|
|
|
310
312
|
it("should throw when all topics are excluded via exclude_topics", () => {
|
|
311
313
|
expect(() => readXanoscriptDocsV2(DOCS_PATH, {
|
|
312
314
|
file_path: "branch.xs",
|
|
313
|
-
exclude_topics: ["syntax", "essentials", "debugging", "branch"],
|
|
315
|
+
exclude_topics: ["syntax", "essentials", "debugging", "branch", "survival", "working"],
|
|
314
316
|
})).toThrow("No documentation found");
|
|
315
317
|
});
|
|
316
318
|
it("should throw for invalid docs path", () => {
|
|
@@ -321,7 +323,7 @@ Even more content.
|
|
|
321
323
|
expect(result).toContain("# XanoScript Documentation Index");
|
|
322
324
|
expect(result).toContain("Version:");
|
|
323
325
|
expect(result).toContain("Topics:");
|
|
324
|
-
expect(result).toContain("| Topic | Description | Size |");
|
|
326
|
+
expect(result).toContain("| Topic | Description | Size | Est. Tokens |");
|
|
325
327
|
// Should contain some known topics
|
|
326
328
|
expect(result).toContain("| syntax |");
|
|
327
329
|
expect(result).toContain("| essentials |");
|
|
@@ -404,7 +406,7 @@ Even more content.
|
|
|
404
406
|
it("should throw when all topics are excluded", () => {
|
|
405
407
|
expect(() => readXanoscriptDocsStructured(DOCS_PATH, {
|
|
406
408
|
file_path: "branch.xs",
|
|
407
|
-
exclude_topics: ["syntax", "essentials", "debugging", "branch"],
|
|
409
|
+
exclude_topics: ["syntax", "essentials", "debugging", "branch", "survival", "working"],
|
|
408
410
|
})).toThrow("No documentation found");
|
|
409
411
|
});
|
|
410
412
|
it("should use quick_reference mode by default", () => {
|
|
@@ -178,6 +178,15 @@ This includes:
|
|
|
178
178
|
|
|
179
179
|
Use `xanoscript_docs({ topic: "<topic>" })` to retrieve documentation.
|
|
180
180
|
|
|
181
|
+
### Tiers (for context-limited models)
|
|
182
|
+
|
|
183
|
+
| Topic | Description | Size |
|
|
184
|
+
| ---------- | ------------------------------------------------------------ | ---- |
|
|
185
|
+
| `survival` | Minimal syntax survival kit for models with <16K context | ~3KB (~800 tokens) |
|
|
186
|
+
| `working` | Complete working reference for models with 16-64K context | ~12KB (~3500 tokens) |
|
|
187
|
+
|
|
188
|
+
Use `xanoscript_docs({ tier: "survival" })` or `xanoscript_docs({ tier: "working" })`.
|
|
189
|
+
|
|
181
190
|
### Core Language
|
|
182
191
|
|
|
183
192
|
| Topic | Description | Key Sections |
|
|
@@ -245,46 +254,3 @@ Use `xanoscript_docs({ topic: "<topic>" })` to retrieve documentation.
|
|
|
245
254
|
| `performance` | Performance optimization best practices | Caching, Query Optimization |
|
|
246
255
|
| `security` | Security best practices for authentication and authorization | Auth Patterns, Token Handling |
|
|
247
256
|
|
|
248
|
-
---
|
|
249
|
-
|
|
250
|
-
## Example Implementations
|
|
251
|
-
|
|
252
|
-
Common integration patterns you can reference:
|
|
253
|
-
|
|
254
|
-
### External API Integrations
|
|
255
|
-
- **OpenAI/ChatGPT**: Use `api.request` with POST to `/v1/chat/completions`
|
|
256
|
-
- **Stripe**: Use `api.request` with form-encoded params for payments
|
|
257
|
-
- **SendGrid/Resend**: Use `api.request` or `util.send_email` for emails
|
|
258
|
-
- **Slack/Discord**: Use `api.request` with webhook URLs
|
|
259
|
-
- **Twilio**: Use `api.request` with Basic auth for SMS
|
|
260
|
-
|
|
261
|
-
### Common Pattern: API Integration Function
|
|
262
|
-
|
|
263
|
-
```xs
|
|
264
|
-
function "call_external_api" {
|
|
265
|
-
input {
|
|
266
|
-
text endpoint
|
|
267
|
-
object payload
|
|
268
|
-
}
|
|
269
|
-
stack {
|
|
270
|
-
api.request {
|
|
271
|
-
url = $env.API_BASE_URL ~ $input.endpoint
|
|
272
|
-
method = "POST"
|
|
273
|
-
params = $input.payload
|
|
274
|
-
headers = [
|
|
275
|
-
"Content-Type: application/json",
|
|
276
|
-
"Authorization: Bearer " ~ $env.API_KEY
|
|
277
|
-
]
|
|
278
|
-
timeout = 30
|
|
279
|
-
} as $api_result
|
|
280
|
-
|
|
281
|
-
precondition ($api_result.response.status >= 200 && $api_result.response.status < 300) {
|
|
282
|
-
error_type = "standard"
|
|
283
|
-
error = "API error: " ~ ($api_result.response.status|to_text)
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
response = $api_result.response.result
|
|
287
|
-
}
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
For more patterns, see `xanoscript_docs({ topic: "essentials" })` or `xanoscript_docs({ topic: "integrations" })`.
|
|
@@ -252,8 +252,6 @@ addon/
|
|
|
252
252
|
1. **Keep addons focused** - One purpose per addon
|
|
253
253
|
2. **Use input parameters** - Make addons reusable
|
|
254
254
|
3. **Use appropriate return types** - `list`, `single`, `count`, `exists`
|
|
255
|
-
4. **Limit nested queries** - Avoid N+1 query patterns
|
|
256
|
-
5. **Document inputs** - Add descriptions to input fields
|
|
257
255
|
|
|
258
256
|
---
|
|
259
257
|
|
|
@@ -290,35 +290,6 @@ agent "Code Reviewer" {
|
|
|
290
290
|
}
|
|
291
291
|
```
|
|
292
292
|
|
|
293
|
-
### Multi-Tool Research Agent
|
|
294
|
-
```xs
|
|
295
|
-
agent "Research Assistant" {
|
|
296
|
-
canonical = "research-v1"
|
|
297
|
-
llm = {
|
|
298
|
-
type: "openai"
|
|
299
|
-
api_key: "{{ $env.OPENAI_API_KEY }}"
|
|
300
|
-
model: "gpt-5"
|
|
301
|
-
system_prompt: """
|
|
302
|
-
You are a research assistant. Use your tools to:
|
|
303
|
-
1. Search for relevant information
|
|
304
|
-
2. Analyze data
|
|
305
|
-
3. Compile findings into clear summaries
|
|
306
|
-
Always cite your sources.
|
|
307
|
-
"""
|
|
308
|
-
prompt: "Research topic: {{ $args.topic }}"
|
|
309
|
-
max_steps: 10
|
|
310
|
-
temperature: 0.5
|
|
311
|
-
reasoning_effort: "high"
|
|
312
|
-
}
|
|
313
|
-
tools = [
|
|
314
|
-
{ name: "web_search" },
|
|
315
|
-
{ name: "fetch_article" },
|
|
316
|
-
{ name: "analyze_data" },
|
|
317
|
-
{ name: "save_findings" }
|
|
318
|
-
]
|
|
319
|
-
}
|
|
320
|
-
```
|
|
321
|
-
|
|
322
293
|
---
|
|
323
294
|
|
|
324
295
|
## External MCP Tools
|
|
@@ -407,12 +378,8 @@ agent "Research Agent" {
|
|
|
407
378
|
## Best Practices
|
|
408
379
|
|
|
409
380
|
1. **Clear system prompts** - Define persona, capabilities, and constraints
|
|
410
|
-
2. **
|
|
411
|
-
3. **
|
|
412
|
-
4. **Don't repeat tool descriptions** - They're auto-injected
|
|
413
|
-
5. **Use environment variables** - Never hardcode API keys
|
|
414
|
-
6. **Test with xano-free first** - Free for development
|
|
415
|
-
7. **Validate external MCP servers** - Check server_details before using
|
|
381
|
+
2. **Limit max_steps** - Prevent infinite loops (3-10 typical)
|
|
382
|
+
3. **Don't repeat tool descriptions** - They're auto-injected; use environment variables for API keys
|
|
416
383
|
|
|
417
384
|
---
|
|
418
385
|
|
|
@@ -440,12 +440,9 @@ When using `return = { type: "list", paging: {...} }`:
|
|
|
440
440
|
|
|
441
441
|
## Best Practices
|
|
442
442
|
|
|
443
|
-
1. **
|
|
444
|
-
2. **
|
|
445
|
-
3. **
|
|
446
|
-
4. **Paginate lists** - Never return unbounded result sets
|
|
447
|
-
5. **Group by resource** - Organize endpoints in logical api groups
|
|
448
|
-
6. **Use specific canonicals** - Prefix canonicals to avoid instance-level collisions (e.g., `myapp-users` not `users`)
|
|
443
|
+
1. **Use specific canonicals** - Prefix canonicals to avoid instance-level collisions (e.g., `myapp-users` not `users`)
|
|
444
|
+
2. **Authenticate writes** - Always require `auth` for POST/PATCH/DELETE endpoints
|
|
445
|
+
3. **Paginate lists** - Use `return = { type: "list", paging: {...} }` to avoid unbounded result sets
|
|
449
446
|
|
|
450
447
|
---
|
|
451
448
|
|
|
@@ -236,5 +236,3 @@ project/
|
|
|
236
236
|
1. **Use descriptive colors** - Green for production, blue for development, yellow for staging
|
|
237
237
|
2. **Limit production history** - Excessive history impacts performance and storage
|
|
238
238
|
3. **Apply security middleware in production** - Rate limiting, auth checks, audit logging
|
|
239
|
-
4. **Disable middleware history in production** - Reduces noise and storage
|
|
240
|
-
5. **Enable full history in development** - Aids debugging and testing
|
|
@@ -628,13 +628,9 @@ try_catch {
|
|
|
628
628
|
|
|
629
629
|
## Best Practices
|
|
630
630
|
|
|
631
|
-
1. **Use
|
|
632
|
-
2. **Use
|
|
633
|
-
3. **Use
|
|
634
|
-
4. **Use transactions for atomicity** - Ensure all-or-nothing operations
|
|
635
|
-
5. **Use null-safe operators** - `==?` for optional filters
|
|
636
|
-
6. **Use bulk operations for batch processing** - More efficient than loops
|
|
637
|
-
7. **Handle deadlocks gracefully** - Implement retry logic for concurrent writes
|
|
631
|
+
1. **Use null-safe operators** - `==?` for optional filters avoids manual null checks
|
|
632
|
+
2. **Use bulk operations for batch processing** - More efficient than loops with individual db calls
|
|
633
|
+
3. **Use transactions for atomicity** - Ensure all-or-nothing operations across multiple tables
|
|
638
634
|
|
|
639
635
|
---
|
|
640
636
|
|