fastmode-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +561 -0
  2. package/bin/run.js +50 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +802 -0
  6. package/dist/lib/api-client.d.ts +81 -0
  7. package/dist/lib/api-client.d.ts.map +1 -0
  8. package/dist/lib/api-client.js +237 -0
  9. package/dist/lib/auth-state.d.ts +13 -0
  10. package/dist/lib/auth-state.d.ts.map +1 -0
  11. package/dist/lib/auth-state.js +24 -0
  12. package/dist/lib/context-fetcher.d.ts +67 -0
  13. package/dist/lib/context-fetcher.d.ts.map +1 -0
  14. package/dist/lib/context-fetcher.js +190 -0
  15. package/dist/lib/credentials.d.ts +52 -0
  16. package/dist/lib/credentials.d.ts.map +1 -0
  17. package/dist/lib/credentials.js +196 -0
  18. package/dist/lib/device-flow.d.ts +14 -0
  19. package/dist/lib/device-flow.d.ts.map +1 -0
  20. package/dist/lib/device-flow.js +244 -0
  21. package/dist/tools/cms-items.d.ts +56 -0
  22. package/dist/tools/cms-items.d.ts.map +1 -0
  23. package/dist/tools/cms-items.js +376 -0
  24. package/dist/tools/create-site.d.ts +9 -0
  25. package/dist/tools/create-site.d.ts.map +1 -0
  26. package/dist/tools/create-site.js +202 -0
  27. package/dist/tools/deploy-package.d.ts +9 -0
  28. package/dist/tools/deploy-package.d.ts.map +1 -0
  29. package/dist/tools/deploy-package.js +434 -0
  30. package/dist/tools/generate-samples.d.ts +19 -0
  31. package/dist/tools/generate-samples.d.ts.map +1 -0
  32. package/dist/tools/generate-samples.js +272 -0
  33. package/dist/tools/get-conversion-guide.d.ts +7 -0
  34. package/dist/tools/get-conversion-guide.d.ts.map +1 -0
  35. package/dist/tools/get-conversion-guide.js +1323 -0
  36. package/dist/tools/get-example.d.ts +7 -0
  37. package/dist/tools/get-example.d.ts.map +1 -0
  38. package/dist/tools/get-example.js +1568 -0
  39. package/dist/tools/get-field-types.d.ts +30 -0
  40. package/dist/tools/get-field-types.d.ts.map +1 -0
  41. package/dist/tools/get-field-types.js +154 -0
  42. package/dist/tools/get-schema.d.ts +5 -0
  43. package/dist/tools/get-schema.d.ts.map +1 -0
  44. package/dist/tools/get-schema.js +320 -0
  45. package/dist/tools/get-started.d.ts +21 -0
  46. package/dist/tools/get-started.d.ts.map +1 -0
  47. package/dist/tools/get-started.js +624 -0
  48. package/dist/tools/get-tenant-schema.d.ts +18 -0
  49. package/dist/tools/get-tenant-schema.d.ts.map +1 -0
  50. package/dist/tools/get-tenant-schema.js +158 -0
  51. package/dist/tools/list-projects.d.ts +5 -0
  52. package/dist/tools/list-projects.d.ts.map +1 -0
  53. package/dist/tools/list-projects.js +101 -0
  54. package/dist/tools/sync-schema.d.ts +41 -0
  55. package/dist/tools/sync-schema.d.ts.map +1 -0
  56. package/dist/tools/sync-schema.js +483 -0
  57. package/dist/tools/validate-manifest.d.ts +5 -0
  58. package/dist/tools/validate-manifest.d.ts.map +1 -0
  59. package/dist/tools/validate-manifest.js +311 -0
  60. package/dist/tools/validate-package.d.ts +5 -0
  61. package/dist/tools/validate-package.d.ts.map +1 -0
  62. package/dist/tools/validate-package.js +337 -0
  63. package/dist/tools/validate-template.d.ts +12 -0
  64. package/dist/tools/validate-template.d.ts.map +1 -0
  65. package/dist/tools/validate-template.js +790 -0
  66. package/package.json +54 -0
  67. package/scripts/postinstall.js +129 -0
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTenantSchema = getTenantSchema;
4
+ const api_client_1 = require("../lib/api-client");
5
+ const device_flow_1 = require("../lib/device-flow");
6
+ /**
7
+ * Resolve a project identifier to a tenant ID
8
+ * Accepts either a UUID or a project name
9
+ */
10
+ async function resolveProjectId(projectIdentifier) {
11
+ // Check if it looks like a UUID
12
+ const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
13
+ if (uuidPattern.test(projectIdentifier)) {
14
+ // It's already a UUID, use it directly
15
+ return { tenantId: projectIdentifier };
16
+ }
17
+ // Otherwise, look up by name using /api/tenants
18
+ const response = await (0, api_client_1.apiRequest)('/api/tenants');
19
+ if ((0, api_client_1.isApiError)(response)) {
20
+ return { error: `Failed to look up project: ${response.error}` };
21
+ }
22
+ const projects = response.data;
23
+ // Find by exact name match (case-insensitive)
24
+ const match = projects.find(p => p.name.toLowerCase() === projectIdentifier.toLowerCase());
25
+ if (match) {
26
+ return { tenantId: match.id };
27
+ }
28
+ // Try partial match
29
+ const partialMatch = projects.find(p => p.name.toLowerCase().includes(projectIdentifier.toLowerCase()));
30
+ if (partialMatch) {
31
+ return { tenantId: partialMatch.id };
32
+ }
33
+ // List available projects for the user
34
+ const availableProjects = projects.map(p => `- ${p.name} (${p.id})`).join('\n');
35
+ return {
36
+ error: `Project "${projectIdentifier}" not found.\n\nAvailable projects:\n${availableProjects || 'None'}\n\nUse list_projects to see all your projects.`
37
+ };
38
+ }
39
+ /**
40
+ * Fetches the complete schema for a specific project including:
41
+ * - All custom collections with their fields
42
+ * - Field tokens, types, and descriptions for AI context
43
+ * - Template patterns and example usage
44
+ *
45
+ * Each field includes:
46
+ * - Field Name (display name)
47
+ * - Token (the exact syntax to use in templates)
48
+ * - Type (text, richText, image, etc.)
49
+ * - Description (help text for context)
50
+ *
51
+ * Uses stored credentials or triggers device flow for authentication.
52
+ *
53
+ * @param projectId - Project ID (UUID) or project name
54
+ */
55
+ async function getTenantSchema(projectId) {
56
+ // Check if we need to authenticate
57
+ if (await (0, api_client_1.needsAuthentication)()) {
58
+ const authResult = await (0, device_flow_1.ensureAuthenticated)();
59
+ if (!authResult.authenticated) {
60
+ return authResult.message;
61
+ }
62
+ }
63
+ // Resolve project identifier to tenant ID
64
+ const resolved = await resolveProjectId(projectId);
65
+ if ('error' in resolved) {
66
+ return `# Project Not Found
67
+
68
+ ${resolved.error}
69
+ `;
70
+ }
71
+ const { tenantId } = resolved;
72
+ const apiUrl = (0, api_client_1.getApiUrl)();
73
+ // Fetch the AI prompt for this tenant
74
+ const response = await (0, api_client_1.apiRequest)('/api/collections/ai-prompt', {
75
+ tenantId,
76
+ });
77
+ if ((0, api_client_1.isApiError)(response)) {
78
+ // If auth error, try to re-authenticate
79
+ if ((0, api_client_1.needsAuthError)(response)) {
80
+ const authResult = await (0, device_flow_1.ensureAuthenticated)();
81
+ if (!authResult.authenticated) {
82
+ return authResult.message;
83
+ }
84
+ // Retry the request
85
+ const retryResponse = await (0, api_client_1.apiRequest)('/api/collections/ai-prompt', {
86
+ tenantId,
87
+ });
88
+ if ((0, api_client_1.isApiError)(retryResponse)) {
89
+ return `# API Error
90
+
91
+ Failed to fetch project schema: ${retryResponse.error}
92
+
93
+ **Project ID:** ${tenantId}
94
+ **Status:** ${retryResponse.statusCode}
95
+
96
+ Please try authenticating again.
97
+ `;
98
+ }
99
+ return formatSchemaResponse(retryResponse.data, tenantId);
100
+ }
101
+ if (response.statusCode === 403) {
102
+ return `# Authorization Error
103
+
104
+ You don't have permission to access this project's schema.
105
+
106
+ **Project ID:** ${tenantId}
107
+
108
+ Make sure:
109
+ 1. You have membership in this project
110
+ 2. Try running \`list_projects\` to see your accessible projects
111
+ `;
112
+ }
113
+ return `# API Error
114
+
115
+ Failed to fetch project schema: ${response.error}
116
+
117
+ **Project ID:** ${tenantId}
118
+ **API URL:** ${apiUrl}
119
+ **Status:** ${response.statusCode}
120
+
121
+ Please verify:
122
+ 1. The project ID is correct
123
+ 2. You have network connectivity
124
+ `;
125
+ }
126
+ return formatSchemaResponse(response.data, tenantId);
127
+ }
128
+ /**
129
+ * Format the schema response for display
130
+ */
131
+ function formatSchemaResponse(data, tenantId) {
132
+ if (!data?.prompt) {
133
+ return `# Unexpected Response
134
+
135
+ The API returned a successful response but the prompt data was missing.
136
+
137
+ **Project ID:** ${tenantId}
138
+ **Response:** ${JSON.stringify(data, null, 2).slice(0, 500)}
139
+ `;
140
+ }
141
+ // Return the full AI prompt which includes all schema information
142
+ return `# Project Schema
143
+
144
+ **Project ID:** \`${tenantId}\`
145
+
146
+ This schema is specific to this project and includes all collections with their fields.
147
+
148
+ **Field Table Format:**
149
+ - **Field Name** - Display name for the field
150
+ - **Token** - The exact token to use in templates (use triple braces for richText)
151
+ - **Type** - Field type (text, richText, image, url, videoEmbed, boolean, number, date, select, relation)
152
+ - **Description** - Help text explaining what the field is for
153
+
154
+ ---
155
+
156
+ ${data.prompt}
157
+ `;
158
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * List all FastMode projects the authenticated user has access to
3
+ */
4
+ export declare function listProjects(): Promise<string>;
5
+ //# sourceMappingURL=list-projects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-projects.d.ts","sourceRoot":"","sources":["../../src/tools/list-projects.ts"],"names":[],"mappings":"AAmBA;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAkDpD"}
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listProjects = listProjects;
4
+ const api_client_1 = require("../lib/api-client");
5
+ const device_flow_1 = require("../lib/device-flow");
6
+ /**
7
+ * List all FastMode projects the authenticated user has access to
8
+ */
9
+ async function listProjects() {
10
+ // Check if we need to authenticate
11
+ if (await (0, api_client_1.needsAuthentication)()) {
12
+ const authResult = await (0, device_flow_1.ensureAuthenticated)();
13
+ if (!authResult.authenticated) {
14
+ return authResult.message;
15
+ }
16
+ }
17
+ // Fetch user's tenants/projects
18
+ const response = await (0, api_client_1.apiRequest)('/api/tenants');
19
+ if ((0, api_client_1.isApiError)(response)) {
20
+ // If auth error, try to re-authenticate
21
+ if ((0, api_client_1.needsAuthError)(response)) {
22
+ const authResult = await (0, device_flow_1.ensureAuthenticated)();
23
+ if (!authResult.authenticated) {
24
+ return authResult.message;
25
+ }
26
+ // Retry the request
27
+ const retryResponse = await (0, api_client_1.apiRequest)('/api/tenants');
28
+ if ((0, api_client_1.isApiError)(retryResponse)) {
29
+ return `# API Error
30
+
31
+ Failed to fetch projects: ${retryResponse.error}
32
+
33
+ **Status:** ${retryResponse.statusCode}
34
+
35
+ Please try authenticating again.
36
+ `;
37
+ }
38
+ return formatProjectList(retryResponse.data);
39
+ }
40
+ return `# API Error
41
+
42
+ Failed to fetch projects: ${response.error}
43
+
44
+ **Status:** ${response.statusCode}
45
+
46
+ Please check:
47
+ 1. Your authentication is valid
48
+ 2. The API URL is correct
49
+ 3. You have network connectivity
50
+ `;
51
+ }
52
+ return formatProjectList(response.data);
53
+ }
54
+ /**
55
+ * Format the project list for display
56
+ */
57
+ function formatProjectList(projects) {
58
+ if (!projects || projects.length === 0) {
59
+ return `# No Projects Found
60
+
61
+ You don't have access to any FastMode projects.
62
+
63
+ **To create a project:**
64
+ 1. Go to app.fastmode.ai
65
+ 2. Click "Create New Project"
66
+ 3. Run \`list_projects\` again to see it here
67
+ `;
68
+ }
69
+ // Format the project list
70
+ let output = `# Your FastMode Projects
71
+
72
+ Found ${projects.length} project${projects.length > 1 ? 's' : ''}:
73
+
74
+ `;
75
+ projects.forEach((project, index) => {
76
+ const siteStatus = project.site?.status || 'pending';
77
+ output += `## ${index + 1}. ${project.name}
78
+
79
+ - **Project ID:** \`${project.id}\`
80
+ - **Subdomain:** ${project.subdomain}.fastmode.ai
81
+ ${project.customDomain ? `- **Custom Domain:** ${project.customDomain}\n` : ''}- **Your Role:** ${project.role}
82
+ - **Site Status:** ${siteStatus}
83
+
84
+ `;
85
+ });
86
+ output += `---
87
+
88
+ ## How to Use
89
+
90
+ To get the schema for a project, use:
91
+ \`\`\`
92
+ get_tenant_schema(projectId: "${projects[0]?.id || 'project-id-here'}")
93
+ \`\`\`
94
+
95
+ Or use the project name:
96
+ \`\`\`
97
+ get_tenant_schema(projectId: "${projects[0]?.name || 'Project Name'}")
98
+ \`\`\`
99
+ `;
100
+ return output;
101
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Sync Schema Tool
3
+ *
4
+ * Creates collections and/or fields in Fast Mode.
5
+ * Requires authentication. Will skip duplicates.
6
+ */
7
+ interface FieldToCreate {
8
+ slug: string;
9
+ name: string;
10
+ type: string;
11
+ description?: string;
12
+ isRequired?: boolean;
13
+ options?: string;
14
+ referenceCollection?: string;
15
+ }
16
+ interface CollectionToCreate {
17
+ slug: string;
18
+ name: string;
19
+ nameSingular: string;
20
+ description?: string;
21
+ hasSlug?: boolean;
22
+ fields?: FieldToCreate[];
23
+ }
24
+ interface FieldsToAdd {
25
+ collectionSlug: string;
26
+ isBuiltin?: boolean;
27
+ fields: FieldToCreate[];
28
+ }
29
+ interface SyncSchemaInput {
30
+ projectId: string;
31
+ collections?: CollectionToCreate[];
32
+ fieldsToAdd?: FieldsToAdd[];
33
+ }
34
+ /**
35
+ * Sync schema - create collections and/or fields
36
+ *
37
+ * @param input - The sync schema input with projectId, collections, and/or fieldsToAdd
38
+ */
39
+ export declare function syncSchema(input: SyncSchemaInput): Promise<string>;
40
+ export {};
41
+ //# sourceMappingURL=sync-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-schema.d.ts","sourceRoot":"","sources":["../../src/tools/sync-schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,UAAU,WAAW;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAED,UAAU,eAAe;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACnC,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;CAC7B;AA2KD;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAkZxE"}