@xano/developer-mcp 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -7,6 +7,8 @@ import { fileURLToPath } from "url";
|
|
|
7
7
|
import { dirname, join } from "path";
|
|
8
8
|
import { xanoscriptParser } from "@xano/xanoscript-language-server/parser/parser.js";
|
|
9
9
|
import { getSchemeFromContent } from "@xano/xanoscript-language-server/utils.js";
|
|
10
|
+
import { generateInitWorkspaceTemplate } from "./templates/init-workspace.js";
|
|
11
|
+
import { generateXanoscriptIndexTemplate } from "./templates/xanoscript-index.js";
|
|
10
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
13
|
const __dirname = dirname(__filename);
|
|
12
14
|
// XanoScript docs mapping - keyword to files
|
|
@@ -102,6 +104,78 @@ const KEYWORD_ALIASES = {
|
|
|
102
104
|
ui: "frontend",
|
|
103
105
|
static: "frontend",
|
|
104
106
|
};
|
|
107
|
+
const XANO_OBJECT_TYPES = {
|
|
108
|
+
function: {
|
|
109
|
+
path: "functions",
|
|
110
|
+
endpoint: "function",
|
|
111
|
+
extension: ".xs",
|
|
112
|
+
hasXanoscript: true,
|
|
113
|
+
},
|
|
114
|
+
table: {
|
|
115
|
+
path: "tables",
|
|
116
|
+
endpoint: "table",
|
|
117
|
+
extension: ".xs",
|
|
118
|
+
hasXanoscript: true,
|
|
119
|
+
},
|
|
120
|
+
task: {
|
|
121
|
+
path: "tasks",
|
|
122
|
+
endpoint: "task",
|
|
123
|
+
extension: ".xs",
|
|
124
|
+
hasXanoscript: true,
|
|
125
|
+
},
|
|
126
|
+
api_group: {
|
|
127
|
+
path: "apis",
|
|
128
|
+
endpoint: "api-group",
|
|
129
|
+
extension: ".xs",
|
|
130
|
+
hasXanoscript: true,
|
|
131
|
+
supportsNesting: true,
|
|
132
|
+
},
|
|
133
|
+
tool: {
|
|
134
|
+
path: "tools",
|
|
135
|
+
endpoint: "tool",
|
|
136
|
+
extension: ".xs",
|
|
137
|
+
hasXanoscript: true,
|
|
138
|
+
},
|
|
139
|
+
agent: {
|
|
140
|
+
path: "agents",
|
|
141
|
+
endpoint: "agent",
|
|
142
|
+
extension: ".xs",
|
|
143
|
+
hasXanoscript: true,
|
|
144
|
+
},
|
|
145
|
+
middleware: {
|
|
146
|
+
path: "middlewares",
|
|
147
|
+
endpoint: "middleware",
|
|
148
|
+
extension: ".xs",
|
|
149
|
+
hasXanoscript: true,
|
|
150
|
+
},
|
|
151
|
+
addon: {
|
|
152
|
+
path: "addons",
|
|
153
|
+
endpoint: "addon",
|
|
154
|
+
extension: ".xs",
|
|
155
|
+
hasXanoscript: true,
|
|
156
|
+
},
|
|
157
|
+
mcp_server: {
|
|
158
|
+
path: "mcp_servers",
|
|
159
|
+
endpoint: "mcp-server",
|
|
160
|
+
extension: ".xs",
|
|
161
|
+
hasXanoscript: true,
|
|
162
|
+
},
|
|
163
|
+
realtime_channel: {
|
|
164
|
+
path: "realtime",
|
|
165
|
+
endpoint: "realtime-channel",
|
|
166
|
+
extension: ".xs",
|
|
167
|
+
hasXanoscript: true,
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
// Generate init_workspace documentation
|
|
171
|
+
function generateInitWorkspaceDoc() {
|
|
172
|
+
const objectTypes = Object.entries(XANO_OBJECT_TYPES).map(([type, config]) => ({
|
|
173
|
+
type,
|
|
174
|
+
path: config.path,
|
|
175
|
+
endpoint: config.endpoint,
|
|
176
|
+
}));
|
|
177
|
+
return generateInitWorkspaceTemplate(objectTypes);
|
|
178
|
+
}
|
|
105
179
|
// Map of object names to their documentation files
|
|
106
180
|
const DOCS_MAP = {
|
|
107
181
|
workspace: "workspace.md",
|
|
@@ -206,60 +280,7 @@ function generateXanoscriptIndex() {
|
|
|
206
280
|
aliasLookup[keyword] = aliasLookup[keyword] || [];
|
|
207
281
|
aliasLookup[keyword].push(alias);
|
|
208
282
|
}
|
|
209
|
-
|
|
210
|
-
const aliases = aliasLookup[keyword]?.slice(0, 3).join(", ") || "";
|
|
211
|
-
return `| \`${keyword}\` | ${aliases ? aliases : "-"} | ${description} |`;
|
|
212
|
-
};
|
|
213
|
-
return `# XanoScript Documentation Index
|
|
214
|
-
Version: ${version}
|
|
215
|
-
|
|
216
|
-
Use \`xanoscript_docs\` with a keyword to retrieve documentation.
|
|
217
|
-
|
|
218
|
-
## Core Concepts
|
|
219
|
-
These return guidelines + examples for writing XanoScript code.
|
|
220
|
-
|
|
221
|
-
| Keyword | Aliases | Description |
|
|
222
|
-
|---------|---------|-------------|
|
|
223
|
-
${formatRow("function", "Custom reusable functions in `functions/`")}
|
|
224
|
-
${formatRow("api_query", "HTTP API endpoints in `apis/`")}
|
|
225
|
-
${formatRow("table", "Database table schemas in `tables/`")}
|
|
226
|
-
${formatRow("task", "Scheduled background tasks in `tasks/`")}
|
|
227
|
-
${formatRow("tool", "AI-callable tools in `tools/`")}
|
|
228
|
-
${formatRow("agent", "AI agents in `agents/`")}
|
|
229
|
-
${formatRow("mcp_server", "MCP servers in `mcp_servers/`")}
|
|
230
|
-
|
|
231
|
-
## Language Reference
|
|
232
|
-
Core syntax and operators.
|
|
233
|
-
|
|
234
|
-
| Keyword | Aliases | Description |
|
|
235
|
-
|---------|---------|-------------|
|
|
236
|
-
${formatRow("syntax", "Complete XanoScript syntax (stack, var, conditional, foreach, etc.)")}
|
|
237
|
-
${formatRow("expressions", "Pipe operators and filters (string, math, array, date)")}
|
|
238
|
-
${formatRow("input", "Input definition syntax (types, filters, validation)")}
|
|
239
|
-
${formatRow("db_query", "Database query patterns (query, add, edit, delete)")}
|
|
240
|
-
${formatRow("query_filter", "WHERE clause and filter syntax")}
|
|
241
|
-
|
|
242
|
-
## Development Workflows
|
|
243
|
-
AI agent development strategies and phases.
|
|
244
|
-
|
|
245
|
-
| Keyword | Aliases | Description |
|
|
246
|
-
|---------|---------|-------------|
|
|
247
|
-
${formatRow("workflow", "Overall XanoScript development workflow")}
|
|
248
|
-
${formatRow("function_workflow", "AI workflow for creating functions")}
|
|
249
|
-
${formatRow("api_workflow", "AI workflow for creating API endpoints")}
|
|
250
|
-
${formatRow("table_workflow", "AI workflow for creating tables")}
|
|
251
|
-
${formatRow("task_workflow", "AI workflow for creating tasks")}
|
|
252
|
-
|
|
253
|
-
## Specialized Topics
|
|
254
|
-
|
|
255
|
-
| Keyword | Aliases | Description |
|
|
256
|
-
|---------|---------|-------------|
|
|
257
|
-
${formatRow("frontend", "Frontend development with Xano")}
|
|
258
|
-
${formatRow("lovable", "Building from Lovable-generated websites")}
|
|
259
|
-
${formatRow("testing", "Unit testing XanoScript code")}
|
|
260
|
-
${formatRow("tips", "Tips and tricks")}
|
|
261
|
-
${formatRow("ephemeral", "Ephemeral environment setup")}
|
|
262
|
-
`;
|
|
283
|
+
return generateXanoscriptIndexTemplate({ version, aliasLookup });
|
|
263
284
|
}
|
|
264
285
|
// Read XanoScript documentation for a keyword
|
|
265
286
|
function readXanoscriptDocs(keyword) {
|
|
@@ -310,6 +331,7 @@ Use xanoscript_docs() without parameters to see the full documentation index.`;
|
|
|
310
331
|
const server = new Server({
|
|
311
332
|
name: "xano-developer-mcp",
|
|
312
333
|
version: "1.0.0",
|
|
334
|
+
description: "MCP server for Xano Headless API documentation and XanoScript code validation",
|
|
313
335
|
}, {
|
|
314
336
|
capabilities: {
|
|
315
337
|
tools: {},
|
|
@@ -367,6 +389,18 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
367
389
|
required: [],
|
|
368
390
|
},
|
|
369
391
|
},
|
|
392
|
+
{
|
|
393
|
+
name: "init_workspace",
|
|
394
|
+
description: "Get comprehensive instructions for initializing a local Xano development workspace. " +
|
|
395
|
+
"Returns documentation on directory structure, file naming conventions, registry format for tracking changes, " +
|
|
396
|
+
"and workflows for pulling/pushing XanoScript files via the Headless API. " +
|
|
397
|
+
"Use this when setting up local development for Xano projects.",
|
|
398
|
+
inputSchema: {
|
|
399
|
+
type: "object",
|
|
400
|
+
properties: {},
|
|
401
|
+
required: [],
|
|
402
|
+
},
|
|
403
|
+
},
|
|
370
404
|
],
|
|
371
405
|
};
|
|
372
406
|
});
|
|
@@ -473,6 +507,17 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
473
507
|
],
|
|
474
508
|
};
|
|
475
509
|
}
|
|
510
|
+
if (request.params.name === "init_workspace") {
|
|
511
|
+
const documentation = generateInitWorkspaceDoc();
|
|
512
|
+
return {
|
|
513
|
+
content: [
|
|
514
|
+
{
|
|
515
|
+
type: "text",
|
|
516
|
+
text: documentation,
|
|
517
|
+
},
|
|
518
|
+
],
|
|
519
|
+
};
|
|
520
|
+
}
|
|
476
521
|
return {
|
|
477
522
|
content: [
|
|
478
523
|
{
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template for init_workspace tool documentation
|
|
3
|
+
* Edit this file to update the workspace initialization guide
|
|
4
|
+
*/
|
|
5
|
+
export interface ObjectTypeConfig {
|
|
6
|
+
type: string;
|
|
7
|
+
path: string;
|
|
8
|
+
endpoint: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function generateInitWorkspaceTemplate(objectTypes: ObjectTypeConfig[]): string;
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template for init_workspace tool documentation
|
|
3
|
+
* Edit this file to update the workspace initialization guide
|
|
4
|
+
*/
|
|
5
|
+
export function generateInitWorkspaceTemplate(objectTypes) {
|
|
6
|
+
const objectTypesTable = objectTypes
|
|
7
|
+
.map(({ type, path, endpoint }) => `| \`${type}\` | \`${path}/\` | \`${endpoint}\` |`)
|
|
8
|
+
.join("\n");
|
|
9
|
+
return `# Xano Workspace Initialization Guide
|
|
10
|
+
|
|
11
|
+
This guide explains how to set up a local development workspace that syncs with the Xano Headless API.
|
|
12
|
+
|
|
13
|
+
## Directory Structure
|
|
14
|
+
|
|
15
|
+
Initialize your workspace with these directories:
|
|
16
|
+
|
|
17
|
+
\`\`\`
|
|
18
|
+
your-project/
|
|
19
|
+
├── .xano/
|
|
20
|
+
│ └── registry.json # Tracks all objects and their sync state
|
|
21
|
+
├── functions/ # Custom reusable functions
|
|
22
|
+
│ ├── calculate_total.xs
|
|
23
|
+
│ └── validate_email.xs
|
|
24
|
+
├── tables/ # Database table schemas
|
|
25
|
+
│ ├── user.xs
|
|
26
|
+
│ └── order.xs
|
|
27
|
+
├── tasks/ # Scheduled background tasks
|
|
28
|
+
│ └── cleanup_sessions.xs
|
|
29
|
+
├── apis/ # API groups and endpoints
|
|
30
|
+
│ └── auth/ # API group directory
|
|
31
|
+
│ ├── api_group.xs # Group definition
|
|
32
|
+
│ ├── POST_login.xs # Endpoint: POST /auth/login
|
|
33
|
+
│ └── GET_me.xs # Endpoint: GET /auth/me
|
|
34
|
+
├── tools/ # AI-callable tools
|
|
35
|
+
├── agents/ # AI agents
|
|
36
|
+
├── middlewares/ # Request/response middleware
|
|
37
|
+
├── addons/ # Query addons
|
|
38
|
+
├── mcp_servers/ # MCP servers
|
|
39
|
+
└── realtime/ # Realtime channels
|
|
40
|
+
\`\`\`
|
|
41
|
+
|
|
42
|
+
## Object Types
|
|
43
|
+
|
|
44
|
+
| Type | Directory | API Endpoint |
|
|
45
|
+
|------|-----------|--------------|
|
|
46
|
+
${objectTypesTable}
|
|
47
|
+
|
|
48
|
+
## File Naming Convention
|
|
49
|
+
|
|
50
|
+
Files should follow snake_case naming with the \`.xs\` extension:
|
|
51
|
+
- \`{name}.xs\` - Basic format (e.g., \`calculate_total.xs\`)
|
|
52
|
+
- \`{id}_{name}.xs\` - With ID prefix for disambiguation (e.g., \`42_calculate_total.xs\`)
|
|
53
|
+
- API endpoints: \`{VERB}_{path}.xs\` (e.g., \`POST_login.xs\`, \`GET_users_id.xs\`)
|
|
54
|
+
|
|
55
|
+
## Registry Format
|
|
56
|
+
|
|
57
|
+
The \`.xano/registry.json\` file tracks the sync state between local files and the Xano API:
|
|
58
|
+
|
|
59
|
+
\`\`\`json
|
|
60
|
+
{
|
|
61
|
+
"workspace_id": 12345,
|
|
62
|
+
"workspace_name": "My Project",
|
|
63
|
+
"branch": "",
|
|
64
|
+
"base_url": "https://your-instance.xano.io/api:headless",
|
|
65
|
+
"created_at": "2025-01-15T10:30:00Z",
|
|
66
|
+
"updated_at": "2025-01-15T10:30:00Z",
|
|
67
|
+
"objects": [
|
|
68
|
+
{
|
|
69
|
+
"id": 1,
|
|
70
|
+
"type": "function",
|
|
71
|
+
"name": "calculate_total",
|
|
72
|
+
"path": "functions/calculate_total.xs",
|
|
73
|
+
"sha256": "abc123...",
|
|
74
|
+
"status": "unchanged",
|
|
75
|
+
"original": "ZnVuY3Rpb24gY2FsY3VsYXRlX3RvdGFsIHsgLi4uIH0=",
|
|
76
|
+
"updated_at": "2025-01-15T10:30:00Z"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"id": 0,
|
|
80
|
+
"type": "function",
|
|
81
|
+
"name": "new_function",
|
|
82
|
+
"path": "functions/new_function.xs",
|
|
83
|
+
"status": "new"
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
\`\`\`
|
|
88
|
+
|
|
89
|
+
### Registry Record Fields
|
|
90
|
+
|
|
91
|
+
| Field | Description |
|
|
92
|
+
|-------|-------------|
|
|
93
|
+
| \`id\` | Xano object ID (0 = new, not yet synced) |
|
|
94
|
+
| \`type\` | Object type (function, table, task, etc.) |
|
|
95
|
+
| \`name\` | Object name extracted from XanoScript |
|
|
96
|
+
| \`path\` | Relative file path from workspace root |
|
|
97
|
+
| \`sha256\` | SHA256 hash of file content for change detection |
|
|
98
|
+
| \`status\` | Sync status: "new", "unchanged", "changed", "deleted" |
|
|
99
|
+
| \`original\` | Base64-encoded original content (for conflict detection) |
|
|
100
|
+
| \`updated_at\` | Last sync timestamp |
|
|
101
|
+
|
|
102
|
+
### Status Values
|
|
103
|
+
|
|
104
|
+
| Status | Description |
|
|
105
|
+
|--------|-------------|
|
|
106
|
+
| \`new\` | Created locally, not yet pushed to Xano |
|
|
107
|
+
| \`unchanged\` | In sync with remote |
|
|
108
|
+
| \`changed\` | Modified locally since last sync |
|
|
109
|
+
| \`deleted\` | Marked for deletion (file removed locally) |
|
|
110
|
+
|
|
111
|
+
## Fetching Objects from the API
|
|
112
|
+
|
|
113
|
+
Use the Headless API to fetch objects. For detailed endpoint documentation, use \`api_docs({ object: "function" })\` etc.
|
|
114
|
+
|
|
115
|
+
### List Objects
|
|
116
|
+
|
|
117
|
+
\`\`\`
|
|
118
|
+
GET /workspace/{workspace_id}/{type}
|
|
119
|
+
Headers:
|
|
120
|
+
Authorization: Bearer {token}
|
|
121
|
+
|
|
122
|
+
Query Parameters:
|
|
123
|
+
- branch: Branch label (empty = live branch)
|
|
124
|
+
- page: Page number (default: 1)
|
|
125
|
+
- per_page: Items per page (default: 50, max: 10000)
|
|
126
|
+
- search: Text search filter
|
|
127
|
+
- sort: Sort field (created_at, updated_at, name)
|
|
128
|
+
- order: asc or desc
|
|
129
|
+
\`\`\`
|
|
130
|
+
|
|
131
|
+
### Get Single Object with XanoScript
|
|
132
|
+
|
|
133
|
+
\`\`\`
|
|
134
|
+
GET /workspace/{workspace_id}/{type}/{id}
|
|
135
|
+
Headers:
|
|
136
|
+
Authorization: Bearer {token}
|
|
137
|
+
|
|
138
|
+
Query Parameters:
|
|
139
|
+
- branch: Branch label
|
|
140
|
+
\`\`\`
|
|
141
|
+
|
|
142
|
+
The response includes the \`xanoscript\` field with the code content:
|
|
143
|
+
\`\`\`json
|
|
144
|
+
{
|
|
145
|
+
"id": 1,
|
|
146
|
+
"name": "calculate_total",
|
|
147
|
+
"xanoscript": {
|
|
148
|
+
"status": "ok",
|
|
149
|
+
"value": "function calculate_total { ... }"
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
\`\`\`
|
|
153
|
+
|
|
154
|
+
### API Endpoints (Nested Under API Groups)
|
|
155
|
+
|
|
156
|
+
**Important:** API endpoints are nested resources under API groups. You must first fetch API groups to obtain their IDs, then use those IDs to fetch the endpoints within each group.
|
|
157
|
+
|
|
158
|
+
\`\`\`
|
|
159
|
+
# 1. First, list API groups
|
|
160
|
+
GET /workspace/{workspace_id}/apigroup
|
|
161
|
+
|
|
162
|
+
# 2. Then, list endpoints for each group using the apigroup_id
|
|
163
|
+
GET /workspace/{workspace_id}/apigroup/{apigroup_id}/api
|
|
164
|
+
|
|
165
|
+
# 3. Get a single endpoint
|
|
166
|
+
GET /workspace/{workspace_id}/apigroup/{apigroup_id}/api/{api_id}
|
|
167
|
+
\`\`\`
|
|
168
|
+
|
|
169
|
+
This hierarchical structure is reflected in the local directory layout:
|
|
170
|
+
\`\`\`
|
|
171
|
+
apis/
|
|
172
|
+
└── auth/ # API group (apigroup_id required)
|
|
173
|
+
├── api_group.xs # Group definition
|
|
174
|
+
├── POST_login.xs # Endpoint within this group
|
|
175
|
+
└── GET_me.xs # Another endpoint
|
|
176
|
+
\`\`\`
|
|
177
|
+
|
|
178
|
+
See \`api_docs({ object: "api_group" })\` for complete API group and endpoint documentation.
|
|
179
|
+
|
|
180
|
+
## Pull Workflow
|
|
181
|
+
|
|
182
|
+
1. **Fetch object list** from API (paginated)
|
|
183
|
+
2. **For each object**, get the full definition including XanoScript
|
|
184
|
+
3. **Generate file path** based on type and name
|
|
185
|
+
4. **Write file** to the appropriate directory
|
|
186
|
+
5. **Update registry** with object metadata and SHA256 hash
|
|
187
|
+
|
|
188
|
+
### Example Pull Request Sequence
|
|
189
|
+
|
|
190
|
+
\`\`\`javascript
|
|
191
|
+
// 1. List all functions
|
|
192
|
+
const response = await fetch(
|
|
193
|
+
\`\${baseUrl}/workspace/\${workspaceId}/function?branch=\${branch}&per_page=100\`,
|
|
194
|
+
{ headers: { Authorization: \`Bearer \${token}\` } }
|
|
195
|
+
);
|
|
196
|
+
const { items, nextPage } = await response.json();
|
|
197
|
+
|
|
198
|
+
// 2. For each function, save to file
|
|
199
|
+
for (const func of items) {
|
|
200
|
+
const xanoscript = func.xanoscript?.value || '';
|
|
201
|
+
const fileName = \`\${snakeCase(func.name)}.xs\`;
|
|
202
|
+
const filePath = \`functions/\${fileName}\`;
|
|
203
|
+
|
|
204
|
+
// Write file
|
|
205
|
+
await writeFile(filePath, xanoscript);
|
|
206
|
+
|
|
207
|
+
// Add to registry
|
|
208
|
+
registry.objects.push({
|
|
209
|
+
id: func.id,
|
|
210
|
+
type: 'function',
|
|
211
|
+
name: func.name,
|
|
212
|
+
path: filePath,
|
|
213
|
+
sha256: sha256(xanoscript),
|
|
214
|
+
status: 'unchanged',
|
|
215
|
+
original: btoa(xanoscript),
|
|
216
|
+
updated_at: func.updated_at
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
\`\`\`
|
|
220
|
+
|
|
221
|
+
## Push Workflow
|
|
222
|
+
|
|
223
|
+
1. **Read registry** to find changed/new objects
|
|
224
|
+
2. **For each changed file**, read content and detect changes
|
|
225
|
+
3. **Create or update** via API with XanoScript content
|
|
226
|
+
4. **Update registry** with new IDs and hashes
|
|
227
|
+
|
|
228
|
+
### Example Push Request
|
|
229
|
+
|
|
230
|
+
\`\`\`javascript
|
|
231
|
+
// Create new function
|
|
232
|
+
const response = await fetch(
|
|
233
|
+
\`\${baseUrl}/workspace/\${workspaceId}/function?branch=\${branch}\`,
|
|
234
|
+
{
|
|
235
|
+
method: 'POST',
|
|
236
|
+
headers: {
|
|
237
|
+
'Authorization': \`Bearer \${token}\`,
|
|
238
|
+
'Content-Type': 'text/x-xanoscript'
|
|
239
|
+
},
|
|
240
|
+
body: xanoscriptContent
|
|
241
|
+
}
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
// Update existing function
|
|
245
|
+
const response = await fetch(
|
|
246
|
+
\`\${baseUrl}/workspace/\${workspaceId}/function/\${functionId}?publish=true\`,
|
|
247
|
+
{
|
|
248
|
+
method: 'PUT',
|
|
249
|
+
headers: {
|
|
250
|
+
'Authorization': \`Bearer \${token}\`,
|
|
251
|
+
'Content-Type': 'text/x-xanoscript'
|
|
252
|
+
},
|
|
253
|
+
body: xanoscriptContent
|
|
254
|
+
}
|
|
255
|
+
);
|
|
256
|
+
\`\`\`
|
|
257
|
+
|
|
258
|
+
## API Documentation References
|
|
259
|
+
|
|
260
|
+
For detailed API documentation on each object type, use:
|
|
261
|
+
|
|
262
|
+
- \`api_docs()\` - Overview of all endpoints
|
|
263
|
+
- \`api_docs({ object: "workspace" })\` - Workspace management
|
|
264
|
+
- \`api_docs({ object: "function" })\` - Functions API
|
|
265
|
+
- \`api_docs({ object: "table" })\` - Tables API
|
|
266
|
+
- \`api_docs({ object: "task" })\` - Tasks API
|
|
267
|
+
- \`api_docs({ object: "api_group" })\` - API groups and endpoints
|
|
268
|
+
- \`api_docs({ object: "agent" })\` - AI agents
|
|
269
|
+
- \`api_docs({ object: "tool" })\` - AI tools
|
|
270
|
+
- \`api_docs({ object: "authentication" })\` - Auth and user info
|
|
271
|
+
|
|
272
|
+
## XanoScript Documentation References
|
|
273
|
+
|
|
274
|
+
For writing XanoScript code, use:
|
|
275
|
+
|
|
276
|
+
- \`xanoscript_docs()\` - Full documentation index
|
|
277
|
+
- \`xanoscript_docs({ keyword: "function" })\` - Function syntax
|
|
278
|
+
- \`xanoscript_docs({ keyword: "table" })\` - Table schema syntax
|
|
279
|
+
- \`xanoscript_docs({ keyword: "api_query" })\` - API endpoint syntax
|
|
280
|
+
- \`xanoscript_docs({ keyword: "syntax" })\` - Language reference
|
|
281
|
+
|
|
282
|
+
## Validating XanoScript
|
|
283
|
+
|
|
284
|
+
Before pushing changes, validate the XanoScript syntax:
|
|
285
|
+
|
|
286
|
+
\`\`\`
|
|
287
|
+
validate_xanoscript({ code: "function foo { ... }" })
|
|
288
|
+
\`\`\`
|
|
289
|
+
|
|
290
|
+
This will check for syntax errors and return line/column positions for any issues.
|
|
291
|
+
`;
|
|
292
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template for xanoscript_docs index documentation
|
|
3
|
+
* Edit this file to update the XanoScript documentation index
|
|
4
|
+
*/
|
|
5
|
+
export interface XanoscriptIndexParams {
|
|
6
|
+
version: string;
|
|
7
|
+
aliasLookup: Record<string, string[]>;
|
|
8
|
+
}
|
|
9
|
+
export declare function generateXanoscriptIndexTemplate(params: XanoscriptIndexParams): string;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template for xanoscript_docs index documentation
|
|
3
|
+
* Edit this file to update the XanoScript documentation index
|
|
4
|
+
*/
|
|
5
|
+
export function generateXanoscriptIndexTemplate(params) {
|
|
6
|
+
const { version, aliasLookup } = params;
|
|
7
|
+
const formatRow = (keyword, description) => {
|
|
8
|
+
const aliases = aliasLookup[keyword]?.slice(0, 3).join(", ") || "";
|
|
9
|
+
return `| \`${keyword}\` | ${aliases ? aliases : "-"} | ${description} |`;
|
|
10
|
+
};
|
|
11
|
+
return `# XanoScript Documentation Index
|
|
12
|
+
Version: ${version}
|
|
13
|
+
|
|
14
|
+
Use \`xanoscript_docs\` with a keyword to retrieve documentation.
|
|
15
|
+
|
|
16
|
+
## Core Concepts
|
|
17
|
+
These return guidelines + examples for writing XanoScript code.
|
|
18
|
+
|
|
19
|
+
| Keyword | Aliases | Description |
|
|
20
|
+
|---------|---------|-------------|
|
|
21
|
+
${formatRow("function", "Custom reusable functions in `functions/`")}
|
|
22
|
+
${formatRow("api_query", "HTTP API endpoints in `apis/`")}
|
|
23
|
+
${formatRow("table", "Database table schemas in `tables/`")}
|
|
24
|
+
${formatRow("task", "Scheduled background tasks in `tasks/`")}
|
|
25
|
+
${formatRow("tool", "AI-callable tools in `tools/`")}
|
|
26
|
+
${formatRow("agent", "AI agents in `agents/`")}
|
|
27
|
+
${formatRow("mcp_server", "MCP servers in `mcp_servers/`")}
|
|
28
|
+
|
|
29
|
+
## Language Reference
|
|
30
|
+
Core syntax and operators.
|
|
31
|
+
|
|
32
|
+
| Keyword | Aliases | Description |
|
|
33
|
+
|---------|---------|-------------|
|
|
34
|
+
${formatRow("syntax", "Complete XanoScript syntax (stack, var, conditional, foreach, etc.)")}
|
|
35
|
+
${formatRow("expressions", "Pipe operators and filters (string, math, array, date)")}
|
|
36
|
+
${formatRow("input", "Input definition syntax (types, filters, validation)")}
|
|
37
|
+
${formatRow("db_query", "Database query patterns (query, add, edit, delete)")}
|
|
38
|
+
${formatRow("query_filter", "WHERE clause and filter syntax")}
|
|
39
|
+
|
|
40
|
+
## Development Workflows
|
|
41
|
+
AI agent development strategies and phases.
|
|
42
|
+
|
|
43
|
+
| Keyword | Aliases | Description |
|
|
44
|
+
|---------|---------|-------------|
|
|
45
|
+
${formatRow("workflow", "Overall XanoScript development workflow")}
|
|
46
|
+
${formatRow("function_workflow", "AI workflow for creating functions")}
|
|
47
|
+
${formatRow("api_workflow", "AI workflow for creating API endpoints")}
|
|
48
|
+
${formatRow("table_workflow", "AI workflow for creating tables")}
|
|
49
|
+
${formatRow("task_workflow", "AI workflow for creating tasks")}
|
|
50
|
+
|
|
51
|
+
## Specialized Topics
|
|
52
|
+
|
|
53
|
+
| Keyword | Aliases | Description |
|
|
54
|
+
|---------|---------|-------------|
|
|
55
|
+
${formatRow("frontend", "Frontend development with Xano")}
|
|
56
|
+
${formatRow("lovable", "Building from Lovable-generated websites")}
|
|
57
|
+
${formatRow("testing", "Unit testing XanoScript code")}
|
|
58
|
+
${formatRow("tips", "Tips and tricks")}
|
|
59
|
+
${formatRow("ephemeral", "Ephemeral environment setup")}
|
|
60
|
+
`;
|
|
61
|
+
}
|