@netpad/mcp-server 2.4.3 → 2.4.5
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 +344 -28
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
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",
|