0nmcp 2.3.0 → 2.4.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.
- package/README.md +44 -29
- package/capability-proxy.js +199 -0
- package/catalog.js +322 -6
- package/crm/helpers.js +9 -6
- package/crm/index.js +3 -2
- package/engine/validator.js +13 -1
- package/index.js +8 -5
- package/lib/stats.json +1 -1
- package/orchestrator.js +6 -35
- package/package.json +3 -2
- package/tools.js +3 -36
- package/workflow.js +336 -12
package/catalog.js
CHANGED
|
@@ -117,18 +117,110 @@ export const SERVICE_CATALOG = {
|
|
|
117
117
|
resend: {
|
|
118
118
|
name: "Resend",
|
|
119
119
|
type: "email",
|
|
120
|
-
description: "Developer-first email API —
|
|
120
|
+
description: "Developer-first email API — transactional emails, broadcasts, contacts, domains, templates, segments, webhooks",
|
|
121
121
|
baseUrl: "https://api.resend.com",
|
|
122
122
|
authType: "api_key",
|
|
123
123
|
credentialKeys: ["apiKey"],
|
|
124
124
|
capabilities: [
|
|
125
|
-
{ name: "send_email", actions: ["send"], description: "Send transactional emails" },
|
|
126
|
-
{ name: "
|
|
125
|
+
{ name: "send_email", actions: ["send"], description: "Send transactional emails with HTML, React templates, scheduling, and attachments" },
|
|
126
|
+
{ name: "batch_emails", actions: ["send"], description: "Send up to 100 emails in a single batch request" },
|
|
127
|
+
{ name: "manage_emails", actions: ["list", "get", "update", "cancel"], description: "List, retrieve, update scheduled, and cancel emails" },
|
|
128
|
+
{ name: "receive_emails", actions: ["list", "get"], description: "List and retrieve received inbound emails" },
|
|
129
|
+
{ name: "manage_attachments", actions: ["list", "get"], description: "List and retrieve attachments from sent and received emails" },
|
|
130
|
+
{ name: "manage_domains", actions: ["create", "list", "get", "update", "verify", "delete"], description: "Create, list, verify, update, and delete email domains" },
|
|
131
|
+
{ name: "manage_api_keys", actions: ["create", "list", "delete"], description: "Create, list, and delete API keys" },
|
|
132
|
+
{ name: "manage_audiences", actions: ["create", "list", "get", "delete"], description: "Create, list, get, and delete audiences (deprecated — use segments)" },
|
|
133
|
+
{ name: "manage_contacts", actions: ["create", "list", "get", "update", "delete"], description: "Create, list, get, update, and delete contacts" },
|
|
134
|
+
{ name: "manage_contact_segments", actions: ["add", "remove", "list"], description: "Add, remove, and list segment memberships for contacts" },
|
|
135
|
+
{ name: "manage_contact_topics", actions: ["get", "update"], description: "Get and update topic subscriptions for contacts" },
|
|
136
|
+
{ name: "manage_broadcasts", actions: ["create", "list", "get", "update", "send", "delete"], description: "Create, list, get, update, send, and delete broadcasts" },
|
|
137
|
+
{ name: "manage_segments", actions: ["create", "list", "get", "delete"], description: "Create, list, get, and delete segments" },
|
|
138
|
+
{ name: "manage_contact_properties", actions: ["create", "list", "get", "update", "delete"], description: "Create, list, get, update, and delete contact properties" },
|
|
139
|
+
{ name: "manage_templates", actions: ["create", "list", "get", "update", "delete", "duplicate", "publish"], description: "Create, list, get, update, delete, duplicate, and publish email templates" },
|
|
140
|
+
{ name: "manage_topics", actions: ["create", "list", "get", "update", "delete"], description: "Create, list, get, update, and delete email topics" },
|
|
141
|
+
{ name: "manage_webhooks", actions: ["create", "list", "get", "update", "delete"], description: "Create, list, get, update, and delete webhooks" },
|
|
127
142
|
],
|
|
128
143
|
endpoints: {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
144
|
+
// ── Emails ──
|
|
145
|
+
send_email: { method: "POST", path: "/emails", body: { from: "", to: [], subject: "", html: "" } },
|
|
146
|
+
send_batch_emails: { method: "POST", path: "/emails/batch", body: [] },
|
|
147
|
+
list_emails: { method: "GET", path: "/emails" },
|
|
148
|
+
get_email: { method: "GET", path: "/emails/{email_id}" },
|
|
149
|
+
update_email: { method: "PATCH", path: "/emails/{email_id}" },
|
|
150
|
+
cancel_email: { method: "POST", path: "/emails/{email_id}/cancel" },
|
|
151
|
+
// ── Received Emails ──
|
|
152
|
+
list_received_emails: { method: "GET", path: "/emails/receiving" },
|
|
153
|
+
get_received_email: { method: "GET", path: "/emails/receiving/{email_id}" },
|
|
154
|
+
// ── Attachments ──
|
|
155
|
+
list_email_attachments: { method: "GET", path: "/emails/{email_id}/attachments" },
|
|
156
|
+
get_email_attachment: { method: "GET", path: "/emails/{email_id}/attachments/{attachment_id}" },
|
|
157
|
+
list_received_attachments:{ method: "GET", path: "/emails/receiving/{email_id}/attachments" },
|
|
158
|
+
get_received_attachment: { method: "GET", path: "/emails/receiving/{email_id}/attachments/{attachment_id}" },
|
|
159
|
+
// ── Domains ──
|
|
160
|
+
create_domain: { method: "POST", path: "/domains", body: { name: "" } },
|
|
161
|
+
list_domains: { method: "GET", path: "/domains" },
|
|
162
|
+
get_domain: { method: "GET", path: "/domains/{domain_id}" },
|
|
163
|
+
update_domain: { method: "PATCH", path: "/domains/{domain_id}" },
|
|
164
|
+
verify_domain: { method: "POST", path: "/domains/{domain_id}/verify" },
|
|
165
|
+
delete_domain: { method: "DELETE", path: "/domains/{domain_id}" },
|
|
166
|
+
// ── API Keys ──
|
|
167
|
+
create_api_key: { method: "POST", path: "/api-keys", body: { name: "" } },
|
|
168
|
+
list_api_keys: { method: "GET", path: "/api-keys" },
|
|
169
|
+
delete_api_key: { method: "DELETE", path: "/api-keys/{api_key_id}" },
|
|
170
|
+
// ── Audiences (deprecated) ──
|
|
171
|
+
create_audience: { method: "POST", path: "/audiences", body: { name: "" } },
|
|
172
|
+
list_audiences: { method: "GET", path: "/audiences" },
|
|
173
|
+
get_audience: { method: "GET", path: "/audiences/{audience_id}" },
|
|
174
|
+
delete_audience: { method: "DELETE", path: "/audiences/{audience_id}" },
|
|
175
|
+
// ── Contacts ──
|
|
176
|
+
create_contact: { method: "POST", path: "/contacts", body: { email: "" } },
|
|
177
|
+
list_contacts: { method: "GET", path: "/contacts" },
|
|
178
|
+
get_contact: { method: "GET", path: "/contacts/{contact_id}" },
|
|
179
|
+
update_contact: { method: "PATCH", path: "/contacts/{contact_id}" },
|
|
180
|
+
delete_contact: { method: "DELETE", path: "/contacts/{contact_id}" },
|
|
181
|
+
add_contact_to_segment: { method: "POST", path: "/contacts/{contact_id}/segments/{segment_id}" },
|
|
182
|
+
remove_contact_from_segment: { method: "DELETE", path: "/contacts/{contact_id}/segments/{segment_id}" },
|
|
183
|
+
list_contact_segments: { method: "GET", path: "/contacts/{contact_id}/segments" },
|
|
184
|
+
get_contact_topics: { method: "GET", path: "/contacts/{contact_id}/topics" },
|
|
185
|
+
update_contact_topics: { method: "PATCH", path: "/contacts/{contact_id}/topics" },
|
|
186
|
+
// ── Broadcasts ──
|
|
187
|
+
create_broadcast: { method: "POST", path: "/broadcasts", body: { segment_id: "", from: "", subject: "" } },
|
|
188
|
+
list_broadcasts: { method: "GET", path: "/broadcasts" },
|
|
189
|
+
get_broadcast: { method: "GET", path: "/broadcasts/{broadcast_id}" },
|
|
190
|
+
update_broadcast: { method: "PATCH", path: "/broadcasts/{broadcast_id}" },
|
|
191
|
+
send_broadcast: { method: "POST", path: "/broadcasts/{broadcast_id}/send" },
|
|
192
|
+
delete_broadcast: { method: "DELETE", path: "/broadcasts/{broadcast_id}" },
|
|
193
|
+
// ── Segments ──
|
|
194
|
+
create_segment: { method: "POST", path: "/segments", body: { name: "" } },
|
|
195
|
+
list_segments: { method: "GET", path: "/segments" },
|
|
196
|
+
get_segment: { method: "GET", path: "/segments/{segment_id}" },
|
|
197
|
+
delete_segment: { method: "DELETE", path: "/segments/{segment_id}" },
|
|
198
|
+
// ── Contact Properties ──
|
|
199
|
+
create_contact_property: { method: "POST", path: "/contact-properties", body: { name: "", type: "string" } },
|
|
200
|
+
list_contact_properties: { method: "GET", path: "/contact-properties" },
|
|
201
|
+
get_contact_property: { method: "GET", path: "/contact-properties/{property_id}" },
|
|
202
|
+
update_contact_property: { method: "PATCH", path: "/contact-properties/{property_id}" },
|
|
203
|
+
delete_contact_property: { method: "DELETE", path: "/contact-properties/{property_id}" },
|
|
204
|
+
// ── Templates ──
|
|
205
|
+
create_template: { method: "POST", path: "/templates", body: { name: "", html: "" } },
|
|
206
|
+
list_templates: { method: "GET", path: "/templates" },
|
|
207
|
+
get_template: { method: "GET", path: "/templates/{template_id}" },
|
|
208
|
+
update_template: { method: "PATCH", path: "/templates/{template_id}" },
|
|
209
|
+
delete_template: { method: "DELETE", path: "/templates/{template_id}" },
|
|
210
|
+
duplicate_template: { method: "POST", path: "/templates/{template_id}/duplicate" },
|
|
211
|
+
publish_template: { method: "POST", path: "/templates/{template_id}/publish" },
|
|
212
|
+
// ── Topics ──
|
|
213
|
+
create_topic: { method: "POST", path: "/topics", body: { name: "" } },
|
|
214
|
+
list_topics: { method: "GET", path: "/topics" },
|
|
215
|
+
get_topic: { method: "GET", path: "/topics/{topic_id}" },
|
|
216
|
+
update_topic: { method: "PATCH", path: "/topics/{topic_id}" },
|
|
217
|
+
delete_topic: { method: "DELETE", path: "/topics/{topic_id}" },
|
|
218
|
+
// ── Webhooks ──
|
|
219
|
+
create_webhook: { method: "POST", path: "/webhooks", body: { endpoint_url: "", events: [] } },
|
|
220
|
+
list_webhooks: { method: "GET", path: "/webhooks" },
|
|
221
|
+
get_webhook: { method: "GET", path: "/webhooks/{webhook_id}" },
|
|
222
|
+
update_webhook: { method: "PATCH", path: "/webhooks/{webhook_id}" },
|
|
223
|
+
delete_webhook: { method: "DELETE", path: "/webhooks/{webhook_id}" },
|
|
132
224
|
},
|
|
133
225
|
authHeader: (creds) => ({
|
|
134
226
|
"Authorization": `Bearer ${creds.apiKey}`,
|
|
@@ -1517,6 +1609,230 @@ export const SERVICE_CATALOG = {
|
|
|
1517
1609
|
}),
|
|
1518
1610
|
},
|
|
1519
1611
|
|
|
1612
|
+
// ── Cloudflare ──────────────────────────────────────────────
|
|
1613
|
+
cloudflare: {
|
|
1614
|
+
name: "Cloudflare",
|
|
1615
|
+
type: "cloud",
|
|
1616
|
+
description: "Edge computing & CDN — Workers, KV, R2 storage, D1 database, DNS, WAF, DDoS protection, analytics",
|
|
1617
|
+
baseUrl: "https://api.cloudflare.com/client/v4",
|
|
1618
|
+
authType: "api_key",
|
|
1619
|
+
credentialKeys: ["apiToken"],
|
|
1620
|
+
capabilities: [
|
|
1621
|
+
{ name: "manage_workers", actions: ["list", "create", "update", "delete", "deploy"], description: "Deploy and manage Cloudflare Workers" },
|
|
1622
|
+
{ name: "manage_kv", actions: ["list_namespaces", "read", "write", "delete"], description: "Key-Value storage for Workers" },
|
|
1623
|
+
{ name: "manage_r2", actions: ["list_buckets", "create_bucket", "list_objects", "put_object", "get_object", "delete_object"], description: "S3-compatible object storage" },
|
|
1624
|
+
{ name: "manage_d1", actions: ["list_databases", "create_database", "query"], description: "Serverless SQL database" },
|
|
1625
|
+
{ name: "manage_dns", actions: ["list_zones", "list_records", "create_record", "update_record", "delete_record"], description: "DNS zone and record management" },
|
|
1626
|
+
{ name: "manage_waf", actions: ["list_rules", "create_rule", "update_rule"], description: "Web Application Firewall rules" },
|
|
1627
|
+
{ name: "manage_pages", actions: ["list_projects", "create_deployment"], description: "Cloudflare Pages static site deployments" },
|
|
1628
|
+
{ name: "analytics", actions: ["get_zone_analytics", "get_worker_analytics"], description: "Traffic and performance analytics" },
|
|
1629
|
+
],
|
|
1630
|
+
endpoints: {
|
|
1631
|
+
list_zones: { method: "GET", path: "/zones", query: ["name", "status", "page", "per_page"] },
|
|
1632
|
+
get_zone: { method: "GET", path: "/zones/{zoneId}" },
|
|
1633
|
+
list_dns_records: { method: "GET", path: "/zones/{zoneId}/dns_records", query: ["type", "name", "page", "per_page"] },
|
|
1634
|
+
create_dns_record: { method: "POST", path: "/zones/{zoneId}/dns_records", body: { type: "", name: "", content: "", ttl: 1, proxied: true } },
|
|
1635
|
+
update_dns_record: { method: "PUT", path: "/zones/{zoneId}/dns_records/{recordId}", body: {} },
|
|
1636
|
+
delete_dns_record: { method: "DELETE", path: "/zones/{zoneId}/dns_records/{recordId}" },
|
|
1637
|
+
list_workers: { method: "GET", path: "/accounts/{accountId}/workers/scripts" },
|
|
1638
|
+
get_worker: { method: "GET", path: "/accounts/{accountId}/workers/scripts/{scriptName}" },
|
|
1639
|
+
delete_worker: { method: "DELETE", path: "/accounts/{accountId}/workers/scripts/{scriptName}" },
|
|
1640
|
+
list_kv_namespaces: { method: "GET", path: "/accounts/{accountId}/storage/kv/namespaces" },
|
|
1641
|
+
create_kv_namespace: { method: "POST", path: "/accounts/{accountId}/storage/kv/namespaces", body: { title: "" } },
|
|
1642
|
+
read_kv_value: { method: "GET", path: "/accounts/{accountId}/storage/kv/namespaces/{namespaceId}/values/{keyName}" },
|
|
1643
|
+
write_kv_value: { method: "PUT", path: "/accounts/{accountId}/storage/kv/namespaces/{namespaceId}/values/{keyName}" },
|
|
1644
|
+
delete_kv_value: { method: "DELETE", path: "/accounts/{accountId}/storage/kv/namespaces/{namespaceId}/values/{keyName}" },
|
|
1645
|
+
list_r2_buckets: { method: "GET", path: "/accounts/{accountId}/r2/buckets" },
|
|
1646
|
+
create_r2_bucket: { method: "POST", path: "/accounts/{accountId}/r2/buckets", body: { name: "" } },
|
|
1647
|
+
list_d1_databases: { method: "GET", path: "/accounts/{accountId}/d1/database" },
|
|
1648
|
+
create_d1_database: { method: "POST", path: "/accounts/{accountId}/d1/database", body: { name: "" } },
|
|
1649
|
+
query_d1: { method: "POST", path: "/accounts/{accountId}/d1/database/{databaseId}/query", body: { sql: "" } },
|
|
1650
|
+
list_pages_projects: { method: "GET", path: "/accounts/{accountId}/pages/projects" },
|
|
1651
|
+
get_zone_analytics: { method: "GET", path: "/zones/{zoneId}/analytics/dashboard", query: ["since", "until"] },
|
|
1652
|
+
},
|
|
1653
|
+
authHeader: (creds) => ({
|
|
1654
|
+
"Authorization": `Bearer ${creds.apiToken}`,
|
|
1655
|
+
"Content-Type": "application/json",
|
|
1656
|
+
}),
|
|
1657
|
+
},
|
|
1658
|
+
|
|
1659
|
+
// ── GoDaddy ───────────────────────────────────────────────────
|
|
1660
|
+
godaddy: {
|
|
1661
|
+
name: "GoDaddy",
|
|
1662
|
+
type: "domains",
|
|
1663
|
+
description: "Domain registrar — search, check availability, manage DNS records, domain registration and management",
|
|
1664
|
+
baseUrl: "https://api.godaddy.com/v1",
|
|
1665
|
+
authType: "api_key",
|
|
1666
|
+
credentialKeys: ["apiKey", "apiSecret"],
|
|
1667
|
+
capabilities: [
|
|
1668
|
+
{ name: "search_domains", actions: ["suggest", "check_availability"], description: "Search and check domain name availability" },
|
|
1669
|
+
{ name: "manage_domains", actions: ["list", "get", "purchase"], description: "List owned domains and purchase new ones" },
|
|
1670
|
+
{ name: "manage_dns", actions: ["list_records", "add_record", "update_record", "delete_record"], description: "Manage DNS records for owned domains" },
|
|
1671
|
+
],
|
|
1672
|
+
endpoints: {
|
|
1673
|
+
suggest_domains: { method: "GET", path: "/domains/suggest", query: ["query", "limit", "tlds"] },
|
|
1674
|
+
check_availability: { method: "GET", path: "/domains/available", query: ["domain"] },
|
|
1675
|
+
list_domains: { method: "GET", path: "/domains", query: ["limit", "marker", "status"] },
|
|
1676
|
+
get_domain: { method: "GET", path: "/domains/{domain}" },
|
|
1677
|
+
purchase_domain: { method: "POST", path: "/domains/purchase", body: { domain: "", consent: {} } },
|
|
1678
|
+
list_dns_records: { method: "GET", path: "/domains/{domain}/records", query: ["type", "name"] },
|
|
1679
|
+
add_dns_records: { method: "PATCH", path: "/domains/{domain}/records", body: [] },
|
|
1680
|
+
update_dns_record: { method: "PUT", path: "/domains/{domain}/records/{type}/{name}", body: [] },
|
|
1681
|
+
delete_dns_record: { method: "DELETE", path: "/domains/{domain}/records/{type}/{name}" },
|
|
1682
|
+
},
|
|
1683
|
+
authHeader: (creds) => ({
|
|
1684
|
+
"Authorization": `sso-key ${creds.apiKey}:${creds.apiSecret}`,
|
|
1685
|
+
"Content-Type": "application/json",
|
|
1686
|
+
}),
|
|
1687
|
+
},
|
|
1688
|
+
|
|
1689
|
+
// ── n8n ─────────────────────────────────────────────────────
|
|
1690
|
+
n8n: {
|
|
1691
|
+
name: "n8n",
|
|
1692
|
+
type: "automation",
|
|
1693
|
+
description: "Open-source workflow automation — workflows, executions, credentials, triggers, webhooks (self-hosted or cloud)",
|
|
1694
|
+
baseUrl: "https://app.n8n.cloud/api/v1",
|
|
1695
|
+
authType: "api_key",
|
|
1696
|
+
credentialKeys: ["apiKey", "baseUrl"],
|
|
1697
|
+
capabilities: [
|
|
1698
|
+
{ name: "manage_workflows", actions: ["list", "get", "create", "update", "delete", "activate", "deactivate"], description: "Create and manage automation workflows" },
|
|
1699
|
+
{ name: "manage_executions", actions: ["list", "get", "delete"], description: "View and manage workflow execution history" },
|
|
1700
|
+
{ name: "manage_credentials", actions: ["list", "create", "delete"], description: "Manage integration credentials" },
|
|
1701
|
+
{ name: "trigger_workflow", actions: ["execute"], description: "Trigger a workflow via webhook or API" },
|
|
1702
|
+
],
|
|
1703
|
+
endpoints: {
|
|
1704
|
+
list_workflows: { method: "GET", path: "/workflows", query: ["active", "limit", "cursor"] },
|
|
1705
|
+
get_workflow: { method: "GET", path: "/workflows/{workflowId}" },
|
|
1706
|
+
create_workflow: { method: "POST", path: "/workflows", body: { name: "", nodes: [], connections: {} } },
|
|
1707
|
+
update_workflow: { method: "PUT", path: "/workflows/{workflowId}", body: {} },
|
|
1708
|
+
delete_workflow: { method: "DELETE", path: "/workflows/{workflowId}" },
|
|
1709
|
+
activate_workflow: { method: "PATCH", path: "/workflows/{workflowId}", body: { active: true } },
|
|
1710
|
+
deactivate_workflow: { method: "PATCH", path: "/workflows/{workflowId}", body: { active: false } },
|
|
1711
|
+
list_executions: { method: "GET", path: "/executions", query: ["workflowId", "status", "limit", "cursor"] },
|
|
1712
|
+
get_execution: { method: "GET", path: "/executions/{executionId}" },
|
|
1713
|
+
delete_execution: { method: "DELETE", path: "/executions/{executionId}" },
|
|
1714
|
+
list_credentials: { method: "GET", path: "/credentials", query: ["limit", "cursor"] },
|
|
1715
|
+
create_credential: { method: "POST", path: "/credentials", body: { name: "", type: "", data: {} } },
|
|
1716
|
+
delete_credential: { method: "DELETE", path: "/credentials/{credentialId}" },
|
|
1717
|
+
execute_workflow: { method: "POST", path: "/workflows/{workflowId}/run", body: {} },
|
|
1718
|
+
},
|
|
1719
|
+
authHeader: (creds) => ({
|
|
1720
|
+
"X-N8N-API-KEY": creds.apiKey,
|
|
1721
|
+
"Content-Type": "application/json",
|
|
1722
|
+
}),
|
|
1723
|
+
},
|
|
1724
|
+
|
|
1725
|
+
// ── Pabbly Connect ──────────────────────────────────────────
|
|
1726
|
+
pabbly: {
|
|
1727
|
+
name: "Pabbly Connect",
|
|
1728
|
+
type: "automation",
|
|
1729
|
+
description: "Workflow automation — connect apps, build automations, manage workflows with webhook triggers",
|
|
1730
|
+
baseUrl: "https://connect.pabbly.com/api",
|
|
1731
|
+
authType: "api_key",
|
|
1732
|
+
credentialKeys: ["apiKey"],
|
|
1733
|
+
capabilities: [
|
|
1734
|
+
{ name: "manage_workflows", actions: ["list", "get", "create", "enable", "disable"], description: "Create and manage automation workflows" },
|
|
1735
|
+
{ name: "manage_connections", actions: ["list"], description: "View connected app integrations" },
|
|
1736
|
+
{ name: "manage_executions", actions: ["list", "get"], description: "View workflow execution history and logs" },
|
|
1737
|
+
{ name: "trigger_workflow", actions: ["execute"], description: "Trigger a workflow via webhook" },
|
|
1738
|
+
],
|
|
1739
|
+
endpoints: {
|
|
1740
|
+
list_workflows: { method: "GET", path: "/workflows", query: ["page", "limit"] },
|
|
1741
|
+
get_workflow: { method: "GET", path: "/workflows/{workflowId}" },
|
|
1742
|
+
create_workflow: { method: "POST", path: "/workflows", body: { name: "", trigger: {} } },
|
|
1743
|
+
enable_workflow: { method: "PUT", path: "/workflows/{workflowId}/enable" },
|
|
1744
|
+
disable_workflow: { method: "PUT", path: "/workflows/{workflowId}/disable" },
|
|
1745
|
+
list_connections: { method: "GET", path: "/connections" },
|
|
1746
|
+
list_executions: { method: "GET", path: "/workflows/{workflowId}/executions", query: ["page", "limit"] },
|
|
1747
|
+
get_execution: { method: "GET", path: "/workflows/{workflowId}/executions/{executionId}" },
|
|
1748
|
+
trigger_webhook: { method: "POST", path: "/webhooks/{webhookId}", body: {} },
|
|
1749
|
+
},
|
|
1750
|
+
authHeader: (creds) => ({
|
|
1751
|
+
"Authorization": `Bearer ${creds.apiKey}`,
|
|
1752
|
+
"Content-Type": "application/json",
|
|
1753
|
+
}),
|
|
1754
|
+
},
|
|
1755
|
+
|
|
1756
|
+
// ── Make (Integromat) ─────────────────────────────────────
|
|
1757
|
+
make: {
|
|
1758
|
+
name: "Make",
|
|
1759
|
+
type: "automation",
|
|
1760
|
+
description: "Visual automation platform (formerly Integromat) — scenarios, organizations, connections, data stores",
|
|
1761
|
+
baseUrl: "https://us1.make.com/api/v2",
|
|
1762
|
+
authType: "api_key",
|
|
1763
|
+
credentialKeys: ["apiToken"],
|
|
1764
|
+
capabilities: [
|
|
1765
|
+
{ name: "manage_scenarios", actions: ["list", "get", "create", "update", "start", "stop", "run"], description: "Create and manage automation scenarios" },
|
|
1766
|
+
{ name: "manage_connections", actions: ["list", "get", "verify"], description: "Manage app connections" },
|
|
1767
|
+
{ name: "manage_data_stores", actions: ["list", "get_records"], description: "Access internal data stores" },
|
|
1768
|
+
{ name: "manage_organizations", actions: ["list", "get"], description: "View organizations and teams" },
|
|
1769
|
+
{ name: "manage_executions", actions: ["list"], description: "View scenario execution history" },
|
|
1770
|
+
],
|
|
1771
|
+
endpoints: {
|
|
1772
|
+
list_scenarios: { method: "GET", path: "/scenarios", query: ["teamId", "folderId", "pg[limit]", "pg[offset]"] },
|
|
1773
|
+
get_scenario: { method: "GET", path: "/scenarios/{scenarioId}" },
|
|
1774
|
+
create_scenario: { method: "POST", path: "/scenarios", body: { teamId: 0, name: "", blueprint: {} } },
|
|
1775
|
+
update_scenario: { method: "PATCH", path: "/scenarios/{scenarioId}", body: {} },
|
|
1776
|
+
start_scenario: { method: "POST", path: "/scenarios/{scenarioId}/start" },
|
|
1777
|
+
stop_scenario: { method: "POST", path: "/scenarios/{scenarioId}/stop" },
|
|
1778
|
+
run_scenario: { method: "POST", path: "/scenarios/{scenarioId}/run", body: {} },
|
|
1779
|
+
list_connections: { method: "GET", path: "/connections", query: ["teamId", "pg[limit]"] },
|
|
1780
|
+
get_connection: { method: "GET", path: "/connections/{connectionId}" },
|
|
1781
|
+
verify_connection: { method: "POST", path: "/connections/{connectionId}/test" },
|
|
1782
|
+
list_data_stores: { method: "GET", path: "/data-stores", query: ["teamId"] },
|
|
1783
|
+
get_data_store_records:{ method: "GET", path: "/data-stores/{dataStoreId}/data", query: ["pg[limit]", "pg[offset]"] },
|
|
1784
|
+
list_organizations: { method: "GET", path: "/organizations" },
|
|
1785
|
+
get_organization: { method: "GET", path: "/organizations/{organizationId}" },
|
|
1786
|
+
list_executions: { method: "GET", path: "/scenarios/{scenarioId}/logs", query: ["pg[limit]", "pg[offset]"] },
|
|
1787
|
+
},
|
|
1788
|
+
authHeader: (creds) => ({
|
|
1789
|
+
"Authorization": `Token ${creds.apiToken}`,
|
|
1790
|
+
"Content-Type": "application/json",
|
|
1791
|
+
}),
|
|
1792
|
+
},
|
|
1793
|
+
|
|
1794
|
+
// ── Whimsical ──────────────────────────────────────────────
|
|
1795
|
+
whimsical: {
|
|
1796
|
+
name: "Whimsical",
|
|
1797
|
+
type: "design",
|
|
1798
|
+
description: "Visual collaboration — flowcharts, wireframes, mind maps, docs, sticky notes, and AI-powered diagramming",
|
|
1799
|
+
baseUrl: "https://api.whimsical.com",
|
|
1800
|
+
authType: "oauth",
|
|
1801
|
+
credentialKeys: ["accessToken"],
|
|
1802
|
+
capabilities: [
|
|
1803
|
+
{ name: "manage_workspaces", actions: ["list", "get"], description: "List and view workspaces" },
|
|
1804
|
+
{ name: "manage_boards", actions: ["list", "get", "create", "update", "delete"], description: "Create and manage whiteboards, flowcharts, wireframes" },
|
|
1805
|
+
{ name: "manage_docs", actions: ["list", "get", "create", "update"], description: "Create and manage documents" },
|
|
1806
|
+
{ name: "manage_mind_maps", actions: ["list", "get", "create"], description: "Create and manage mind maps" },
|
|
1807
|
+
{ name: "generate_diagrams", actions: ["create_from_mermaid", "create_from_text"], description: "AI-powered diagram generation from text or Mermaid markup" },
|
|
1808
|
+
{ name: "manage_users", actions: ["list", "create", "update", "deactivate"], description: "SCIM user provisioning and management" },
|
|
1809
|
+
],
|
|
1810
|
+
endpoints: {
|
|
1811
|
+
list_workspaces: { method: "GET", path: "/workspaces" },
|
|
1812
|
+
get_workspace: { method: "GET", path: "/workspaces/{workspaceId}" },
|
|
1813
|
+
list_boards: { method: "GET", path: "/workspaces/{workspaceId}/boards", query: ["type", "limit", "cursor"] },
|
|
1814
|
+
get_board: { method: "GET", path: "/boards/{boardId}" },
|
|
1815
|
+
create_board: { method: "POST", path: "/workspaces/{workspaceId}/boards", body: { name: "", type: "flowchart" } },
|
|
1816
|
+
update_board: { method: "PATCH", path: "/boards/{boardId}", body: {} },
|
|
1817
|
+
delete_board: { method: "DELETE", path: "/boards/{boardId}" },
|
|
1818
|
+
get_board_export: { method: "GET", path: "/boards/{boardId}/export", query: ["format"] },
|
|
1819
|
+
list_docs: { method: "GET", path: "/workspaces/{workspaceId}/docs", query: ["limit", "cursor"] },
|
|
1820
|
+
get_doc: { method: "GET", path: "/docs/{docId}" },
|
|
1821
|
+
create_doc: { method: "POST", path: "/workspaces/{workspaceId}/docs", body: { title: "", content: "" } },
|
|
1822
|
+
update_doc: { method: "PATCH", path: "/docs/{docId}", body: {} },
|
|
1823
|
+
create_from_mermaid: { method: "POST", path: "/boards/from-mermaid", body: { workspaceId: "", mermaid: "", name: "" } },
|
|
1824
|
+
create_from_text: { method: "POST", path: "/boards/from-text", body: { workspaceId: "", text: "", type: "flowchart" } },
|
|
1825
|
+
list_scim_users: { method: "GET", path: "/scim-v2/Users", query: ["filter", "count", "startIndex"] },
|
|
1826
|
+
create_scim_user: { method: "POST", path: "/scim-v2/Users", body: { schemas: ["urn:ietf:params:scim:schemas:core:2.0:User"], userName: "", name: {} } },
|
|
1827
|
+
update_scim_user: { method: "PUT", path: "/scim-v2/Users/{userId}", body: {} },
|
|
1828
|
+
deactivate_scim_user: { method: "PATCH", path: "/scim-v2/Users/{userId}", body: { Operations: [{ op: "replace", value: { active: false } }] } },
|
|
1829
|
+
},
|
|
1830
|
+
authHeader: (creds) => ({
|
|
1831
|
+
"Authorization": `Bearer ${creds.accessToken}`,
|
|
1832
|
+
"Content-Type": "application/json",
|
|
1833
|
+
}),
|
|
1834
|
+
},
|
|
1835
|
+
|
|
1520
1836
|
};
|
|
1521
1837
|
|
|
1522
1838
|
// ── Helpers ────────────────────────────────────────────────
|
package/crm/helpers.js
CHANGED
|
@@ -35,7 +35,7 @@ export function crmHeaders(accessToken) {
|
|
|
35
35
|
* Every tool automatically receives `access_token` (required) and
|
|
36
36
|
* `location_id` (optional) parameters.
|
|
37
37
|
*/
|
|
38
|
-
export function registerTools(server, z, definitions) {
|
|
38
|
+
export function registerTools(server, z, definitions, proxy) {
|
|
39
39
|
for (const def of definitions) {
|
|
40
40
|
const schema = buildSchema(z, def);
|
|
41
41
|
|
|
@@ -93,11 +93,14 @@ export function registerTools(server, z, definitions) {
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
96
|
+
// Execute through capability proxy (rate-limited, audited)
|
|
97
|
+
// CRM tools receive access_token per-call from AI client, not from ConnectionManager
|
|
98
|
+
const { response: res, data } = proxy
|
|
99
|
+
? await proxy.callWithCredentials("crm", def.name, url, options)
|
|
100
|
+
: await fetch(url, options).then(async r => ({
|
|
101
|
+
response: r,
|
|
102
|
+
data: await r.json().catch(() => ({ status: r.status, statusText: r.statusText })),
|
|
103
|
+
}));
|
|
101
104
|
|
|
102
105
|
return {
|
|
103
106
|
content: [
|
package/crm/index.js
CHANGED
|
@@ -50,8 +50,9 @@ export {
|
|
|
50
50
|
* Register ALL CRM tools on the MCP server.
|
|
51
51
|
* @param {import("@modelcontextprotocol/sdk/server/mcp.js").McpServer} server
|
|
52
52
|
* @param {import("zod")} z
|
|
53
|
+
* @param {import("../capability-proxy.js").CapabilityProxy} [proxy]
|
|
53
54
|
*/
|
|
54
|
-
export function registerCrmTools(server, z) {
|
|
55
|
+
export function registerCrmTools(server, z, proxy) {
|
|
55
56
|
// 1. Auth & custom-logic tools (OAuth, snapshot deploy, workflow process)
|
|
56
57
|
registerAuthTools(server, z);
|
|
57
58
|
|
|
@@ -72,7 +73,7 @@ export function registerCrmTools(server, z) {
|
|
|
72
73
|
|
|
73
74
|
let totalTools = 5; // auth tools count
|
|
74
75
|
for (const cat of categories) {
|
|
75
|
-
registerTools(server, z, cat.defs);
|
|
76
|
+
registerTools(server, z, cat.defs, proxy);
|
|
76
77
|
totalTools += cat.defs.length;
|
|
77
78
|
}
|
|
78
79
|
|
package/engine/validator.js
CHANGED
|
@@ -168,9 +168,21 @@ const VERIFICATION_ENDPOINTS = {
|
|
|
168
168
|
check: (r) => r.status === 200 || r.status === 400, // 400 = auth works, bad params
|
|
169
169
|
},
|
|
170
170
|
crm: {
|
|
171
|
-
url: "https://services.leadconnectorhq.com/
|
|
171
|
+
url: "https://services.leadconnectorhq.com/calendars/services",
|
|
172
172
|
method: "GET",
|
|
173
173
|
headers: (c) => ({ Authorization: `Bearer ${c.access_token}`, Version: "2021-07-28" }),
|
|
174
|
+
check: (r) => r.status === 200 || r.status === 400 || r.status === 422, // 400/422 = auth works, missing params
|
|
175
|
+
},
|
|
176
|
+
anthropic: {
|
|
177
|
+
url: "https://api.anthropic.com/v1/models",
|
|
178
|
+
method: "GET",
|
|
179
|
+
headers: (c) => ({ "x-api-key": c.apiKey, "anthropic-version": "2023-06-01" }),
|
|
180
|
+
check: (r) => r.status === 200,
|
|
181
|
+
},
|
|
182
|
+
vercel: {
|
|
183
|
+
url: "https://api.vercel.com/v9/projects",
|
|
184
|
+
method: "GET",
|
|
185
|
+
headers: (c) => ({ Authorization: `Bearer ${c.apiKey}` }),
|
|
174
186
|
check: (r) => r.status === 200,
|
|
175
187
|
},
|
|
176
188
|
};
|
package/index.js
CHANGED
|
@@ -32,30 +32,33 @@ import { registerContainerTools } from "./vault/tools-container.js";
|
|
|
32
32
|
import { registerDeedTools } from "./vault/tools-deed.js";
|
|
33
33
|
import { unsealedCache } from "./vault/cache.js";
|
|
34
34
|
import { registerEngineTools } from "./engine/index.js";
|
|
35
|
+
import { CapabilityProxy } from "./capability-proxy.js";
|
|
36
|
+
import { SERVICE_CATALOG } from "./catalog.js";
|
|
35
37
|
|
|
36
38
|
// ── Initialize ─────────────────────────────────────────────
|
|
37
39
|
const connections = new ConnectionManager();
|
|
38
40
|
connections._vaultCache = unsealedCache;
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
+
const proxy = new CapabilityProxy(connections, SERVICE_CATALOG);
|
|
42
|
+
const orchestrator = new Orchestrator(connections, proxy);
|
|
43
|
+
const workflowRunner = new WorkflowRunner(connections, proxy);
|
|
41
44
|
|
|
42
45
|
const server = new McpServer({
|
|
43
46
|
name: "0nMCP",
|
|
44
|
-
version: "2.
|
|
47
|
+
version: "2.2.0",
|
|
45
48
|
});
|
|
46
49
|
|
|
47
50
|
// ============================================================
|
|
48
51
|
// REGISTER ALL TOOLS
|
|
49
52
|
// ============================================================
|
|
50
53
|
|
|
51
|
-
registerAllTools(server, connections, orchestrator, workflowRunner);
|
|
54
|
+
registerAllTools(server, connections, orchestrator, workflowRunner, proxy);
|
|
52
55
|
|
|
53
56
|
// ============================================================
|
|
54
57
|
// SERVICE-SPECIFIC TOOLS
|
|
55
58
|
// ============================================================
|
|
56
59
|
|
|
57
60
|
import { z } from "zod";
|
|
58
|
-
registerCrmTools(server, z);
|
|
61
|
+
registerCrmTools(server, z, proxy);
|
|
59
62
|
|
|
60
63
|
// ============================================================
|
|
61
64
|
// VAULT TOOLS (machine-bound credential encryption)
|
package/lib/stats.json
CHANGED
package/orchestrator.js
CHANGED
|
@@ -38,9 +38,11 @@ const CAPABILITY_KEYWORDS = {
|
|
|
38
38
|
export class Orchestrator {
|
|
39
39
|
/**
|
|
40
40
|
* @param {import("./connections.js").ConnectionManager} connectionManager
|
|
41
|
+
* @param {import("./capability-proxy.js").CapabilityProxy} [proxy]
|
|
41
42
|
*/
|
|
42
|
-
constructor(connectionManager) {
|
|
43
|
+
constructor(connectionManager, proxy) {
|
|
43
44
|
this.connections = connectionManager;
|
|
45
|
+
this.proxy = proxy;
|
|
44
46
|
this.anthropic = null;
|
|
45
47
|
|
|
46
48
|
// Dynamically import Anthropic SDK if key is available
|
|
@@ -277,14 +279,7 @@ Rules:
|
|
|
277
279
|
}
|
|
278
280
|
|
|
279
281
|
try {
|
|
280
|
-
//
|
|
281
|
-
let url = service.baseUrl + endpoint.path;
|
|
282
|
-
|
|
283
|
-
// Substitute path params from step.params and credentials
|
|
284
|
-
const allParams = { ...creds, ...step.params };
|
|
285
|
-
url = url.replace(/\{(\w+)\}/g, (_, key) => allParams[key] || `{${key}}`);
|
|
286
|
-
|
|
287
|
-
// Substitute context references {{label.field}}
|
|
282
|
+
// Substitute context references {{label.field}} in params
|
|
288
283
|
if (step.params) {
|
|
289
284
|
const paramsStr = JSON.stringify(step.params);
|
|
290
285
|
const resolved = paramsStr.replace(/\{\{(\w+)\.(\w+)\}\}/g, (_, label, field) => {
|
|
@@ -293,32 +288,8 @@ Rules:
|
|
|
293
288
|
step.params = JSON.parse(resolved);
|
|
294
289
|
}
|
|
295
290
|
|
|
296
|
-
//
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
// Build request options
|
|
300
|
-
const options = { method: endpoint.method, headers };
|
|
301
|
-
|
|
302
|
-
if (endpoint.method !== "GET" && step.params) {
|
|
303
|
-
const contentType = endpoint.contentType || "application/json";
|
|
304
|
-
if (contentType === "application/x-www-form-urlencoded") {
|
|
305
|
-
headers["Content-Type"] = "application/x-www-form-urlencoded";
|
|
306
|
-
options.body = new URLSearchParams(this._flattenParams(step.params)).toString();
|
|
307
|
-
} else {
|
|
308
|
-
headers["Content-Type"] = "application/json";
|
|
309
|
-
options.body = JSON.stringify(step.params);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// Add query params for GET requests
|
|
314
|
-
if (endpoint.method === "GET" && step.params) {
|
|
315
|
-
const queryStr = new URLSearchParams(this._flattenParams(step.params)).toString();
|
|
316
|
-
if (queryStr) url += (url.includes("?") ? "&" : "?") + queryStr;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// Execute
|
|
320
|
-
const response = await fetch(url, options);
|
|
321
|
-
const data = await response.json().catch(() => ({ status: response.status }));
|
|
291
|
+
// Execute through capability proxy (rate-limited, audited, zero-knowledge)
|
|
292
|
+
const { response, data } = await this.proxy.call(step.service, step.endpoint, step.params || {});
|
|
322
293
|
|
|
323
294
|
return {
|
|
324
295
|
success: response.ok,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "0nmcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"mcpName": "io.github.0nork/0nMCP",
|
|
5
5
|
"description": "Universal AI API Orchestrator — 819 tools, 48 services, portable AI Brain bundles + machine-bound vault encryption + Application Engine. The most comprehensive MCP server available. Free and open source from 0nORK.",
|
|
6
6
|
"type": "module",
|
|
@@ -246,6 +246,7 @@
|
|
|
246
246
|
"catalog.js",
|
|
247
247
|
"connections.js",
|
|
248
248
|
"orchestrator.js",
|
|
249
|
+
"capability-proxy.js",
|
|
249
250
|
"crm.js",
|
|
250
251
|
"crm/",
|
|
251
252
|
"webhooks.js",
|
|
@@ -271,6 +272,6 @@
|
|
|
271
272
|
"triggers": 155,
|
|
272
273
|
"totalCapabilities": 1078,
|
|
273
274
|
"categories": 21,
|
|
274
|
-
"lastUpdated": "2026-03-
|
|
275
|
+
"lastUpdated": "2026-03-13T00:31:43.573Z"
|
|
275
276
|
}
|
|
276
277
|
}
|
package/tools.js
CHANGED
|
@@ -16,7 +16,7 @@ import { SERVICE_CATALOG, listServices, getService } from "./catalog.js";
|
|
|
16
16
|
* @param {import("./orchestrator.js").Orchestrator} orchestrator
|
|
17
17
|
* @param {import("./workflow.js").WorkflowRunner} [workflowRunner]
|
|
18
18
|
*/
|
|
19
|
-
export function registerAllTools(server, connections, orchestrator, workflowRunner) {
|
|
19
|
+
export function registerAllTools(server, connections, orchestrator, workflowRunner, proxy) {
|
|
20
20
|
// ─── execute ───────────────────────────────────────────
|
|
21
21
|
server.tool(
|
|
22
22
|
"execute",
|
|
@@ -291,41 +291,8 @@ Examples:
|
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
try {
|
|
294
|
-
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
// Substitute path params
|
|
298
|
-
url = url.replace(/\{(\w+)\}/g, (_, key) => allParams[key] || `{${key}}`);
|
|
299
|
-
|
|
300
|
-
const headers = catalog.authHeader(creds);
|
|
301
|
-
const options = { method: ep.method, headers };
|
|
302
|
-
|
|
303
|
-
if (ep.method !== "GET" && params) {
|
|
304
|
-
const contentType = ep.contentType || "application/json";
|
|
305
|
-
if (contentType === "application/x-www-form-urlencoded") {
|
|
306
|
-
headers["Content-Type"] = "application/x-www-form-urlencoded";
|
|
307
|
-
const flat = {};
|
|
308
|
-
for (const [k, v] of Object.entries(params)) {
|
|
309
|
-
if (typeof v !== "object") flat[k] = String(v);
|
|
310
|
-
}
|
|
311
|
-
options.body = new URLSearchParams(flat).toString();
|
|
312
|
-
} else {
|
|
313
|
-
headers["Content-Type"] = "application/json";
|
|
314
|
-
options.body = JSON.stringify(params);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (ep.method === "GET" && params) {
|
|
319
|
-
const flat = {};
|
|
320
|
-
for (const [k, v] of Object.entries(params)) {
|
|
321
|
-
if (typeof v !== "object") flat[k] = String(v);
|
|
322
|
-
}
|
|
323
|
-
const qs = new URLSearchParams(flat).toString();
|
|
324
|
-
if (qs) url += (url.includes("?") ? "&" : "?") + qs;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
const response = await fetch(url, options);
|
|
328
|
-
const data = await response.json().catch(() => ({ status: response.status, statusText: response.statusText }));
|
|
294
|
+
// Execute through capability proxy (rate-limited, audited, zero-knowledge)
|
|
295
|
+
const { response, data } = await proxy.call(service, endpoint, params || {});
|
|
329
296
|
|
|
330
297
|
return {
|
|
331
298
|
content: [{
|