@netpad/mcp-server 2.4.2 → 2.4.4
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 +82 -2
- package/dist/index.js +344 -28
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,6 +1,40 @@
|
|
|
1
1
|
# @netpad/mcp-server
|
|
2
2
|
|
|
3
|
-
An MCP (Model Context Protocol) server for AI-assisted NetPad application development. This comprehensive toolkit provides **
|
|
3
|
+
An MCP (Model Context Protocol) server for AI-assisted NetPad application development. This comprehensive toolkit provides **80+ tools** for building forms, workflows, applications, and data-driven experiences with the NetPad platform.
|
|
4
|
+
|
|
5
|
+
> **Build forms in minutes, not hours.** Describe what you need to Claude, get a working form with one click.
|
|
6
|
+
>
|
|
7
|
+
> Learn more at [netpad.io/mcp](https://netpad.io/mcp)
|
|
8
|
+
|
|
9
|
+
## Build from Claude
|
|
10
|
+
|
|
11
|
+
The most powerful way to use NetPad is through conversational building with Claude:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
You: "I need a customer feedback form with rating, comments, and contact info"
|
|
15
|
+
|
|
16
|
+
Claude: I've generated your feedback form with:
|
|
17
|
+
- Star rating field (1-5)
|
|
18
|
+
- Comments textarea with 500 character limit
|
|
19
|
+
- Email and phone fields with validation
|
|
20
|
+
|
|
21
|
+
Click to import: https://netpad.io/import/imp_abc123
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**That's it.** One conversation, one click, working form.
|
|
25
|
+
|
|
26
|
+
### How It Works
|
|
27
|
+
|
|
28
|
+
1. **Describe** - Tell Claude what form you need in plain English
|
|
29
|
+
2. **Generate** - Claude uses `generate_form` to create the configuration
|
|
30
|
+
3. **Import** - Click the link or use `create_import_link` for a shareable URL
|
|
31
|
+
4. **Customize** - Fine-tune in NetPad's visual builder if needed
|
|
32
|
+
|
|
33
|
+
## What's New in v2.4.0
|
|
34
|
+
|
|
35
|
+
- **One-Click Import Links**: `create_import_link` tool generates shareable URLs for instant form import
|
|
36
|
+
- **Import URLs in Output**: `generate_form` now includes a direct import link in the response
|
|
37
|
+
- **Deep Link Integration**: Forms created in Claude can be imported to NetPad Cloud with one click
|
|
4
38
|
|
|
5
39
|
## What's New in v2.0.0
|
|
6
40
|
|
|
@@ -97,7 +131,13 @@ Add to `~/.cursor/mcp.json`:
|
|
|
97
131
|
}
|
|
98
132
|
```
|
|
99
133
|
|
|
100
|
-
## Available Tools (
|
|
134
|
+
## Available Tools (80+ total)
|
|
135
|
+
|
|
136
|
+
### Import & Sharing Tools (1) - NEW
|
|
137
|
+
|
|
138
|
+
| Tool | Description |
|
|
139
|
+
|------|-------------|
|
|
140
|
+
| `create_import_link` | Generate a shareable one-click import URL for any form configuration |
|
|
101
141
|
|
|
102
142
|
### Form Building Tools (6)
|
|
103
143
|
|
|
@@ -298,6 +338,44 @@ The server exposes documentation as MCP resources:
|
|
|
298
338
|
|
|
299
339
|
## Example Interactions
|
|
300
340
|
|
|
341
|
+
### Build a Form with One Click
|
|
342
|
+
|
|
343
|
+
```
|
|
344
|
+
User: I need a job application form with resume upload, experience level,
|
|
345
|
+
and availability
|
|
346
|
+
|
|
347
|
+
Claude: [Uses generate_form tool]
|
|
348
|
+
I've generated your job application form with:
|
|
349
|
+
- Resume file upload (PDF, DOC, DOCX - max 10MB)
|
|
350
|
+
- Experience level dropdown (Entry, Mid, Senior, Executive)
|
|
351
|
+
- Availability date picker
|
|
352
|
+
- Cover letter textarea
|
|
353
|
+
- Contact information section
|
|
354
|
+
|
|
355
|
+
Click to import: https://netpad.io/import/imp_xyz789
|
|
356
|
+
|
|
357
|
+
The form is ready to use - just click the link to add it to your NetPad workspace.
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Generate and Share an Import Link
|
|
361
|
+
|
|
362
|
+
```
|
|
363
|
+
User: Can you create a patient intake form and give me a link I can share
|
|
364
|
+
with my team?
|
|
365
|
+
|
|
366
|
+
Claude: [Uses generate_form, then create_import_link]
|
|
367
|
+
Here's your patient intake form with:
|
|
368
|
+
- Personal information section
|
|
369
|
+
- Medical history fields
|
|
370
|
+
- Insurance details
|
|
371
|
+
- Emergency contact
|
|
372
|
+
|
|
373
|
+
Shareable import link: https://netpad.io/import/imp_abc123
|
|
374
|
+
|
|
375
|
+
This link expires in 7 days. Anyone with a NetPad account can click it
|
|
376
|
+
to import this form into their workspace.
|
|
377
|
+
```
|
|
378
|
+
|
|
301
379
|
### Create an Application
|
|
302
380
|
|
|
303
381
|
```
|
|
@@ -386,9 +464,11 @@ echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_form_
|
|
|
386
464
|
|
|
387
465
|
## Related Packages
|
|
388
466
|
|
|
467
|
+
- [@netpad/mcp-server-remote](https://www.npmjs.com/package/@netpad/mcp-server-remote) - Remote HTTP MCP server for Claude custom connectors
|
|
389
468
|
- [@netpad/forms](https://www.npmjs.com/package/@netpad/forms) - React form renderer library
|
|
390
469
|
- [@netpad/workflows](https://www.npmjs.com/package/@netpad/workflows) - Workflow automation client
|
|
391
470
|
- [NetPad Platform](https://netpad.io) - Full form builder platform with database integration
|
|
471
|
+
- [NetPad MCP Guide](https://netpad.io/mcp) - Learn more about building with Claude
|
|
392
472
|
|
|
393
473
|
## License
|
|
394
474
|
|
package/dist/index.js
CHANGED
|
@@ -21826,6 +21826,21 @@ function formatToolOutput(output) {
|
|
|
21826
21826
|
}
|
|
21827
21827
|
|
|
21828
21828
|
// src/index.ts
|
|
21829
|
+
import {
|
|
21830
|
+
UI_RESOURCES
|
|
21831
|
+
} from "@netpad/mcp-apps";
|
|
21832
|
+
function withUIResource(textContent, resourceId, data) {
|
|
21833
|
+
const resource = UI_RESOURCES[resourceId];
|
|
21834
|
+
return {
|
|
21835
|
+
content: [{ type: "text", text: textContent }],
|
|
21836
|
+
_meta: {
|
|
21837
|
+
ui: {
|
|
21838
|
+
resourceUri: resource.uri,
|
|
21839
|
+
data
|
|
21840
|
+
}
|
|
21841
|
+
}
|
|
21842
|
+
};
|
|
21843
|
+
}
|
|
21829
21844
|
function createNetPadMcpServer(options) {
|
|
21830
21845
|
const server = new McpServer({
|
|
21831
21846
|
name: options?.name ?? "@netpad/mcp-server",
|
|
@@ -22204,14 +22219,26 @@ This will open NetPad where you can:
|
|
|
22204
22219
|
If you prefer to work with code, here's the complete TypeScript implementation:
|
|
22205
22220
|
|
|
22206
22221
|
${formatToolOutput(output)}`;
|
|
22207
|
-
|
|
22208
|
-
|
|
22209
|
-
|
|
22210
|
-
|
|
22211
|
-
|
|
22212
|
-
|
|
22213
|
-
|
|
22222
|
+
const formPreviewData = {
|
|
22223
|
+
form: {
|
|
22224
|
+
name: schema.name,
|
|
22225
|
+
description: schema.description,
|
|
22226
|
+
fields: (schema.fieldConfigs || []).map((f) => ({
|
|
22227
|
+
id: f.path,
|
|
22228
|
+
type: f.type,
|
|
22229
|
+
label: f.label,
|
|
22230
|
+
placeholder: f.placeholder,
|
|
22231
|
+
required: f.required,
|
|
22232
|
+
options: f.options
|
|
22233
|
+
})),
|
|
22234
|
+
theme: schema.theme,
|
|
22235
|
+
multiPage: schema.multiPage
|
|
22236
|
+
},
|
|
22237
|
+
theme: "dark",
|
|
22238
|
+
mode: "traditional",
|
|
22239
|
+
readonly: true
|
|
22214
22240
|
};
|
|
22241
|
+
return withUIResource(outputWithImport, "form-preview", formPreviewData);
|
|
22215
22242
|
}
|
|
22216
22243
|
);
|
|
22217
22244
|
server.tool(
|
|
@@ -22650,17 +22677,27 @@ Available topics: ${Object.keys(docs).join(", ")}`
|
|
|
22650
22677
|
fieldCount: t.fields.length,
|
|
22651
22678
|
hasMultiPage: !!t.multiPage?.enabled
|
|
22652
22679
|
}));
|
|
22653
|
-
|
|
22654
|
-
|
|
22655
|
-
|
|
22656
|
-
|
|
22657
|
-
|
|
22658
|
-
|
|
22659
|
-
|
|
22660
|
-
|
|
22661
|
-
|
|
22662
|
-
|
|
22680
|
+
const textResponse = JSON.stringify({
|
|
22681
|
+
templateType: "form",
|
|
22682
|
+
templates: summary,
|
|
22683
|
+
total: summary.length,
|
|
22684
|
+
categories: [...new Set(templates.map((t) => t.category))]
|
|
22685
|
+
}, null, 2);
|
|
22686
|
+
const galleryItems = templates.map((t) => ({
|
|
22687
|
+
id: t.id,
|
|
22688
|
+
name: t.name,
|
|
22689
|
+
description: t.description,
|
|
22690
|
+
category: t.category,
|
|
22691
|
+
tags: t.tags,
|
|
22692
|
+
icon: t.icon || "\u{1F4DD}"
|
|
22693
|
+
}));
|
|
22694
|
+
const galleryData = {
|
|
22695
|
+
templates: galleryItems,
|
|
22696
|
+
templateType: "form",
|
|
22697
|
+
theme: "dark",
|
|
22698
|
+
showCategories: true
|
|
22663
22699
|
};
|
|
22700
|
+
return withUIResource(textResponse, "template-gallery", galleryData);
|
|
22664
22701
|
}
|
|
22665
22702
|
case "application": {
|
|
22666
22703
|
if (action === "categories") {
|
|
@@ -22748,7 +22785,33 @@ Available topics: ${Object.keys(docs).join(", ")}`
|
|
|
22748
22785
|
edges: template.edges
|
|
22749
22786
|
}
|
|
22750
22787
|
};
|
|
22751
|
-
|
|
22788
|
+
const uiData = {
|
|
22789
|
+
workflow: {
|
|
22790
|
+
nodes: template.nodes.map((n) => ({
|
|
22791
|
+
id: n.id,
|
|
22792
|
+
type: n.type,
|
|
22793
|
+
position: n.position,
|
|
22794
|
+
data: { label: n.label || n.type, ...n.config }
|
|
22795
|
+
})),
|
|
22796
|
+
edges: template.edges.map((e) => ({
|
|
22797
|
+
id: e.id,
|
|
22798
|
+
source: e.source,
|
|
22799
|
+
target: e.target,
|
|
22800
|
+
sourceHandle: e.sourceHandle,
|
|
22801
|
+
targetHandle: e.targetHandle,
|
|
22802
|
+
label: e.condition?.label
|
|
22803
|
+
}))
|
|
22804
|
+
},
|
|
22805
|
+
theme: "dark",
|
|
22806
|
+
fitView: true,
|
|
22807
|
+
showMinimap: true,
|
|
22808
|
+
autoLayout: true
|
|
22809
|
+
};
|
|
22810
|
+
return withUIResource(
|
|
22811
|
+
JSON.stringify(workflowForUI, null, 2),
|
|
22812
|
+
"workflow-viewer",
|
|
22813
|
+
uiData
|
|
22814
|
+
);
|
|
22752
22815
|
}
|
|
22753
22816
|
let templates = Object.values(WORKFLOW_TEMPLATES);
|
|
22754
22817
|
if (category) {
|
|
@@ -22759,17 +22822,27 @@ Available topics: ${Object.keys(docs).join(", ")}`
|
|
|
22759
22822
|
nodesCount: t.nodes.length,
|
|
22760
22823
|
edgesCount: t.edges.length
|
|
22761
22824
|
}));
|
|
22762
|
-
|
|
22763
|
-
|
|
22764
|
-
|
|
22765
|
-
|
|
22766
|
-
|
|
22767
|
-
|
|
22768
|
-
|
|
22769
|
-
|
|
22770
|
-
|
|
22771
|
-
|
|
22825
|
+
const textResponse = JSON.stringify({
|
|
22826
|
+
templateType: "workflow",
|
|
22827
|
+
templates: summary,
|
|
22828
|
+
total: summary.length,
|
|
22829
|
+
categories: [...new Set(Object.values(WORKFLOW_TEMPLATES).map((t) => t.category))]
|
|
22830
|
+
}, null, 2);
|
|
22831
|
+
const galleryItems = templates.map((t) => ({
|
|
22832
|
+
id: t.id,
|
|
22833
|
+
name: t.name,
|
|
22834
|
+
description: t.description,
|
|
22835
|
+
category: t.category,
|
|
22836
|
+
tags: t.tags,
|
|
22837
|
+
icon: "\u26A1"
|
|
22838
|
+
}));
|
|
22839
|
+
const galleryData = {
|
|
22840
|
+
templates: galleryItems,
|
|
22841
|
+
templateType: "workflow",
|
|
22842
|
+
theme: "dark",
|
|
22843
|
+
showCategories: true
|
|
22772
22844
|
};
|
|
22845
|
+
return withUIResource(textResponse, "template-gallery", galleryData);
|
|
22773
22846
|
}
|
|
22774
22847
|
case "conversational": {
|
|
22775
22848
|
if (action === "categories") {
|
|
@@ -26290,6 +26363,249 @@ You can use any valid hex color.`
|
|
|
26290
26363
|
};
|
|
26291
26364
|
}
|
|
26292
26365
|
);
|
|
26366
|
+
server.tool(
|
|
26367
|
+
"import_google_form",
|
|
26368
|
+
`Import a Google Form into NetPad. This tool generates the API call and mapping preview for importing a Google Form.
|
|
26369
|
+
|
|
26370
|
+
IMPORTANT: Before using this tool, the user must have:
|
|
26371
|
+
1. Connected their Google account via the NetPad UI (Settings > Integrations > Google Forms)
|
|
26372
|
+
2. Obtained a credentialId for their Google Forms connection
|
|
26373
|
+
|
|
26374
|
+
The tool returns:
|
|
26375
|
+
- Instructions for completing the import via the NetPad API
|
|
26376
|
+
- A preview of how the Google Form fields will be mapped to NetPad field types
|
|
26377
|
+
- Any warnings about fields that may need manual adjustment`,
|
|
26378
|
+
{
|
|
26379
|
+
formId: external_exports.string().describe("The Google Form ID to import. Can be found in the form URL: https://docs.google.com/forms/d/{FORM_ID}/edit"),
|
|
26380
|
+
organizationId: external_exports.string().describe("The NetPad organization ID"),
|
|
26381
|
+
projectId: external_exports.string().describe("The NetPad project ID where the form will be created"),
|
|
26382
|
+
credentialId: external_exports.string().optional().describe("The credential ID for the Google Forms connection. If not provided, the user must set it up via the UI first."),
|
|
26383
|
+
preview: external_exports.boolean().optional().describe("If true, only return the mapping preview without creating the form (default: true)")
|
|
26384
|
+
},
|
|
26385
|
+
async ({ formId, organizationId, projectId, credentialId, preview = true }) => {
|
|
26386
|
+
const baseUrl = "https://netpad.io";
|
|
26387
|
+
const fieldTypeMapping = `
|
|
26388
|
+
## Google Forms to NetPad Field Type Mapping
|
|
26389
|
+
|
|
26390
|
+
| Google Forms Type | NetPad Type | Confidence |
|
|
26391
|
+
|-------------------|-------------|------------|
|
|
26392
|
+
| SHORT_ANSWER | short_text | Exact |
|
|
26393
|
+
| PARAGRAPH_TEXT | long_text | Exact |
|
|
26394
|
+
| MULTIPLE_CHOICE | radio | Exact |
|
|
26395
|
+
| CHECKBOXES | checkbox_group | Exact |
|
|
26396
|
+
| DROPDOWN | dropdown | Exact |
|
|
26397
|
+
| LINEAR_SCALE | rating | Exact |
|
|
26398
|
+
| MULTIPLE_CHOICE_GRID | matrix | Approximate |
|
|
26399
|
+
| CHECKBOX_GRID | matrix | Approximate |
|
|
26400
|
+
| DATE | date | Exact |
|
|
26401
|
+
| TIME | time | Exact |
|
|
26402
|
+
| FILE_UPLOAD | file | Exact |
|
|
26403
|
+
`;
|
|
26404
|
+
if (!credentialId) {
|
|
26405
|
+
return {
|
|
26406
|
+
content: [{
|
|
26407
|
+
type: "text",
|
|
26408
|
+
text: `# Google Forms Import
|
|
26409
|
+
|
|
26410
|
+
## Setup Required
|
|
26411
|
+
|
|
26412
|
+
Before importing Google Forms, you need to connect your Google account:
|
|
26413
|
+
|
|
26414
|
+
1. Go to **Settings > Integrations** in NetPad
|
|
26415
|
+
2. Click **Connect Google Account** under Google Forms
|
|
26416
|
+
3. Authorize NetPad to read your forms
|
|
26417
|
+
4. Copy the credential ID from the connection details
|
|
26418
|
+
|
|
26419
|
+
Or use this URL to start the OAuth flow:
|
|
26420
|
+
\`\`\`
|
|
26421
|
+
${baseUrl}/api/auth/google?provider=google_forms&orgId=${organizationId}
|
|
26422
|
+
\`\`\`
|
|
26423
|
+
|
|
26424
|
+
## Once Connected
|
|
26425
|
+
|
|
26426
|
+
Call this tool again with the \`credentialId\` parameter to preview or import the form.
|
|
26427
|
+
|
|
26428
|
+
${fieldTypeMapping}`
|
|
26429
|
+
}]
|
|
26430
|
+
};
|
|
26431
|
+
}
|
|
26432
|
+
const previewApiCall = `
|
|
26433
|
+
## Preview Import
|
|
26434
|
+
|
|
26435
|
+
To see how the Google Form will be mapped to NetPad fields:
|
|
26436
|
+
|
|
26437
|
+
\`\`\`bash
|
|
26438
|
+
curl "${baseUrl}/api/integrations/google-forms/preview?\\
|
|
26439
|
+
orgId=${organizationId}&\\
|
|
26440
|
+
credentialId=${credentialId}&\\
|
|
26441
|
+
formId=${formId}"
|
|
26442
|
+
\`\`\`
|
|
26443
|
+
|
|
26444
|
+
Or using fetch:
|
|
26445
|
+
|
|
26446
|
+
\`\`\`typescript
|
|
26447
|
+
const response = await fetch(
|
|
26448
|
+
'${baseUrl}/api/integrations/google-forms/preview?' + new URLSearchParams({
|
|
26449
|
+
orgId: '${organizationId}',
|
|
26450
|
+
credentialId: '${credentialId}',
|
|
26451
|
+
formId: '${formId}',
|
|
26452
|
+
})
|
|
26453
|
+
);
|
|
26454
|
+
const preview = await response.json();
|
|
26455
|
+
console.log('Fields:', preview.previewConfig.fieldConfigs);
|
|
26456
|
+
console.log('Warnings:', preview.mappingResult.warnings);
|
|
26457
|
+
\`\`\`
|
|
26458
|
+
`;
|
|
26459
|
+
const importApiCall = `
|
|
26460
|
+
## Execute Import
|
|
26461
|
+
|
|
26462
|
+
To create the NetPad form from the Google Form:
|
|
26463
|
+
|
|
26464
|
+
\`\`\`bash
|
|
26465
|
+
curl -X POST "${baseUrl}/api/integrations/google-forms/import" \\
|
|
26466
|
+
-H "Content-Type: application/json" \\
|
|
26467
|
+
-d '{
|
|
26468
|
+
"orgId": "${organizationId}",
|
|
26469
|
+
"credentialId": "${credentialId}",
|
|
26470
|
+
"formId": "${formId}",
|
|
26471
|
+
"projectId": "${projectId}"
|
|
26472
|
+
}'
|
|
26473
|
+
\`\`\`
|
|
26474
|
+
|
|
26475
|
+
Or using fetch:
|
|
26476
|
+
|
|
26477
|
+
\`\`\`typescript
|
|
26478
|
+
const response = await fetch('${baseUrl}/api/integrations/google-forms/import', {
|
|
26479
|
+
method: 'POST',
|
|
26480
|
+
headers: { 'Content-Type': 'application/json' },
|
|
26481
|
+
body: JSON.stringify({
|
|
26482
|
+
orgId: '${organizationId}',
|
|
26483
|
+
credentialId: '${credentialId}',
|
|
26484
|
+
formId: '${formId}',
|
|
26485
|
+
projectId: '${projectId}',
|
|
26486
|
+
// Optional customizations:
|
|
26487
|
+
customizations: {
|
|
26488
|
+
name: 'Custom Form Name', // Override the form name
|
|
26489
|
+
fieldOverrides: { // Modify specific field mappings
|
|
26490
|
+
'field_path': { type: 'dropdown' }
|
|
26491
|
+
},
|
|
26492
|
+
excludeFields: ['unwanted_field'] // Skip certain fields
|
|
26493
|
+
}
|
|
26494
|
+
})
|
|
26495
|
+
});
|
|
26496
|
+
|
|
26497
|
+
const result = await response.json();
|
|
26498
|
+
if (result.success) {
|
|
26499
|
+
console.log('Form created:', result.form.id);
|
|
26500
|
+
console.log('Edit URL:', result.importReport.viewUrl);
|
|
26501
|
+
}
|
|
26502
|
+
\`\`\`
|
|
26503
|
+
`;
|
|
26504
|
+
return {
|
|
26505
|
+
content: [{
|
|
26506
|
+
type: "text",
|
|
26507
|
+
text: `# Google Forms Import
|
|
26508
|
+
|
|
26509
|
+
**Form ID:** ${formId}
|
|
26510
|
+
**Organization:** ${organizationId}
|
|
26511
|
+
**Project:** ${projectId}
|
|
26512
|
+
**Credential:** ${credentialId}
|
|
26513
|
+
|
|
26514
|
+
${previewApiCall}
|
|
26515
|
+
|
|
26516
|
+
${preview ? "" : importApiCall}
|
|
26517
|
+
|
|
26518
|
+
${fieldTypeMapping}
|
|
26519
|
+
|
|
26520
|
+
## Using the Import Wizard UI
|
|
26521
|
+
|
|
26522
|
+
Alternatively, users can import Google Forms through the NetPad UI:
|
|
26523
|
+
|
|
26524
|
+
1. Go to **Forms** in your project
|
|
26525
|
+
2. Click **Import** > **Import from Google Forms**
|
|
26526
|
+
3. Select the Google account and form
|
|
26527
|
+
4. Review the field mappings
|
|
26528
|
+
5. Click **Import**
|
|
26529
|
+
|
|
26530
|
+
## Notes
|
|
26531
|
+
|
|
26532
|
+
- Only form structure is imported, not responses/submissions
|
|
26533
|
+
- Some field types may be approximated (see mapping table)
|
|
26534
|
+
- Validation rules are preserved where possible
|
|
26535
|
+
- Section/page breaks become multi-page form pages
|
|
26536
|
+
- Images and videos in the form are not imported`
|
|
26537
|
+
}]
|
|
26538
|
+
};
|
|
26539
|
+
}
|
|
26540
|
+
);
|
|
26541
|
+
server.tool(
|
|
26542
|
+
"list_google_forms",
|
|
26543
|
+
"List Google Forms available for import. Requires a connected Google account.",
|
|
26544
|
+
{
|
|
26545
|
+
organizationId: external_exports.string().describe("The NetPad organization ID"),
|
|
26546
|
+
credentialId: external_exports.string().describe("The credential ID for the Google Forms connection"),
|
|
26547
|
+
searchQuery: external_exports.string().optional().describe("Search query to filter forms by name")
|
|
26548
|
+
},
|
|
26549
|
+
async ({ organizationId, credentialId, searchQuery }) => {
|
|
26550
|
+
const baseUrl = "https://netpad.io";
|
|
26551
|
+
const params = new URLSearchParams({
|
|
26552
|
+
orgId: organizationId,
|
|
26553
|
+
credentialId
|
|
26554
|
+
});
|
|
26555
|
+
if (searchQuery) {
|
|
26556
|
+
params.set("q", searchQuery);
|
|
26557
|
+
}
|
|
26558
|
+
return {
|
|
26559
|
+
content: [{
|
|
26560
|
+
type: "text",
|
|
26561
|
+
text: `# List Google Forms
|
|
26562
|
+
|
|
26563
|
+
To list forms available for import, make this API call:
|
|
26564
|
+
|
|
26565
|
+
\`\`\`bash
|
|
26566
|
+
curl "${baseUrl}/api/integrations/google-forms?${params.toString()}"
|
|
26567
|
+
\`\`\`
|
|
26568
|
+
|
|
26569
|
+
Or using fetch:
|
|
26570
|
+
|
|
26571
|
+
\`\`\`typescript
|
|
26572
|
+
const response = await fetch(
|
|
26573
|
+
'${baseUrl}/api/integrations/google-forms?${params.toString()}'
|
|
26574
|
+
);
|
|
26575
|
+
const data = await response.json();
|
|
26576
|
+
|
|
26577
|
+
// data.forms contains:
|
|
26578
|
+
// - id: Form ID for importing
|
|
26579
|
+
// - name: Form title
|
|
26580
|
+
// - modifiedTime: Last modified date
|
|
26581
|
+
// - webViewLink: Link to edit form in Google
|
|
26582
|
+
|
|
26583
|
+
for (const form of data.forms) {
|
|
26584
|
+
console.log(\`\${form.name} (ID: \${form.id})\`);
|
|
26585
|
+
}
|
|
26586
|
+
\`\`\`
|
|
26587
|
+
|
|
26588
|
+
## Response Format
|
|
26589
|
+
|
|
26590
|
+
\`\`\`json
|
|
26591
|
+
{
|
|
26592
|
+
"forms": [
|
|
26593
|
+
{
|
|
26594
|
+
"id": "1BxiMVs0XRA5nFMdkkxYYfYpHm5PZ-abc123",
|
|
26595
|
+
"name": "Customer Feedback Survey",
|
|
26596
|
+
"modifiedTime": "2024-01-15T10:30:00Z",
|
|
26597
|
+
"webViewLink": "https://docs.google.com/forms/d/.../edit"
|
|
26598
|
+
}
|
|
26599
|
+
],
|
|
26600
|
+
"nextPageToken": "..." // For pagination
|
|
26601
|
+
}
|
|
26602
|
+
\`\`\`
|
|
26603
|
+
|
|
26604
|
+
Use the \`import_google_form\` tool with the form ID to import a specific form.`
|
|
26605
|
+
}]
|
|
26606
|
+
};
|
|
26607
|
+
}
|
|
26608
|
+
);
|
|
26293
26609
|
server.resource(
|
|
26294
26610
|
"netpad-extension-reference",
|
|
26295
26611
|
"netpad://reference/extensions",
|