aldform-mcp 1.0.3
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 +58 -0
- package/dist/api-client.js +97 -0
- package/dist/api-client.js.map +1 -0
- package/dist/cli.js +33 -0
- package/dist/cli.js.map +1 -0
- package/dist/docs.js +588 -0
- package/dist/docs.js.map +1 -0
- package/dist/server-remote.js +355 -0
- package/dist/server-remote.js.map +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# @aldform/mcp
|
|
2
|
+
|
|
3
|
+
Model Context Protocol server for managing Aldform forms and submissions from any MCP-compatible AI client (Claude, Cursor, Windsurf, Antigravity, etc.).
|
|
4
|
+
|
|
5
|
+
## Quick Install
|
|
6
|
+
|
|
7
|
+
### Claude Code
|
|
8
|
+
```bash
|
|
9
|
+
claude mcp add-json aldform '{"command":"npx","args":["-y","@aldform/mcp","aldform-mcp"],"env":{"ALDFORM_API_KEY":"your_api_key"}}'
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
### Claude Desktop / Antigravity / Other MCP Clients
|
|
13
|
+
|
|
14
|
+
Add to your MCP config (`claude_desktop_config.json`, `mcp_config.json`, etc.):
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"mcpServers": {
|
|
19
|
+
"aldform": {
|
|
20
|
+
"command": "npx",
|
|
21
|
+
"args": ["-y", "@aldform/mcp", "aldform-mcp"],
|
|
22
|
+
"env": {
|
|
23
|
+
"ALDFORM_API_KEY": "your_api_key_here"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Tools
|
|
31
|
+
|
|
32
|
+
| Tool | Description |
|
|
33
|
+
|------|-------------|
|
|
34
|
+
| `create_form` | Create a new form to collect submissions |
|
|
35
|
+
| `list_forms` | List all your forms with submission counts |
|
|
36
|
+
| `get_submissions` | Get paginated submissions for a form |
|
|
37
|
+
| `get_submission` | Get a single submission with full data |
|
|
38
|
+
| `delete_form` | Delete a form and all its submissions |
|
|
39
|
+
| `get_docs` | Read Aldform documentation by topic |
|
|
40
|
+
| `search_docs` | Search Aldform docs by keyword |
|
|
41
|
+
|
|
42
|
+
## Getting Your API Key
|
|
43
|
+
|
|
44
|
+
1. Sign up at [app.aldform.com](https://app.aldform.com)
|
|
45
|
+
2. Go to **Dashboard → Billing** to find your API key
|
|
46
|
+
3. Or check any form's **Setup Guide** tab
|
|
47
|
+
|
|
48
|
+
## How It Works
|
|
49
|
+
|
|
50
|
+
- **Transport:** stdio — your AI client spawns `npx aldform-mcp` as a local process
|
|
51
|
+
- **Authentication:** Your `ALDFORM_API_KEY` env var authenticates all API requests
|
|
52
|
+
- **No database needed:** Calls the hosted Aldform API. No DATABASE_URL or local setup required
|
|
53
|
+
- **Input validation:** All tool arguments validated with Zod schemas
|
|
54
|
+
- **Ownership enforcement:** Users can only access their own forms and submissions
|
|
55
|
+
|
|
56
|
+
## Requirements
|
|
57
|
+
|
|
58
|
+
- Node.js 18+
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* HTTP client that calls the Aldform REST API.
|
|
4
|
+
* Used by the CLI/npx MCP server so it doesn't need DATABASE_URL.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.AldformApiClient = void 0;
|
|
8
|
+
const DEFAULT_API_URL = "https://api.aldform.com";
|
|
9
|
+
class AldformApiClient {
|
|
10
|
+
apiKey;
|
|
11
|
+
apiUrl;
|
|
12
|
+
constructor(apiKey) {
|
|
13
|
+
this.apiKey = apiKey;
|
|
14
|
+
this.apiUrl = (process.env.ALDFORM_API_URL || DEFAULT_API_URL).replace(/\/+$/, "");
|
|
15
|
+
}
|
|
16
|
+
async request(path, options = {}) {
|
|
17
|
+
const res = await fetch(`${this.apiUrl}${path}`, {
|
|
18
|
+
...options,
|
|
19
|
+
headers: {
|
|
20
|
+
"Content-Type": "application/json",
|
|
21
|
+
"x-api-key": this.apiKey,
|
|
22
|
+
...(options.headers || {}),
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
if (!res.ok) {
|
|
26
|
+
const body = await res.json().catch(() => ({}));
|
|
27
|
+
throw new Error(body.error || `API error ${res.status}`);
|
|
28
|
+
}
|
|
29
|
+
return res.json();
|
|
30
|
+
}
|
|
31
|
+
/** Validate the API key and get user info */
|
|
32
|
+
async me() {
|
|
33
|
+
return this.request("/auth/me");
|
|
34
|
+
}
|
|
35
|
+
/** Create a new form */
|
|
36
|
+
async createForm(name) {
|
|
37
|
+
return this.request("/v1/forms", {
|
|
38
|
+
method: "POST",
|
|
39
|
+
body: JSON.stringify({ name }),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/** List all forms for the authenticated user */
|
|
43
|
+
async listForms() {
|
|
44
|
+
return this.request("/v1/forms");
|
|
45
|
+
}
|
|
46
|
+
/** Delete a form */
|
|
47
|
+
async deleteForm(formId) {
|
|
48
|
+
return this.request(`/v1/forms/${formId}`, { method: "DELETE" });
|
|
49
|
+
}
|
|
50
|
+
/** Get paginated submissions for a form */
|
|
51
|
+
async getSubmissions(formId, page = 1, limit = 20) {
|
|
52
|
+
return this.request(`/v1/forms/${formId}/submissions?page=${page}&limit=${limit}`);
|
|
53
|
+
}
|
|
54
|
+
/** Get a single submission */
|
|
55
|
+
async getSubmission(formId, submissionId) {
|
|
56
|
+
return this.request(`/v1/forms/${formId}/submissions/${submissionId}`);
|
|
57
|
+
}
|
|
58
|
+
/** List all email templates */
|
|
59
|
+
async listTemplates() {
|
|
60
|
+
return this.request("/v1/templates");
|
|
61
|
+
}
|
|
62
|
+
/** Get a single email template */
|
|
63
|
+
async getTemplate(templateId) {
|
|
64
|
+
return this.request(`/v1/templates/${templateId}`);
|
|
65
|
+
}
|
|
66
|
+
/** Create an email template */
|
|
67
|
+
async createTemplate(data) {
|
|
68
|
+
return this.request("/v1/templates", {
|
|
69
|
+
method: "POST",
|
|
70
|
+
body: JSON.stringify(data),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/** Update an email template */
|
|
74
|
+
async updateTemplate(templateId, data) {
|
|
75
|
+
return this.request(`/v1/templates/${templateId}`, {
|
|
76
|
+
method: "PUT",
|
|
77
|
+
body: JSON.stringify(data),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/** Delete an email template */
|
|
81
|
+
async deleteTemplate(templateId) {
|
|
82
|
+
return this.request(`/v1/templates/${templateId}`, { method: "DELETE" });
|
|
83
|
+
}
|
|
84
|
+
/** Preview a rendered email template */
|
|
85
|
+
async previewTemplate(templateId, sampleData) {
|
|
86
|
+
return this.request(`/v1/templates/${templateId}/preview`, {
|
|
87
|
+
method: "POST",
|
|
88
|
+
body: JSON.stringify({ sampleData }),
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/** Send a test email for a template */
|
|
92
|
+
async testTemplate(templateId) {
|
|
93
|
+
return this.request(`/v1/templates/${templateId}/test`, { method: "POST" });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
exports.AldformApiClient = AldformApiClient;
|
|
97
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
5
|
+
const server_remote_1 = require("./server-remote");
|
|
6
|
+
const api_client_1 = require("./api-client");
|
|
7
|
+
async function main() {
|
|
8
|
+
const apiKey = process.env.ALDFORM_API_KEY;
|
|
9
|
+
if (!apiKey) {
|
|
10
|
+
console.error("Error: ALDFORM_API_KEY environment variable is required.\n" +
|
|
11
|
+
"Set it in your MCP client config:\n\n" +
|
|
12
|
+
' "env": { "ALDFORM_API_KEY": "your_api_key_here" }\n');
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
// Validate the API key against the hosted API
|
|
16
|
+
try {
|
|
17
|
+
const client = new api_client_1.AldformApiClient(apiKey);
|
|
18
|
+
const user = await client.me();
|
|
19
|
+
console.error(`Aldform MCP server running (user: ${user.email || user.id})`);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
console.error("Error: Invalid ALDFORM_API_KEY. Check your API key in the Aldform dashboard.");
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
const server = (0, server_remote_1.createRemoteMcpServer)(apiKey);
|
|
26
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
27
|
+
await server.connect(transport);
|
|
28
|
+
}
|
|
29
|
+
main().catch((err) => {
|
|
30
|
+
console.error("Fatal error:", err.message);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,wEAAiF;AACjF,mDAAwD;AACxD,6CAAgD;AAEhD,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CACX,4DAA4D;YAC1D,uCAAuC;YACvC,uDAAuD,CAC1D,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,8CAA8C;IAC9C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,6BAAgB,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,EAAE,EAAE,CAAC;QAC/B,OAAO,CAAC,KAAK,CAAC,qCAAqC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IAC/E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,8EAA8E,CAAC,CAAC;QAC9F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAA,qCAAqB,EAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/docs.js
ADDED
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DOCS = void 0;
|
|
4
|
+
exports.DOCS = {
|
|
5
|
+
overview: {
|
|
6
|
+
title: "Overview",
|
|
7
|
+
description: "What Aldform is, how it works, and core concepts",
|
|
8
|
+
content: `# Aldform Overview
|
|
9
|
+
|
|
10
|
+
Aldform is a form submission API. You send form data to our endpoint and we store it, send email notifications, and track usage. There's no backend to build — just point your form at the API.
|
|
11
|
+
|
|
12
|
+
## How It Works
|
|
13
|
+
|
|
14
|
+
1. Create a form in the dashboard — you get a Form ID and API Key.
|
|
15
|
+
2. POST your form data (JSON or multipart) to /v1/forms/{formId}/submit.
|
|
16
|
+
3. View submissions in the dashboard, or fetch them via GET /v1/forms/{formId}/submissions.
|
|
17
|
+
|
|
18
|
+
## Base URL
|
|
19
|
+
|
|
20
|
+
https://api.aldform.com
|
|
21
|
+
|
|
22
|
+
## Authentication
|
|
23
|
+
|
|
24
|
+
All API requests require an x-api-key header with your API key.
|
|
25
|
+
|
|
26
|
+
## Core Concepts
|
|
27
|
+
|
|
28
|
+
- **Form**: A container for submissions. Has a unique ID and name.
|
|
29
|
+
- **Submission**: A single form entry. Contains JSON data and optional file uploads.
|
|
30
|
+
- **API Key**: Your authentication credential. Found in the dashboard.
|
|
31
|
+
- **Sections**: Group related fields in submissions using the _sections key.`,
|
|
32
|
+
},
|
|
33
|
+
quickstart: {
|
|
34
|
+
title: "Quick Start",
|
|
35
|
+
description: "Get up and running in under 5 minutes with code examples",
|
|
36
|
+
content: `# Quick Start
|
|
37
|
+
|
|
38
|
+
## 1. Get Your Credentials
|
|
39
|
+
|
|
40
|
+
Sign up at app.aldform.com, create a form, and copy your Form ID and API Key.
|
|
41
|
+
|
|
42
|
+
## 2. Submit Your First Form (HTML)
|
|
43
|
+
|
|
44
|
+
\`\`\`html
|
|
45
|
+
<form id="my-form">
|
|
46
|
+
<input name="name" placeholder="Name" required />
|
|
47
|
+
<input name="email" type="email" placeholder="Email" required />
|
|
48
|
+
<textarea name="message" placeholder="Message"></textarea>
|
|
49
|
+
<button type="submit">Send</button>
|
|
50
|
+
</form>
|
|
51
|
+
|
|
52
|
+
<script>
|
|
53
|
+
document.getElementById('my-form').addEventListener('submit', async (e) => {
|
|
54
|
+
e.preventDefault();
|
|
55
|
+
const data = Object.fromEntries(new FormData(e.target));
|
|
56
|
+
const res = await fetch('https://api.aldform.com/v1/forms/FORM_ID/submit', {
|
|
57
|
+
method: 'POST',
|
|
58
|
+
headers: {
|
|
59
|
+
'Content-Type': 'application/json',
|
|
60
|
+
'x-api-key': 'YOUR_API_KEY'
|
|
61
|
+
},
|
|
62
|
+
body: JSON.stringify(data)
|
|
63
|
+
});
|
|
64
|
+
if (res.ok) {
|
|
65
|
+
alert('Submitted!');
|
|
66
|
+
e.target.reset();
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
</script>
|
|
70
|
+
\`\`\`
|
|
71
|
+
|
|
72
|
+
## 3. Fetch Submissions
|
|
73
|
+
|
|
74
|
+
\`\`\`javascript
|
|
75
|
+
const res = await fetch('https://api.aldform.com/v1/forms/FORM_ID/submissions?page=1&limit=20', {
|
|
76
|
+
headers: { 'x-api-key': 'YOUR_API_KEY' }
|
|
77
|
+
});
|
|
78
|
+
const { form, meta } = await res.json();
|
|
79
|
+
console.log(form.submissions); // Array of submissions
|
|
80
|
+
console.log(meta); // { total, page, limit, totalPages }
|
|
81
|
+
\`\`\``,
|
|
82
|
+
},
|
|
83
|
+
authentication: {
|
|
84
|
+
title: "Authentication",
|
|
85
|
+
description: "How to authenticate API requests using x-api-key header",
|
|
86
|
+
content: `# Authentication
|
|
87
|
+
|
|
88
|
+
All API requests must include your API key in the x-api-key header.
|
|
89
|
+
|
|
90
|
+
## Header Format
|
|
91
|
+
|
|
92
|
+
\`\`\`
|
|
93
|
+
x-api-key: your_api_key_here
|
|
94
|
+
\`\`\`
|
|
95
|
+
|
|
96
|
+
## Example
|
|
97
|
+
|
|
98
|
+
\`\`\`javascript
|
|
99
|
+
const res = await fetch('https://api.aldform.com/v1/forms', {
|
|
100
|
+
headers: { 'x-api-key': 'your_api_key_here' }
|
|
101
|
+
});
|
|
102
|
+
\`\`\`
|
|
103
|
+
|
|
104
|
+
## Where to Find Your API Key
|
|
105
|
+
|
|
106
|
+
1. Log in to the Aldform dashboard at app.aldform.com
|
|
107
|
+
2. Your API key is displayed on the main Dashboard page
|
|
108
|
+
3. You can also find it on the Account page
|
|
109
|
+
|
|
110
|
+
## API Key Security
|
|
111
|
+
|
|
112
|
+
- Your API key identifies your account and all submissions are counted against your usage
|
|
113
|
+
- API keys are safe to use in client-side code for public-facing forms
|
|
114
|
+
- You can regenerate your API key from the Account page (this invalidates the old key)
|
|
115
|
+
- Never share your API key in public repositories if your forms collect sensitive data
|
|
116
|
+
|
|
117
|
+
## Rate Limiting
|
|
118
|
+
|
|
119
|
+
All endpoints are rate-limited to 20 requests per minute per IP address. If exceeded, you'll receive a 429 status code.`,
|
|
120
|
+
},
|
|
121
|
+
submit: {
|
|
122
|
+
title: "Submitting Forms",
|
|
123
|
+
description: "How to submit form data via POST, including JSON and multipart formats",
|
|
124
|
+
content: `# Submitting Forms
|
|
125
|
+
|
|
126
|
+
## Endpoint
|
|
127
|
+
|
|
128
|
+
POST https://api.aldform.com/v1/forms/{formId}/submit
|
|
129
|
+
|
|
130
|
+
## JSON Submission
|
|
131
|
+
|
|
132
|
+
For text-only forms, use JSON:
|
|
133
|
+
|
|
134
|
+
\`\`\`javascript
|
|
135
|
+
const res = await fetch('https://api.aldform.com/v1/forms/FORM_ID/submit', {
|
|
136
|
+
method: 'POST',
|
|
137
|
+
headers: {
|
|
138
|
+
'Content-Type': 'application/json',
|
|
139
|
+
'x-api-key': 'YOUR_API_KEY'
|
|
140
|
+
},
|
|
141
|
+
body: JSON.stringify({
|
|
142
|
+
name: 'Jane Doe',
|
|
143
|
+
email: 'jane@example.com',
|
|
144
|
+
message: 'Hello!'
|
|
145
|
+
})
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const data = await res.json();
|
|
149
|
+
// { success: true, submissionId: "clx..." }
|
|
150
|
+
\`\`\`
|
|
151
|
+
|
|
152
|
+
## Multipart Submission (with files)
|
|
153
|
+
|
|
154
|
+
For forms with file uploads, use FormData:
|
|
155
|
+
|
|
156
|
+
\`\`\`javascript
|
|
157
|
+
const formData = new FormData();
|
|
158
|
+
formData.append('name', 'Jane Doe');
|
|
159
|
+
formData.append('resume', fileInput.files[0]);
|
|
160
|
+
|
|
161
|
+
const res = await fetch('https://api.aldform.com/v1/forms/FORM_ID/submit', {
|
|
162
|
+
method: 'POST',
|
|
163
|
+
headers: { 'x-api-key': 'YOUR_API_KEY' },
|
|
164
|
+
// Do NOT set Content-Type — browser sets it with multipart boundary
|
|
165
|
+
body: formData
|
|
166
|
+
});
|
|
167
|
+
\`\`\`
|
|
168
|
+
|
|
169
|
+
## cURL Examples
|
|
170
|
+
|
|
171
|
+
JSON:
|
|
172
|
+
\`\`\`bash
|
|
173
|
+
curl -X POST 'https://api.aldform.com/v1/forms/FORM_ID/submit' \\
|
|
174
|
+
-H 'Content-Type: application/json' \\
|
|
175
|
+
-H 'x-api-key: YOUR_API_KEY' \\
|
|
176
|
+
-d '{"name":"Jane","email":"jane@example.com"}'
|
|
177
|
+
\`\`\`
|
|
178
|
+
|
|
179
|
+
File upload:
|
|
180
|
+
\`\`\`bash
|
|
181
|
+
curl -X POST 'https://api.aldform.com/v1/forms/FORM_ID/submit' \\
|
|
182
|
+
-H 'x-api-key: YOUR_API_KEY' \\
|
|
183
|
+
-F 'name=Jane Doe' \\
|
|
184
|
+
-F 'resume=@/path/to/resume.pdf'
|
|
185
|
+
\`\`\`
|
|
186
|
+
|
|
187
|
+
## Response
|
|
188
|
+
|
|
189
|
+
Success (201):
|
|
190
|
+
\`\`\`json
|
|
191
|
+
{ "success": true, "submissionId": "clx..." }
|
|
192
|
+
\`\`\`
|
|
193
|
+
|
|
194
|
+
## Important Notes
|
|
195
|
+
|
|
196
|
+
- All fields are stored as-is — Aldform is schema-less
|
|
197
|
+
- You can send any JSON structure, including nested objects
|
|
198
|
+
- The API key authenticates the request; the form ID determines where data is stored
|
|
199
|
+
- Email notifications are sent to the form owner on each submission`,
|
|
200
|
+
},
|
|
201
|
+
submissions: {
|
|
202
|
+
title: "Fetching Submissions",
|
|
203
|
+
description: "How to list and retrieve submissions with pagination",
|
|
204
|
+
content: `# Fetching Submissions
|
|
205
|
+
|
|
206
|
+
## List Submissions (Paginated)
|
|
207
|
+
|
|
208
|
+
GET https://api.aldform.com/v1/forms/{formId}/submissions?page=1&limit=20
|
|
209
|
+
|
|
210
|
+
### Parameters
|
|
211
|
+
|
|
212
|
+
| Parameter | Default | Max | Description |
|
|
213
|
+
|-----------|---------|-----|-------------|
|
|
214
|
+
| page | 1 | — | Page number |
|
|
215
|
+
| limit | 20 | 100 | Results per page |
|
|
216
|
+
|
|
217
|
+
### Response
|
|
218
|
+
|
|
219
|
+
\`\`\`json
|
|
220
|
+
{
|
|
221
|
+
"form": {
|
|
222
|
+
"id": "clx...",
|
|
223
|
+
"name": "Contact Form",
|
|
224
|
+
"submissions": [
|
|
225
|
+
{
|
|
226
|
+
"id": "clx...",
|
|
227
|
+
"data": { "name": "Jane", "email": "jane@example.com" },
|
|
228
|
+
"files": null,
|
|
229
|
+
"createdAt": "2026-03-14T..."
|
|
230
|
+
}
|
|
231
|
+
],
|
|
232
|
+
"_count": { "submissions": 42 }
|
|
233
|
+
},
|
|
234
|
+
"meta": {
|
|
235
|
+
"total": 42,
|
|
236
|
+
"page": 1,
|
|
237
|
+
"limit": 20,
|
|
238
|
+
"totalPages": 3
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
\`\`\`
|
|
242
|
+
|
|
243
|
+
IMPORTANT: Submissions are at response.form.submissions, NOT response.submissions.
|
|
244
|
+
|
|
245
|
+
## Get Single Submission
|
|
246
|
+
|
|
247
|
+
GET https://api.aldform.com/v1/forms/{formId}/submissions/{submissionId}
|
|
248
|
+
|
|
249
|
+
### Response
|
|
250
|
+
|
|
251
|
+
\`\`\`json
|
|
252
|
+
{
|
|
253
|
+
"submission": {
|
|
254
|
+
"id": "clx...",
|
|
255
|
+
"formId": "clx...",
|
|
256
|
+
"data": { "name": "Jane", ... },
|
|
257
|
+
"files": {
|
|
258
|
+
"resume": {
|
|
259
|
+
"url": "https://...",
|
|
260
|
+
"size": 52400,
|
|
261
|
+
"name": "resume.pdf",
|
|
262
|
+
"type": "application/pdf"
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
"createdAt": "2026-03-14T..."
|
|
266
|
+
},
|
|
267
|
+
"form": { "id": "clx...", "name": "Contact Form" },
|
|
268
|
+
"prev": "clx...",
|
|
269
|
+
"next": "clx..."
|
|
270
|
+
}
|
|
271
|
+
\`\`\`
|
|
272
|
+
|
|
273
|
+
The prev and next fields contain adjacent submission IDs for navigation. File URLs are pre-signed and valid for 1 hour.`,
|
|
274
|
+
},
|
|
275
|
+
files: {
|
|
276
|
+
title: "File Uploads",
|
|
277
|
+
description: "Supported file types, size limits, and how to upload files with submissions",
|
|
278
|
+
content: `# File Uploads
|
|
279
|
+
|
|
280
|
+
## How It Works
|
|
281
|
+
|
|
282
|
+
Send files alongside form data using multipart/form-data. Files are stored in S3 and pre-signed download URLs are generated when you fetch a submission.
|
|
283
|
+
|
|
284
|
+
## Constraints
|
|
285
|
+
|
|
286
|
+
| Constraint | Value |
|
|
287
|
+
|-------------------|------------------------------------------------|
|
|
288
|
+
| Max file size | 10 MB per file |
|
|
289
|
+
| Allowed types | Images (jpg, png, gif, webp), Documents (pdf, doc, docx), Text (txt) |
|
|
290
|
+
| Storage metering | Billed at ₹5/GB per month for Cloud plan users |
|
|
291
|
+
|
|
292
|
+
## Upload Example (HTML)
|
|
293
|
+
|
|
294
|
+
\`\`\`html
|
|
295
|
+
<form id="upload-form">
|
|
296
|
+
<input name="name" placeholder="Name" required />
|
|
297
|
+
<input name="resume" type="file" accept=".pdf,.doc,.docx" />
|
|
298
|
+
<button type="submit">Send</button>
|
|
299
|
+
</form>
|
|
300
|
+
|
|
301
|
+
<script>
|
|
302
|
+
document.getElementById('upload-form').addEventListener('submit', async (e) => {
|
|
303
|
+
e.preventDefault();
|
|
304
|
+
const formData = new FormData(e.target);
|
|
305
|
+
const res = await fetch('https://api.aldform.com/v1/forms/FORM_ID/submit', {
|
|
306
|
+
method: 'POST',
|
|
307
|
+
headers: { 'x-api-key': 'YOUR_API_KEY' },
|
|
308
|
+
body: formData // No Content-Type header — browser sets it
|
|
309
|
+
});
|
|
310
|
+
if (res.ok) alert('Submitted!');
|
|
311
|
+
});
|
|
312
|
+
</script>
|
|
313
|
+
\`\`\`
|
|
314
|
+
|
|
315
|
+
## File Metadata in Submissions
|
|
316
|
+
|
|
317
|
+
When you fetch a single submission (GET /v1/forms/{formId}/submissions/{subId}), files include pre-signed download URLs:
|
|
318
|
+
|
|
319
|
+
\`\`\`json
|
|
320
|
+
{
|
|
321
|
+
"files": {
|
|
322
|
+
"resume": {
|
|
323
|
+
"url": "https://s3.amazonaws.com/...",
|
|
324
|
+
"size": 52400,
|
|
325
|
+
"name": "resume.pdf",
|
|
326
|
+
"type": "application/pdf"
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
\`\`\`
|
|
331
|
+
|
|
332
|
+
Pre-signed URLs expire after 1 hour. When listing submissions, file URLs are not included to avoid generating many pre-signed URLs.
|
|
333
|
+
|
|
334
|
+
## Error Responses
|
|
335
|
+
|
|
336
|
+
- 400 "File too large (max 10MB)" — file exceeds size limit
|
|
337
|
+
- 400 "File type not allowed" — unsupported MIME type`,
|
|
338
|
+
},
|
|
339
|
+
sections: {
|
|
340
|
+
title: "Sections (Grouped Fields)",
|
|
341
|
+
description: "How to group related fields into collapsible sections in submissions",
|
|
342
|
+
content: `# Sections (Grouped Fields)
|
|
343
|
+
|
|
344
|
+
Submissions can contain nested, grouped fields using the _sections convention. Sections appear as collapsible groups in the dashboard's submission detail page.
|
|
345
|
+
|
|
346
|
+
## How It Works
|
|
347
|
+
|
|
348
|
+
Include a _sections key in your submission body. Each key within _sections becomes a collapsible section in the dashboard.
|
|
349
|
+
|
|
350
|
+
## Example
|
|
351
|
+
|
|
352
|
+
\`\`\`json
|
|
353
|
+
{
|
|
354
|
+
"timestamp": "2026-03-15T10:30:00Z",
|
|
355
|
+
"source": "website",
|
|
356
|
+
"_sections": {
|
|
357
|
+
"contact": {
|
|
358
|
+
"name": "Jane Doe",
|
|
359
|
+
"email": "jane@example.com",
|
|
360
|
+
"phone": "+1-555-0123"
|
|
361
|
+
},
|
|
362
|
+
"order": {
|
|
363
|
+
"product": "Pro Plan",
|
|
364
|
+
"amount": 49.99,
|
|
365
|
+
"currency": "USD"
|
|
366
|
+
},
|
|
367
|
+
"shipping": {
|
|
368
|
+
"address": "123 Main St",
|
|
369
|
+
"city": "San Francisco",
|
|
370
|
+
"state": "CA",
|
|
371
|
+
"zip": "94102"
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
\`\`\`
|
|
376
|
+
|
|
377
|
+
## Submitting with Sections
|
|
378
|
+
|
|
379
|
+
\`\`\`javascript
|
|
380
|
+
const res = await fetch('https://api.aldform.com/v1/forms/FORM_ID/submit', {
|
|
381
|
+
method: 'POST',
|
|
382
|
+
headers: {
|
|
383
|
+
'Content-Type': 'application/json',
|
|
384
|
+
'x-api-key': 'YOUR_API_KEY'
|
|
385
|
+
},
|
|
386
|
+
body: JSON.stringify({
|
|
387
|
+
source: 'website',
|
|
388
|
+
_sections: {
|
|
389
|
+
contact: { name: 'Jane Doe', email: 'jane@example.com' },
|
|
390
|
+
order: { product: 'Pro Plan', amount: 49.99 }
|
|
391
|
+
}
|
|
392
|
+
})
|
|
393
|
+
});
|
|
394
|
+
\`\`\`
|
|
395
|
+
|
|
396
|
+
## SDK Support
|
|
397
|
+
|
|
398
|
+
\`\`\`javascript
|
|
399
|
+
import Aldform from '@aldform/sdk';
|
|
400
|
+
|
|
401
|
+
const form = new Aldform('YOUR_API_KEY', 'FORM_ID');
|
|
402
|
+
|
|
403
|
+
const contact = form.section('contact');
|
|
404
|
+
contact.set('name', 'Jane Doe');
|
|
405
|
+
contact.set('email', 'jane@example.com');
|
|
406
|
+
|
|
407
|
+
const order = form.section('order');
|
|
408
|
+
order.set('product', 'Pro Plan');
|
|
409
|
+
order.set('amount', 49.99);
|
|
410
|
+
|
|
411
|
+
await form.submitWithSections();
|
|
412
|
+
\`\`\`
|
|
413
|
+
|
|
414
|
+
## Dashboard Behavior
|
|
415
|
+
|
|
416
|
+
- Fields outside _sections appear at the top level of the submission detail
|
|
417
|
+
- Each section renders as a collapsible card labeled with the section name (capitalized)
|
|
418
|
+
- Sections are expanded by default and can be collapsed by clicking
|
|
419
|
+
- Nested objects within sections are rendered recursively with indentation
|
|
420
|
+
- In the submissions list view, _sections fields are excluded from the preview`,
|
|
421
|
+
},
|
|
422
|
+
errors: {
|
|
423
|
+
title: "Error Handling",
|
|
424
|
+
description: "All error codes, error response format, and how to handle them",
|
|
425
|
+
content: `# Error Handling
|
|
426
|
+
|
|
427
|
+
## Error Response Format
|
|
428
|
+
|
|
429
|
+
All errors return a JSON body with an "error" field:
|
|
430
|
+
|
|
431
|
+
\`\`\`json
|
|
432
|
+
{ "error": "Description of what went wrong" }
|
|
433
|
+
\`\`\`
|
|
434
|
+
|
|
435
|
+
## HTTP Status Codes
|
|
436
|
+
|
|
437
|
+
| Code | Meaning | Common Causes |
|
|
438
|
+
|------|---------|---------------|
|
|
439
|
+
| 400 | Bad Request | Missing required fields, invalid JSON, file too large, unsupported file type |
|
|
440
|
+
| 401 | Unauthorized | Missing or invalid x-api-key header |
|
|
441
|
+
| 404 | Not Found | Form ID doesn't exist or doesn't belong to you |
|
|
442
|
+
| 429 | Too Many Requests | Rate limit exceeded (20 req/min per IP) |
|
|
443
|
+
| 500 | Internal Server Error | Server-side issue — retry after a moment |
|
|
444
|
+
|
|
445
|
+
## Common Errors and Solutions
|
|
446
|
+
|
|
447
|
+
### "Email and password are required"
|
|
448
|
+
Status 400. Both email and password must be provided for login/register.
|
|
449
|
+
|
|
450
|
+
### "Invalid or missing API key"
|
|
451
|
+
Status 401. Check that your x-api-key header is set correctly.
|
|
452
|
+
|
|
453
|
+
### "Form not found"
|
|
454
|
+
Status 404. The form ID is incorrect or the form belongs to a different account.
|
|
455
|
+
|
|
456
|
+
### "File too large (max 10MB)"
|
|
457
|
+
Status 400. Reduce file size or compress before uploading.
|
|
458
|
+
|
|
459
|
+
### "File type not allowed"
|
|
460
|
+
Status 400. Only these types are accepted: jpg, png, gif, webp, pdf, doc, docx, txt.
|
|
461
|
+
|
|
462
|
+
### Rate limited (429)
|
|
463
|
+
Wait 60 seconds before retrying. The rate limit is per IP address.
|
|
464
|
+
|
|
465
|
+
## Best Practices
|
|
466
|
+
|
|
467
|
+
- Always check res.ok before parsing the response
|
|
468
|
+
- Display the error message to users for 4xx errors
|
|
469
|
+
- Retry once for 5xx errors after a short delay
|
|
470
|
+
- Use try/catch around fetch calls to handle network errors`,
|
|
471
|
+
},
|
|
472
|
+
sdk: {
|
|
473
|
+
title: "SDK",
|
|
474
|
+
description: "Using the @aldform/sdk npm package for JavaScript/TypeScript",
|
|
475
|
+
content: `# Aldform SDK
|
|
476
|
+
|
|
477
|
+
The @aldform/sdk package provides a simple JavaScript/TypeScript client for Aldform.
|
|
478
|
+
|
|
479
|
+
## Installation
|
|
480
|
+
|
|
481
|
+
\`\`\`bash
|
|
482
|
+
npm install @aldform/sdk
|
|
483
|
+
\`\`\`
|
|
484
|
+
|
|
485
|
+
## Basic Usage
|
|
486
|
+
|
|
487
|
+
\`\`\`javascript
|
|
488
|
+
import Aldform from '@aldform/sdk';
|
|
489
|
+
|
|
490
|
+
const form = new Aldform('YOUR_API_KEY', 'FORM_ID');
|
|
491
|
+
|
|
492
|
+
// Simple submission
|
|
493
|
+
await form.submit({
|
|
494
|
+
name: 'Jane Doe',
|
|
495
|
+
email: 'jane@example.com',
|
|
496
|
+
message: 'Hello!'
|
|
497
|
+
});
|
|
498
|
+
\`\`\`
|
|
499
|
+
|
|
500
|
+
## File Uploads
|
|
501
|
+
|
|
502
|
+
Files are auto-detected — the SDK switches to multipart/form-data automatically:
|
|
503
|
+
|
|
504
|
+
\`\`\`javascript
|
|
505
|
+
const fileInput = document.querySelector('input[type="file"]');
|
|
506
|
+
|
|
507
|
+
await form.submit({
|
|
508
|
+
name: 'Jane Doe',
|
|
509
|
+
resume: fileInput.files[0] // File object
|
|
510
|
+
});
|
|
511
|
+
\`\`\`
|
|
512
|
+
|
|
513
|
+
## Sections
|
|
514
|
+
|
|
515
|
+
Use the section builder for grouped fields:
|
|
516
|
+
|
|
517
|
+
\`\`\`javascript
|
|
518
|
+
const contact = form.section('contact');
|
|
519
|
+
contact.set('name', 'Jane Doe');
|
|
520
|
+
contact.set('email', 'jane@example.com');
|
|
521
|
+
|
|
522
|
+
const order = form.section('order');
|
|
523
|
+
order.set('product', 'Pro Plan');
|
|
524
|
+
order.set('amount', 49.99);
|
|
525
|
+
|
|
526
|
+
await form.submitWithSections();
|
|
527
|
+
\`\`\`
|
|
528
|
+
|
|
529
|
+
## Custom Base URL
|
|
530
|
+
|
|
531
|
+
For self-hosted or development:
|
|
532
|
+
|
|
533
|
+
\`\`\`javascript
|
|
534
|
+
const form = new Aldform('API_KEY', 'FORM_ID', 'http://localhost:4000');
|
|
535
|
+
\`\`\``,
|
|
536
|
+
},
|
|
537
|
+
limits: {
|
|
538
|
+
title: "Limits & Billing",
|
|
539
|
+
description: "Free tier limits, paid plan details, rate limits, and usage metering",
|
|
540
|
+
content: `# Limits & Billing
|
|
541
|
+
|
|
542
|
+
## Free Tier
|
|
543
|
+
|
|
544
|
+
| Resource | Limit |
|
|
545
|
+
|----------|-------|
|
|
546
|
+
| Submissions | 100 per month |
|
|
547
|
+
| Forms | Unlimited |
|
|
548
|
+
| File uploads | 10 MB per file |
|
|
549
|
+
| Rate limit | 20 requests per minute per IP |
|
|
550
|
+
| File types | Images, PDFs, Word docs, text |
|
|
551
|
+
|
|
552
|
+
## Cloud Plan (Paid)
|
|
553
|
+
|
|
554
|
+
After 100 submissions/month, usage is metered via Polar.sh:
|
|
555
|
+
- Overage submissions are billed at the end of each month
|
|
556
|
+
- File storage is billed at ₹5/GB per month
|
|
557
|
+
- Priority email delivery
|
|
558
|
+
- Usage analytics & reports
|
|
559
|
+
|
|
560
|
+
## Email Notifications
|
|
561
|
+
|
|
562
|
+
You receive automatic email notifications at:
|
|
563
|
+
- 80% usage (80 submissions) — warning
|
|
564
|
+
- 100% usage (100 submissions) — limit reached
|
|
565
|
+
- On every form submission — to the form owner's email
|
|
566
|
+
|
|
567
|
+
Emails are sent from billing@billing.aldform.com and notifications@aldform.com.
|
|
568
|
+
|
|
569
|
+
## Rate Limits
|
|
570
|
+
|
|
571
|
+
| Scope | Limit |
|
|
572
|
+
|-------|-------|
|
|
573
|
+
| Per IP | 20 requests per 60 seconds |
|
|
574
|
+
| Applies to | All endpoints |
|
|
575
|
+
| Response | 429 Too Many Requests |
|
|
576
|
+
|
|
577
|
+
When rate limited, wait 60 seconds before retrying.
|
|
578
|
+
|
|
579
|
+
## Usage Tracking
|
|
580
|
+
|
|
581
|
+
View your usage in real-time on the Billing page of the dashboard:
|
|
582
|
+
- Total submissions this month
|
|
583
|
+
- Per-form breakdown
|
|
584
|
+
- File storage used
|
|
585
|
+
- Invoice history (for Cloud plan users)`,
|
|
586
|
+
},
|
|
587
|
+
};
|
|
588
|
+
//# sourceMappingURL=docs.js.map
|
package/dist/docs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":";;;AAMa,QAAA,IAAI,GAA6B;IAC5C,QAAQ,EAAE;QACR,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,kDAAkD;QAC/D,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;6EAuBgE;KAC1E;IAED,UAAU,EAAE;QACV,KAAK,EAAE,aAAa;QACpB,WAAW,EAAE,0DAA0D;QACvE,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6CN;KACJ;IAED,cAAc,EAAE;QACd,KAAK,EAAE,gBAAgB;QACvB,WAAW,EAAE,yDAAyD;QACtE,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wHAiC2G;KACrH;IAED,MAAM,EAAE;QACN,KAAK,EAAE,kBAAkB;QACzB,WAAW,EAAE,wEAAwE;QACrF,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oEA2EuD;KACjE;IAED,WAAW,EAAE;QACX,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EAAE,sDAAsD;QACnE,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wHAqE2G;KACrH;IAED,KAAK,EAAE;QACL,KAAK,EAAE,cAAc;QACrB,WAAW,EAAE,6EAA6E;QAC1F,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sDA2DyC;KACnD;IAED,QAAQ,EAAE;QACR,KAAK,EAAE,2BAA2B;QAClC,WAAW,EAAE,sEAAsE;QACnF,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+EA8EkE;KAC5E;IAED,MAAM,EAAE;QACN,KAAK,EAAE,gBAAgB;QACvB,WAAW,EAAE,gEAAgE;QAC7E,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4DA6C+C;KACzD;IAED,GAAG,EAAE;QACH,KAAK,EAAE,KAAK;QACZ,WAAW,EAAE,8DAA8D;QAC3E,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4DN;KACJ;IAED,MAAM,EAAE;QACN,KAAK,EAAE,kBAAkB;QACzB,WAAW,EAAE,sEAAsE;QACnF,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCA6C4B;KACtC;CACF,CAAC"}
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRemoteMcpServer = createRemoteMcpServer;
|
|
4
|
+
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
const api_client_1 = require("./api-client");
|
|
7
|
+
const docs_1 = require("./docs");
|
|
8
|
+
/**
|
|
9
|
+
* Create an MCP server that calls the Aldform REST API over HTTP.
|
|
10
|
+
* Used by the CLI (npx) — no DATABASE_URL or Prisma needed.
|
|
11
|
+
*/
|
|
12
|
+
function createRemoteMcpServer(apiKey) {
|
|
13
|
+
const client = new api_client_1.AldformApiClient(apiKey);
|
|
14
|
+
const server = new mcp_js_1.McpServer({
|
|
15
|
+
name: "aldform",
|
|
16
|
+
version: "1.0.0",
|
|
17
|
+
});
|
|
18
|
+
// ─── create_form ───
|
|
19
|
+
// @ts-ignore — MCP SDK type depth limit with many tools
|
|
20
|
+
server.tool("create_form", "Create a new form to collect submissions", {
|
|
21
|
+
name: zod_1.z.string().min(1).max(200).describe("Name for the new form"),
|
|
22
|
+
}, async (args) => {
|
|
23
|
+
try {
|
|
24
|
+
const data = await client.createForm(args.name);
|
|
25
|
+
return textResult({
|
|
26
|
+
message: `Form "${data.form.name}" created successfully`,
|
|
27
|
+
form: {
|
|
28
|
+
id: data.form.id,
|
|
29
|
+
name: data.form.name,
|
|
30
|
+
createdAt: data.form.createdAt,
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
return textError(err.message);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
// ─── list_forms ───
|
|
39
|
+
server.tool("list_forms", "List all forms owned by the authenticated user", {}, async () => {
|
|
40
|
+
try {
|
|
41
|
+
const data = await client.listForms();
|
|
42
|
+
const forms = (data.forms || []).map((f) => ({
|
|
43
|
+
id: f.id,
|
|
44
|
+
name: f.name,
|
|
45
|
+
createdAt: f.createdAt,
|
|
46
|
+
submissionCount: f._count?.submissions ?? 0,
|
|
47
|
+
}));
|
|
48
|
+
return textResult({ forms, total: forms.length });
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
return textError(err.message);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
// ─── get_submissions ───
|
|
55
|
+
server.tool("get_submissions", "Get paginated submissions for a form", {
|
|
56
|
+
formId: zod_1.z.string().min(1).describe("The form ID to fetch submissions for"),
|
|
57
|
+
page: zod_1.z.number().int().min(1).default(1).describe("Page number (default 1)"),
|
|
58
|
+
limit: zod_1.z
|
|
59
|
+
.number()
|
|
60
|
+
.int()
|
|
61
|
+
.min(1)
|
|
62
|
+
.max(100)
|
|
63
|
+
.default(20)
|
|
64
|
+
.describe("Results per page (default 20, max 100)"),
|
|
65
|
+
}, async (args) => {
|
|
66
|
+
try {
|
|
67
|
+
const data = await client.getSubmissions(args.formId, args.page, args.limit);
|
|
68
|
+
const submissions = (data.form?.submissions || []).map((s) => ({
|
|
69
|
+
id: s.id,
|
|
70
|
+
data: s.data,
|
|
71
|
+
hasFiles: s.files !== null,
|
|
72
|
+
fileCount: s.files && typeof s.files === "object" ? Object.keys(s.files).length : 0,
|
|
73
|
+
createdAt: s.createdAt,
|
|
74
|
+
}));
|
|
75
|
+
return textResult({
|
|
76
|
+
form: { id: data.form?.id, name: data.form?.name },
|
|
77
|
+
submissions,
|
|
78
|
+
meta: data.meta,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
return textError(err.message);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
// ─── get_submission ───
|
|
86
|
+
server.tool("get_submission", "Get a single submission with full data", {
|
|
87
|
+
formId: zod_1.z.string().min(1).describe("The form ID"),
|
|
88
|
+
submissionId: zod_1.z.string().min(1).describe("The submission ID"),
|
|
89
|
+
}, async (args) => {
|
|
90
|
+
try {
|
|
91
|
+
const data = await client.getSubmission(args.formId, args.submissionId);
|
|
92
|
+
let fileInfo = null;
|
|
93
|
+
if (data.submission?.files && typeof data.submission.files === "object") {
|
|
94
|
+
const cleaned = {};
|
|
95
|
+
for (const [field, val] of Object.entries(data.submission.files)) {
|
|
96
|
+
if (val && typeof val === "object") {
|
|
97
|
+
cleaned[field] = {
|
|
98
|
+
name: val.name || field,
|
|
99
|
+
type: val.type || "unknown",
|
|
100
|
+
size: val.size || null,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
cleaned[field] = { name: field };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
fileInfo = cleaned;
|
|
108
|
+
}
|
|
109
|
+
return textResult({
|
|
110
|
+
submission: {
|
|
111
|
+
id: data.submission.id,
|
|
112
|
+
formId: data.submission.formId,
|
|
113
|
+
data: data.submission.data,
|
|
114
|
+
files: fileInfo,
|
|
115
|
+
createdAt: data.submission.createdAt,
|
|
116
|
+
},
|
|
117
|
+
form: data.form,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
return textError(err.message);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
// ─── delete_form ───
|
|
125
|
+
server.tool("delete_form", "Delete a form and all its submissions permanently", {
|
|
126
|
+
formId: zod_1.z.string().min(1).describe("The form ID to delete"),
|
|
127
|
+
}, async (args) => {
|
|
128
|
+
try {
|
|
129
|
+
await client.deleteForm(args.formId);
|
|
130
|
+
return textResult({
|
|
131
|
+
message: `Form deleted permanently`,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
return textError(err.message);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
// ─── list_templates ───
|
|
139
|
+
// @ts-ignore
|
|
140
|
+
server.tool("list_templates", "List all email templates. Email templates are used to send confirmation emails to people who submit your forms.", {}, async () => {
|
|
141
|
+
try {
|
|
142
|
+
const data = await client.listTemplates();
|
|
143
|
+
const templates = (data.templates || []).map((t) => ({
|
|
144
|
+
id: t.id,
|
|
145
|
+
name: t.name,
|
|
146
|
+
slug: t.slug,
|
|
147
|
+
senderPrefix: t.senderPrefix,
|
|
148
|
+
senderName: t.senderName,
|
|
149
|
+
subject: t.subject,
|
|
150
|
+
enabled: t.enabled,
|
|
151
|
+
linkedForm: t.form ? { id: t.form.id, name: t.form.name } : null,
|
|
152
|
+
}));
|
|
153
|
+
return textResult({ templates, total: templates.length });
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
return textError(err.message);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
// ─── create_template ───
|
|
160
|
+
// @ts-ignore
|
|
161
|
+
server.tool("create_template", "Create an email template for sending confirmation emails to form submitters. Use {{variableName}} placeholders for dynamic content (e.g. {{name}}, {{email}}, {{formName}}, {{submissionId}}). Link it to a form so confirmation emails are sent automatically when someone submits.", {
|
|
162
|
+
name: zod_1.z.string().min(1).max(100).describe("Template name (e.g. 'Contact Confirmation')"),
|
|
163
|
+
htmlContent: zod_1.z.string().min(1).describe("HTML email content with {{variable}} placeholders. Example: '<div>Hi {{name}}, thanks for contacting us!</div>'"),
|
|
164
|
+
subject: zod_1.z.string().max(200).optional().describe("Email subject line, supports {{variables}} (default: 'Thank you for your submission')"),
|
|
165
|
+
senderPrefix: zod_1.z.string().optional().describe("Sender email prefix — will send from prefix@notifications.aldform.com (default: 'notifications')"),
|
|
166
|
+
senderName: zod_1.z.string().max(50).optional().describe("Display name for the sender (default: 'Aldform')"),
|
|
167
|
+
formId: zod_1.z.string().optional().describe("Form ID to link this template to. When linked, submissions to this form will automatically trigger the confirmation email."),
|
|
168
|
+
}, async (args) => {
|
|
169
|
+
try {
|
|
170
|
+
const data = await client.createTemplate({
|
|
171
|
+
name: args.name,
|
|
172
|
+
htmlContent: args.htmlContent,
|
|
173
|
+
subject: args.subject,
|
|
174
|
+
senderPrefix: args.senderPrefix,
|
|
175
|
+
senderName: args.senderName,
|
|
176
|
+
formId: args.formId,
|
|
177
|
+
});
|
|
178
|
+
return textResult({
|
|
179
|
+
message: `Template "${data.template.name}" created successfully`,
|
|
180
|
+
template: {
|
|
181
|
+
id: data.template.id,
|
|
182
|
+
name: data.template.name,
|
|
183
|
+
slug: data.template.slug,
|
|
184
|
+
subject: data.template.subject,
|
|
185
|
+
senderPrefix: data.template.senderPrefix,
|
|
186
|
+
senderName: data.template.senderName,
|
|
187
|
+
enabled: data.template.enabled,
|
|
188
|
+
formId: data.template.formId,
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
return textError(err.message);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
// ─── update_template ───
|
|
197
|
+
// @ts-ignore
|
|
198
|
+
server.tool("update_template", "Update an existing email template. You can change the HTML content, subject, sender, form linking, or enable/disable it.", {
|
|
199
|
+
templateId: zod_1.z.string().min(1).describe("The template ID to update"),
|
|
200
|
+
name: zod_1.z.string().max(100).optional().describe("New template name"),
|
|
201
|
+
htmlContent: zod_1.z.string().optional().describe("New HTML email content with {{variable}} placeholders"),
|
|
202
|
+
subject: zod_1.z.string().max(200).optional().describe("New email subject line"),
|
|
203
|
+
senderPrefix: zod_1.z.string().optional().describe("New sender email prefix"),
|
|
204
|
+
senderName: zod_1.z.string().max(50).optional().describe("New sender display name"),
|
|
205
|
+
formId: zod_1.z.string().nullable().optional().describe("Form ID to link to (null to unlink)"),
|
|
206
|
+
enabled: zod_1.z.boolean().optional().describe("Enable or disable the template"),
|
|
207
|
+
}, async (args) => {
|
|
208
|
+
try {
|
|
209
|
+
const { templateId, ...updates } = args;
|
|
210
|
+
// Remove undefined values
|
|
211
|
+
const cleanUpdates = {};
|
|
212
|
+
for (const [k, v] of Object.entries(updates)) {
|
|
213
|
+
if (v !== undefined)
|
|
214
|
+
cleanUpdates[k] = v;
|
|
215
|
+
}
|
|
216
|
+
const data = await client.updateTemplate(templateId, cleanUpdates);
|
|
217
|
+
return textResult({
|
|
218
|
+
message: `Template "${data.template.name}" updated successfully`,
|
|
219
|
+
template: {
|
|
220
|
+
id: data.template.id,
|
|
221
|
+
name: data.template.name,
|
|
222
|
+
slug: data.template.slug,
|
|
223
|
+
subject: data.template.subject,
|
|
224
|
+
senderPrefix: data.template.senderPrefix,
|
|
225
|
+
senderName: data.template.senderName,
|
|
226
|
+
enabled: data.template.enabled,
|
|
227
|
+
formId: data.template.formId,
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
return textError(err.message);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
// ─── delete_template ───
|
|
236
|
+
// @ts-ignore
|
|
237
|
+
server.tool("delete_template", "Delete an email template permanently", {
|
|
238
|
+
templateId: zod_1.z.string().min(1).describe("The template ID to delete"),
|
|
239
|
+
}, async (args) => {
|
|
240
|
+
try {
|
|
241
|
+
await client.deleteTemplate(args.templateId);
|
|
242
|
+
return textResult({ message: "Template deleted permanently" });
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
return textError(err.message);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
// ─── preview_template ───
|
|
249
|
+
// @ts-ignore
|
|
250
|
+
server.tool("preview_template", "Render a preview of an email template with sample data. Returns the rendered HTML and subject line.", {
|
|
251
|
+
templateId: zod_1.z.string().min(1).describe("The template ID to preview"),
|
|
252
|
+
sampleData: zod_1.z.record(zod_1.z.string()).optional().describe("Optional sample data to use for rendering (e.g. { name: 'Jane', email: 'jane@example.com' })"),
|
|
253
|
+
}, async (args) => {
|
|
254
|
+
try {
|
|
255
|
+
const data = await client.previewTemplate(args.templateId, args.sampleData);
|
|
256
|
+
return textResult({
|
|
257
|
+
subject: data.subject,
|
|
258
|
+
from: data.from,
|
|
259
|
+
renderedHtml: data.html,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
catch (err) {
|
|
263
|
+
return textError(err.message);
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
// ─── test_template ───
|
|
267
|
+
// @ts-ignore
|
|
268
|
+
server.tool("test_template", "Send a test email using this template to your own email address. Max 5 test emails per hour.", {
|
|
269
|
+
templateId: zod_1.z.string().min(1).describe("The template ID to send a test for"),
|
|
270
|
+
}, async (args) => {
|
|
271
|
+
try {
|
|
272
|
+
const data = await client.testTemplate(args.templateId);
|
|
273
|
+
return textResult({ message: data.message });
|
|
274
|
+
}
|
|
275
|
+
catch (err) {
|
|
276
|
+
return textError(err.message);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
// ─── get_docs ───
|
|
280
|
+
server.tool("get_docs", "Get Aldform documentation. Returns a specific topic or lists all available topics. Use this to learn how to use the Aldform API, submit forms, upload files, handle errors, use sections, and more.", {
|
|
281
|
+
topic: zod_1.z
|
|
282
|
+
.string()
|
|
283
|
+
.describe("The documentation topic to retrieve. Available topics: overview, quickstart, authentication, submit, submissions, files, sections, errors, sdk, limits. Use 'all_topics' to list available topics with descriptions."),
|
|
284
|
+
}, async (args) => {
|
|
285
|
+
if (args.topic === "all_topics") {
|
|
286
|
+
return textResult({
|
|
287
|
+
topics: Object.entries(docs_1.DOCS).map(([key, doc]) => ({
|
|
288
|
+
topic: key,
|
|
289
|
+
title: doc.title,
|
|
290
|
+
description: doc.description,
|
|
291
|
+
})),
|
|
292
|
+
usage: "Call get_docs with a specific topic to read the full documentation.",
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
const doc = docs_1.DOCS[args.topic];
|
|
296
|
+
if (!doc)
|
|
297
|
+
return textError(`Unknown topic: ${args.topic}`);
|
|
298
|
+
return textResult({
|
|
299
|
+
topic: args.topic,
|
|
300
|
+
title: doc.title,
|
|
301
|
+
content: doc.content,
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
// ─── search_docs ───
|
|
305
|
+
server.tool("search_docs", "Search across all Aldform documentation for a keyword or phrase. Returns matching sections with relevant content.", {
|
|
306
|
+
query: zod_1.z.string().min(1).max(200).describe("The search term or phrase to look for in the documentation"),
|
|
307
|
+
}, async (args) => {
|
|
308
|
+
const query = args.query.toLowerCase();
|
|
309
|
+
const results = [];
|
|
310
|
+
for (const [key, doc] of Object.entries(docs_1.DOCS)) {
|
|
311
|
+
const lines = doc.content.split("\n");
|
|
312
|
+
const matchingLines = [];
|
|
313
|
+
for (let i = 0; i < lines.length; i++) {
|
|
314
|
+
if (lines[i].toLowerCase().includes(query)) {
|
|
315
|
+
const start = Math.max(0, i - 1);
|
|
316
|
+
const end = Math.min(lines.length - 1, i + 1);
|
|
317
|
+
const context = lines.slice(start, end + 1).join("\n").trim();
|
|
318
|
+
if (context && !matchingLines.includes(context)) {
|
|
319
|
+
matchingLines.push(context);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (matchingLines.length > 0) {
|
|
324
|
+
results.push({
|
|
325
|
+
topic: key,
|
|
326
|
+
title: doc.title,
|
|
327
|
+
matches: matchingLines.slice(0, 5),
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (results.length === 0) {
|
|
332
|
+
return textResult({
|
|
333
|
+
message: `No documentation found matching "${args.query}". Try get_docs with topic "all_topics" to see available topics.`,
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
return textResult({
|
|
337
|
+
query: args.query,
|
|
338
|
+
results,
|
|
339
|
+
hint: "Use get_docs with a specific topic to read the full documentation.",
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
return server;
|
|
343
|
+
}
|
|
344
|
+
function textResult(data) {
|
|
345
|
+
return {
|
|
346
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
function textError(message) {
|
|
350
|
+
return {
|
|
351
|
+
content: [{ type: "text", text: JSON.stringify({ error: message }) }],
|
|
352
|
+
isError: true,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
//# sourceMappingURL=server-remote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-remote.js","sourceRoot":"","sources":["../src/server-remote.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aldform-mcp",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"description": "Aldform MCP Server — Model Context Protocol server for managing forms and submissions via AI assistants",
|
|
5
|
+
"main": "dist/cli.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"aldform-mcp": "./dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "public"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist/cli.js",
|
|
14
|
+
"dist/cli.js.map",
|
|
15
|
+
"dist/server-remote.js",
|
|
16
|
+
"dist/server-remote.js.map",
|
|
17
|
+
"dist/api-client.js",
|
|
18
|
+
"dist/api-client.js.map",
|
|
19
|
+
"dist/docs.js",
|
|
20
|
+
"dist/docs.js.map"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "NODE_OPTIONS=--max-old-space-size=8192 tsc",
|
|
24
|
+
"dev": "ts-node src/cli.ts",
|
|
25
|
+
"deploy": "node ../../node_modules/serverless/bin/serverless.js deploy",
|
|
26
|
+
"test:docs": "npx ts-node test-docs.ts",
|
|
27
|
+
"prepublishOnly": "npm run build"
|
|
28
|
+
},
|
|
29
|
+
"keywords": ["mcp", "aldform", "forms", "model-context-protocol", "ai", "claude"],
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/omrajguru05/aldform-app.git",
|
|
34
|
+
"directory": "apps/mcp"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
38
|
+
"@prisma/client": "^6.8.2",
|
|
39
|
+
"zod": "^3.24.4",
|
|
40
|
+
"uuid": "^11.1.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"typescript": "^5.7.3",
|
|
44
|
+
"@types/node": "^22.15.17",
|
|
45
|
+
"@types/uuid": "^10.0.0",
|
|
46
|
+
"@types/aws-lambda": "^8.10.148",
|
|
47
|
+
"prisma": "^6.8.2",
|
|
48
|
+
"serverless": "^3.38.0",
|
|
49
|
+
"serverless-esbuild": "^1.52.0"
|
|
50
|
+
}
|
|
51
|
+
}
|