adoptai-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README.md +70 -0
  2. package/bin/adoptai-mcp.js +2 -0
  3. package/dist/apps/canva.js +1 -0
  4. package/dist/apps/figma.js +1 -0
  5. package/dist/apps/github.js +2 -0
  6. package/dist/apps/notion.js +1 -0
  7. package/dist/apps/registry.js +20 -0
  8. package/dist/apps/salesforce.js +1 -0
  9. package/dist/cli/add.js +532 -0
  10. package/dist/cli/index.js +39 -0
  11. package/dist/cli/list.js +19 -0
  12. package/dist/cli/remove.js +37 -0
  13. package/dist/cli/serve.js +27 -0
  14. package/dist/cli/status.js +24 -0
  15. package/dist/config/clients.js +118 -0
  16. package/dist/config/credentials.js +34 -0
  17. package/dist/core/auth-manager.js +237 -0
  18. package/dist/core/config-writer.js +161 -0
  19. package/dist/core/doctor.js +199 -0
  20. package/dist/core/package.json +3 -0
  21. package/dist/core/server-base.js +81 -0
  22. package/dist/integrations/canva/.env +3 -0
  23. package/dist/integrations/canva/auth.js +287 -0
  24. package/dist/integrations/canva/env.js +9 -0
  25. package/dist/integrations/canva/index.js +12 -0
  26. package/dist/integrations/canva/package.json +31 -0
  27. package/dist/integrations/canva/publish-to-adoptai.js +365 -0
  28. package/dist/integrations/canva/setup.js +90 -0
  29. package/dist/integrations/canva/tools.js +1315 -0
  30. package/dist/integrations/canva/tools.original.js +1315 -0
  31. package/dist/integrations/figma/auth.js +48 -0
  32. package/dist/integrations/figma/index.js +11 -0
  33. package/dist/integrations/figma/package.json +27 -0
  34. package/dist/integrations/figma/publish-to-adoptai.js +384 -0
  35. package/dist/integrations/figma/setup.js +90 -0
  36. package/dist/integrations/figma/tools.js +1137 -0
  37. package/dist/integrations/github/auth.js +53 -0
  38. package/dist/integrations/github/index.js +11 -0
  39. package/dist/integrations/github/package.json +28 -0
  40. package/dist/integrations/github/publish-to-adoptai.js +240 -0
  41. package/dist/integrations/github/setup.js +103 -0
  42. package/dist/integrations/github/tools.js +78 -0
  43. package/dist/integrations/github-actions/auth.js +53 -0
  44. package/dist/integrations/github-actions/index.js +11 -0
  45. package/dist/integrations/github-actions/package.json +27 -0
  46. package/dist/integrations/github-actions/setup.js +103 -0
  47. package/dist/integrations/github-actions/tools.js +5642 -0
  48. package/dist/integrations/github-activity/auth.js +53 -0
  49. package/dist/integrations/github-activity/index.js +11 -0
  50. package/dist/integrations/github-activity/package.json +27 -0
  51. package/dist/integrations/github-activity/setup.js +103 -0
  52. package/dist/integrations/github-activity/tools.js +925 -0
  53. package/dist/integrations/github-apps/auth.js +53 -0
  54. package/dist/integrations/github-apps/index.js +11 -0
  55. package/dist/integrations/github-apps/package.json +27 -0
  56. package/dist/integrations/github-apps/setup.js +103 -0
  57. package/dist/integrations/github-apps/tools.js +791 -0
  58. package/dist/integrations/github-billing/auth.js +53 -0
  59. package/dist/integrations/github-billing/index.js +11 -0
  60. package/dist/integrations/github-billing/package.json +27 -0
  61. package/dist/integrations/github-billing/setup.js +103 -0
  62. package/dist/integrations/github-billing/tools.js +438 -0
  63. package/dist/integrations/github-checks/auth.js +53 -0
  64. package/dist/integrations/github-checks/index.js +11 -0
  65. package/dist/integrations/github-checks/package.json +27 -0
  66. package/dist/integrations/github-checks/setup.js +103 -0
  67. package/dist/integrations/github-checks/tools.js +607 -0
  68. package/dist/integrations/github-code-scanning/auth.js +53 -0
  69. package/dist/integrations/github-code-scanning/index.js +11 -0
  70. package/dist/integrations/github-code-scanning/package.json +27 -0
  71. package/dist/integrations/github-code-scanning/setup.js +103 -0
  72. package/dist/integrations/github-code-scanning/tools.js +987 -0
  73. package/dist/integrations/github-dependabot/auth.js +53 -0
  74. package/dist/integrations/github-dependabot/index.js +11 -0
  75. package/dist/integrations/github-dependabot/package.json +27 -0
  76. package/dist/integrations/github-dependabot/setup.js +103 -0
  77. package/dist/integrations/github-dependabot/tools.js +915 -0
  78. package/dist/integrations/github-gists/auth.js +53 -0
  79. package/dist/integrations/github-gists/index.js +11 -0
  80. package/dist/integrations/github-gists/package.json +27 -0
  81. package/dist/integrations/github-gists/setup.js +103 -0
  82. package/dist/integrations/github-gists/tools.js +545 -0
  83. package/dist/integrations/github-git/auth.js +53 -0
  84. package/dist/integrations/github-git/index.js +11 -0
  85. package/dist/integrations/github-git/package.json +27 -0
  86. package/dist/integrations/github-git/setup.js +103 -0
  87. package/dist/integrations/github-git/tools.js +513 -0
  88. package/dist/integrations/github-issues/auth.js +53 -0
  89. package/dist/integrations/github-issues/index.js +11 -0
  90. package/dist/integrations/github-issues/package.json +27 -0
  91. package/dist/integrations/github-issues/setup.js +103 -0
  92. package/dist/integrations/github-issues/tools.js +2232 -0
  93. package/dist/integrations/github-orgs/auth.js +53 -0
  94. package/dist/integrations/github-orgs/index.js +11 -0
  95. package/dist/integrations/github-orgs/package.json +27 -0
  96. package/dist/integrations/github-orgs/setup.js +103 -0
  97. package/dist/integrations/github-orgs/tools.js +3512 -0
  98. package/dist/integrations/github-packages/auth.js +53 -0
  99. package/dist/integrations/github-packages/index.js +11 -0
  100. package/dist/integrations/github-packages/package.json +27 -0
  101. package/dist/integrations/github-packages/setup.js +103 -0
  102. package/dist/integrations/github-packages/tools.js +1088 -0
  103. package/dist/integrations/github-pulls/auth.js +53 -0
  104. package/dist/integrations/github-pulls/index.js +11 -0
  105. package/dist/integrations/github-pulls/package.json +27 -0
  106. package/dist/integrations/github-pulls/setup.js +103 -0
  107. package/dist/integrations/github-pulls/tools.js +1252 -0
  108. package/dist/integrations/github-reactions/auth.js +53 -0
  109. package/dist/integrations/github-reactions/index.js +11 -0
  110. package/dist/integrations/github-reactions/package.json +27 -0
  111. package/dist/integrations/github-reactions/setup.js +103 -0
  112. package/dist/integrations/github-reactions/tools.js +706 -0
  113. package/dist/integrations/github-repos/auth.js +53 -0
  114. package/dist/integrations/github-repos/index.js +11 -0
  115. package/dist/integrations/github-repos/package.json +27 -0
  116. package/dist/integrations/github-repos/setup.js +103 -0
  117. package/dist/integrations/github-repos/tools.js +7286 -0
  118. package/dist/integrations/github-search/auth.js +53 -0
  119. package/dist/integrations/github-search/index.js +11 -0
  120. package/dist/integrations/github-search/package.json +27 -0
  121. package/dist/integrations/github-search/setup.js +103 -0
  122. package/dist/integrations/github-search/tools.js +370 -0
  123. package/dist/integrations/github-teams/auth.js +53 -0
  124. package/dist/integrations/github-teams/index.js +11 -0
  125. package/dist/integrations/github-teams/package.json +27 -0
  126. package/dist/integrations/github-teams/setup.js +103 -0
  127. package/dist/integrations/github-teams/tools.js +633 -0
  128. package/dist/integrations/github-users/auth.js +53 -0
  129. package/dist/integrations/github-users/index.js +11 -0
  130. package/dist/integrations/github-users/package.json +27 -0
  131. package/dist/integrations/github-users/setup.js +103 -0
  132. package/dist/integrations/github-users/tools.js +1118 -0
  133. package/dist/integrations/notion/api.js +108 -0
  134. package/dist/integrations/notion/auth.js +59 -0
  135. package/dist/integrations/notion/endpoints.json +630 -0
  136. package/dist/integrations/notion/index.js +11 -0
  137. package/dist/integrations/notion/package.json +33 -0
  138. package/dist/integrations/notion/publish-to-adoptai.js +271 -0
  139. package/dist/integrations/notion/scripts/generate-endpoints.mjs +306 -0
  140. package/dist/integrations/notion/setup.js +89 -0
  141. package/dist/integrations/notion/tools.js +586 -0
  142. package/dist/integrations/notion/tools.original.js +568 -0
  143. package/dist/integrations/salesforce/.env +8 -0
  144. package/dist/integrations/salesforce/.env.example +15 -0
  145. package/dist/integrations/salesforce/auth.js +311 -0
  146. package/dist/integrations/salesforce/endpoints.json +1359 -0
  147. package/dist/integrations/salesforce/env.js +9 -0
  148. package/dist/integrations/salesforce/index.js +12 -0
  149. package/dist/integrations/salesforce/package.json +42 -0
  150. package/dist/integrations/salesforce/publish-smart-specs.js +890 -0
  151. package/dist/integrations/salesforce/publish-to-adoptai.js +386 -0
  152. package/dist/integrations/salesforce/scripts/extract-postman.mjs +222 -0
  153. package/dist/integrations/salesforce/setup.js +112 -0
  154. package/dist/integrations/salesforce/tools.js +4544 -0
  155. package/dist/integrations/salesforce/tools.original.js +4487 -0
  156. package/dist/server/mcp-server.js +50 -0
  157. package/dist/server/tool-loader.js +47 -0
  158. package/dist/specs/figma-api.json +13621 -0
  159. package/dist/specs/split/salesforce-auth.json +3931 -0
  160. package/dist/specs/split/salesforce-bulk-v1.json +1489 -0
  161. package/dist/specs/split/salesforce-bulk-v2.json +1951 -0
  162. package/dist/specs/split/salesforce-composite.json +1246 -0
  163. package/dist/specs/split/salesforce-connect.json +11639 -0
  164. package/dist/specs/split/salesforce-einstein-prediction-service.json +576 -0
  165. package/dist/specs/split/salesforce-event-platform.json +2682 -0
  166. package/dist/specs/split/salesforce-graphql.json +1754 -0
  167. package/dist/specs/split/salesforce-industries.json +4115 -0
  168. package/dist/specs/split/salesforce-metadata.json +555 -0
  169. package/dist/specs/split/salesforce-rest.json +4798 -0
  170. package/dist/specs/split/salesforce-soap.json +210 -0
  171. package/dist/specs/split/salesforce-subscription-management.json +1299 -0
  172. package/dist/specs/split/salesforce-tooling.json +2026 -0
  173. package/dist/specs/split/salesforce-ui.json +7426 -0
  174. package/package.json +47 -0
@@ -0,0 +1,890 @@
1
+ /**
2
+ * HTTP mappings for Salesforce MCP “smart” tools that are not Postman-generated.
3
+ * Used only by publish-to-adoptai.js (adopt catalog), not at MCP runtime.
4
+ */
5
+
6
+ export const SMART_PUBLISH_SPECS = {
7
+ get_account: {
8
+ method: 'GET',
9
+ path: '/sobjects/Account/{account_id}',
10
+ urlKind: 'versioned',
11
+ queryParamsExplicit: { fields: '{fields}' },
12
+ },
13
+
14
+ get_account_with_contacts: {
15
+ method: 'GET',
16
+ path: '/query/',
17
+ urlKind: 'versioned',
18
+ queryParamsExplicit: { q: '{q}' },
19
+ inputSchemaOverride: soqlQSchema(
20
+ 'SOQL for account + contacts. Example: SELECT Id,Name,(SELECT Id,FirstName,LastName,Email FROM Contacts) FROM Account WHERE Id = \'001…\''
21
+ ),
22
+ note: 'MCP builds SOQL from account_id; via HTTP pass the full SOQL as q.',
23
+ },
24
+ get_account_with_opportunities: {
25
+ method: 'GET',
26
+ path: '/query/',
27
+ urlKind: 'versioned',
28
+ queryParamsExplicit: { q: '{q}' },
29
+ inputSchemaOverride: soqlQSchema(
30
+ 'SOQL for account + opportunities. Example: SELECT Id,Name,(SELECT Id,Name,StageName,Amount FROM Opportunities) FROM Account WHERE Id = \'001…\''
31
+ ),
32
+ note: 'MCP builds SOQL from account_id; via HTTP pass the full SOQL as q.',
33
+ },
34
+ get_account_with_cases: {
35
+ method: 'GET',
36
+ path: '/query/',
37
+ urlKind: 'versioned',
38
+ queryParamsExplicit: { q: '{q}' },
39
+ inputSchemaOverride: soqlQSchema(
40
+ 'SOQL for account + open cases. Example: SELECT Id,Name,(SELECT Id,CaseNumber,Subject,Status FROM Cases WHERE IsClosed=false) FROM Account WHERE Id = \'001…\''
41
+ ),
42
+ note: 'MCP builds SOQL from account_id; via HTTP pass the full SOQL as q.',
43
+ },
44
+ get_account_full_profile: {
45
+ method: 'GET',
46
+ path: '/query/',
47
+ urlKind: 'versioned',
48
+ queryParamsExplicit: { q: '{q}' },
49
+ inputSchemaOverride: soqlQSchema(
50
+ 'SOQL for account + contacts + opportunities + cases in one query.'
51
+ ),
52
+ note: 'MCP builds SOQL from account_id; via HTTP pass the full SOQL as q.',
53
+ },
54
+
55
+ update_opportunity: {
56
+ method: 'PATCH',
57
+ path: '/sobjects/Opportunity/{opportunity_id}',
58
+ urlKind: 'versioned',
59
+ },
60
+ update_opportunity_stage: {
61
+ method: 'PATCH',
62
+ path: '/sobjects/Opportunity/{opportunity_id}',
63
+ urlKind: 'versioned',
64
+ bodyExplicit: {
65
+ StageName: '{stage}',
66
+ CloseDate: '{close_date}',
67
+ Probability: '{probability}',
68
+ },
69
+ omitArgsFromHttp: [],
70
+ },
71
+ update_opportunity_amount: {
72
+ method: 'PATCH',
73
+ path: '/sobjects/Opportunity/{opportunity_id}',
74
+ urlKind: 'versioned',
75
+ bodyExplicit: { Amount: '{amount}' },
76
+ },
77
+ update_opportunity_close_date: {
78
+ method: 'PATCH',
79
+ path: '/sobjects/Opportunity/{opportunity_id}',
80
+ urlKind: 'versioned',
81
+ bodyExplicit: { CloseDate: '{close_date}' },
82
+ },
83
+ close_won_opportunity: {
84
+ method: 'PATCH',
85
+ path: '/sobjects/Opportunity/{opportunity_id}',
86
+ urlKind: 'versioned',
87
+ bodyExplicit: {
88
+ StageName: 'Closed Won',
89
+ Probability: 100,
90
+ CloseDate: '{close_date}',
91
+ },
92
+ },
93
+ close_lost_opportunity: {
94
+ method: 'PATCH',
95
+ path: '/sobjects/Opportunity/{opportunity_id}',
96
+ urlKind: 'versioned',
97
+ bodyExplicit: {
98
+ StageName: 'Closed Lost',
99
+ Probability: 0,
100
+ Description: '{loss_reason}',
101
+ },
102
+ },
103
+
104
+ run_soql_query: {
105
+ method: 'GET',
106
+ path: '/query/',
107
+ urlKind: 'versioned',
108
+ queryParamsExplicit: { q: '{query}' },
109
+ omitArgsFromHttp: ['limit'],
110
+ note: 'limit is MCP-only (appends LIMIT to SOQL). For HTTP, include LIMIT inside query or omit.',
111
+ },
112
+ run_soql_query_all_pages: {
113
+ method: 'GET',
114
+ path: '/query/',
115
+ urlKind: 'versioned',
116
+ queryParamsExplicit: { q: '{query}' },
117
+ omitArgsFromHttp: ['max_records'],
118
+ note: 'Returns first page only via HTTP; use nextRecordsUrl for more pages. max_records is MCP-only.',
119
+ },
120
+
121
+ search_accounts: {
122
+ method: 'GET',
123
+ path: '/query/',
124
+ urlKind: 'versioned',
125
+ queryParamsExplicit: { q: '{q}' },
126
+ inputSchemaOverride: soqlQSchema('SOQL for Account search (MCP builds from name/industry/type/city).'),
127
+ note: 'MCP composes WHERE from filters; via HTTP pass full SOQL as q.',
128
+ },
129
+ search_contacts: {
130
+ method: 'GET',
131
+ path: '/query/',
132
+ urlKind: 'versioned',
133
+ queryParamsExplicit: { q: '{q}' },
134
+ inputSchemaOverride: soqlQSchema('SOQL for Contact search.'),
135
+ note: 'MCP composes WHERE from filters; via HTTP pass full SOQL as q.',
136
+ },
137
+ search_leads: {
138
+ method: 'GET',
139
+ path: '/query/',
140
+ urlKind: 'versioned',
141
+ queryParamsExplicit: { q: '{q}' },
142
+ inputSchemaOverride: soqlQSchema('SOQL for Lead search.'),
143
+ note: 'MCP composes WHERE from filters; via HTTP pass full SOQL as q.',
144
+ },
145
+ search_opportunities: {
146
+ method: 'GET',
147
+ path: '/query/',
148
+ urlKind: 'versioned',
149
+ queryParamsExplicit: { q: '{q}' },
150
+ inputSchemaOverride: soqlQSchema('SOQL for Opportunity search.'),
151
+ note: 'MCP composes WHERE from filters; via HTTP pass full SOQL as q.',
152
+ },
153
+ get_pipeline_summary: {
154
+ method: 'GET',
155
+ path: '/query/',
156
+ urlKind: 'versioned',
157
+ queryParamsExplicit: { q: '{q}' },
158
+ inputSchemaOverride: soqlQSchema(
159
+ 'Aggregate SOQL e.g. SELECT StageName, COUNT(Id), SUM(Amount) FROM Opportunity WHERE IsClosed = false … GROUP BY StageName'
160
+ ),
161
+ note: 'MCP builds GROUP BY from owner_id/period; via HTTP pass full SOQL as q.',
162
+ },
163
+ global_search: {
164
+ method: 'GET',
165
+ path: '/search/',
166
+ urlKind: 'versioned',
167
+ queryParamsExplicit: { q: '{q}' },
168
+ inputSchemaOverride: {
169
+ type: 'object',
170
+ properties: {
171
+ q: {
172
+ type: 'string',
173
+ description:
174
+ 'Full SOSL string, e.g. FIND {Acme} IN ALL FIELDS RETURNING Account(Id,Name),Contact(Id,Name) LIMIT 10',
175
+ },
176
+ },
177
+ required: ['q'],
178
+ },
179
+ note: 'MCP builds SOSL from search_term/objects/limit; via HTTP pass full SOSL as q.',
180
+ },
181
+
182
+ create_task: {
183
+ method: 'POST',
184
+ path: '/sobjects/Task',
185
+ urlKind: 'versioned',
186
+ },
187
+ log_call: {
188
+ method: 'POST',
189
+ path: '/sobjects/Task',
190
+ urlKind: 'versioned',
191
+ bodyExplicit: {
192
+ Subject: '{subject}',
193
+ Type: 'Call',
194
+ Status: 'Completed',
195
+ TaskSubtype: 'Call',
196
+ WhoId: '{who_id}',
197
+ WhatId: '{what_id}',
198
+ Description: '{description}',
199
+ CallDurationInSeconds: '{duration_seconds}',
200
+ CallDisposition: '{call_disposition}',
201
+ CallType: '{call_type}',
202
+ },
203
+ inputSchemaOverride: {
204
+ type: 'object',
205
+ properties: {
206
+ subject: { type: 'string' },
207
+ who_id: { type: 'string' },
208
+ what_id: { type: 'string' },
209
+ description: { type: 'string' },
210
+ duration_seconds: {
211
+ type: 'number',
212
+ description: 'Call duration in seconds (MCP uses duration_minutes × 60).',
213
+ },
214
+ call_disposition: { type: 'string' },
215
+ call_type: { type: 'string' },
216
+ },
217
+ required: ['subject'],
218
+ },
219
+ note: 'MCP maps duration_minutes to CallDurationInSeconds; HTTP uses duration_seconds.',
220
+ },
221
+ log_email: {
222
+ method: 'POST',
223
+ path: '/sobjects/EmailMessage',
224
+ urlKind: 'versioned',
225
+ bodyExplicit: {
226
+ Subject: '{subject}',
227
+ Status: '3',
228
+ Incoming: false,
229
+ TextBody: '{body}',
230
+ ToAddress: '{to_address}',
231
+ MessageDate: '{sent_date}',
232
+ RelatedToId: '{related_to_id}',
233
+ },
234
+ inputSchemaOverride: {
235
+ type: 'object',
236
+ properties: {
237
+ subject: { type: 'string' },
238
+ to_address: { type: 'string' },
239
+ body: { type: 'string' },
240
+ sent_date: { type: 'string' },
241
+ related_to_id: {
242
+ type: 'string',
243
+ description: 'MCP sets from what_id or who_id; pass the target record Id.',
244
+ },
245
+ },
246
+ required: ['subject'],
247
+ },
248
+ note: 'Set related_to_id to WhatId/WhoId target. MCP chooses what_id vs who_id.',
249
+ },
250
+ create_followup_task: {
251
+ method: 'POST',
252
+ path: '/sobjects/Task',
253
+ urlKind: 'versioned',
254
+ bodyExplicit: {
255
+ Subject: '{subject}',
256
+ ActivityDate: '{due_date}',
257
+ Status: 'Not Started',
258
+ WhoId: '{who_id}',
259
+ WhatId: '{what_id}',
260
+ Priority: '{priority}',
261
+ OwnerId: '{assigned_to_id}',
262
+ Description: '{description}',
263
+ },
264
+ },
265
+ get_todays_tasks: {
266
+ method: 'GET',
267
+ path: '/query/',
268
+ urlKind: 'versioned',
269
+ queryParamsExplicit: { q: '{q}' },
270
+ inputSchemaOverride: soqlQSchema(
271
+ 'SOQL for open tasks (today / overdue). Include OwnerId filter and ActivityDate predicates.'
272
+ ),
273
+ note: 'MCP defaults OwnerId from OAuth user; via HTTP include OwnerId in SOQL.',
274
+ },
275
+ get_overdue_tasks: {
276
+ method: 'GET',
277
+ path: '/query/',
278
+ urlKind: 'versioned',
279
+ queryParamsExplicit: { q: '{q}' },
280
+ inputSchemaOverride: soqlQSchema('SOQL for overdue tasks for a user.'),
281
+ note: 'MCP defaults OwnerId from OAuth; via HTTP include OwnerId in SOQL.',
282
+ },
283
+
284
+ update_lead: {
285
+ method: 'PATCH',
286
+ path: '/sobjects/Lead/{lead_id}',
287
+ urlKind: 'versioned',
288
+ },
289
+ update_lead_status: {
290
+ method: 'PATCH',
291
+ path: '/sobjects/Lead/{lead_id}',
292
+ urlKind: 'versioned',
293
+ bodyExplicit: { Status: '{status}' },
294
+ },
295
+ convert_lead: {
296
+ method: 'POST',
297
+ path: '/sobjects/Lead/{lead_id}/actions/standard/convert',
298
+ urlKind: 'versioned',
299
+ bodyExplicit: { inputs: '{inputs}' },
300
+ inputSchemaOverride: {
301
+ type: 'object',
302
+ properties: {
303
+ lead_id: { type: 'string' },
304
+ inputs: {
305
+ type: 'array',
306
+ items: { type: 'object', additionalProperties: true },
307
+ description: 'Salesforce Lead convert inputs[] (leadId, convertedStatus, doNotCreateOpportunity, etc.).',
308
+ },
309
+ },
310
+ required: ['lead_id', 'inputs'],
311
+ },
312
+ note: 'MCP builds inputs from create_opportunity/opportunity_name/account_id/contact_id; HTTP must pass inputs array.',
313
+ },
314
+
315
+ bulk_create_records: {
316
+ method: 'POST',
317
+ path: '/jobs/ingest',
318
+ urlKind: 'versioned',
319
+ bodyExplicit: {
320
+ object: '{object_type}',
321
+ operation: 'insert',
322
+ contentType: 'CSV',
323
+ lineEnding: 'LF',
324
+ columnDelimiter: 'COMMA',
325
+ },
326
+ omitArgsFromHttp: ['records', 'batch_size'],
327
+ note: 'Creates Bulk API 2 ingest job only. Upload CSV with bulk_v2_upload_job_data, then PATCH job UploadComplete.',
328
+ },
329
+ bulk_update_records: {
330
+ method: 'POST',
331
+ path: '/jobs/ingest',
332
+ urlKind: 'versioned',
333
+ bodyExplicit: {
334
+ object: '{object_type}',
335
+ operation: 'update',
336
+ contentType: 'CSV',
337
+ lineEnding: 'LF',
338
+ columnDelimiter: 'COMMA',
339
+ },
340
+ omitArgsFromHttp: ['records', 'batch_size'],
341
+ note: 'Creates job only; upload rows with Id column via bulk_v2_upload_job_data.',
342
+ },
343
+ bulk_upsert_records: {
344
+ method: 'POST',
345
+ path: '/jobs/ingest',
346
+ urlKind: 'versioned',
347
+ bodyExplicit: {
348
+ object: '{object_type}',
349
+ operation: 'upsert',
350
+ externalIdFieldName: '{external_id_field}',
351
+ contentType: 'CSV',
352
+ lineEnding: 'LF',
353
+ columnDelimiter: 'COMMA',
354
+ },
355
+ omitArgsFromHttp: ['records', 'batch_size'],
356
+ note: 'Creates job only; upload CSV via bulk_v2_upload_job_data.',
357
+ },
358
+ bulk_delete_records: {
359
+ method: 'POST',
360
+ path: '/jobs/ingest',
361
+ urlKind: 'versioned',
362
+ bodyExplicit: {
363
+ object: '{object_type}',
364
+ operation: 'delete',
365
+ contentType: 'CSV',
366
+ lineEnding: 'LF',
367
+ columnDelimiter: 'COMMA',
368
+ },
369
+ omitArgsFromHttp: ['record_ids'],
370
+ note: 'Creates delete job; MCP sends Ids as CSV. Via HTTP create job then PUT CSV of Ids to batches.',
371
+ },
372
+ get_bulk_job_status: {
373
+ method: 'GET',
374
+ path: '/jobs/ingest/{job_id}',
375
+ urlKind: 'versioned',
376
+ },
377
+ get_bulk_job_results: {
378
+ method: 'GET',
379
+ path: '/jobs/ingest/{job_id}/{result_segment}',
380
+ urlKind: 'versioned',
381
+ inputSchemaOverride: {
382
+ type: 'object',
383
+ properties: {
384
+ job_id: { type: 'string' },
385
+ result_segment: {
386
+ type: 'string',
387
+ enum: ['successfulResults', 'failedResults', 'unprocessedrecords'],
388
+ description: 'Path segment (note lowercase c in unprocessedrecords per Salesforce).',
389
+ },
390
+ },
391
+ required: ['job_id', 'result_segment'],
392
+ },
393
+ extraHeaders: { accept: 'text/csv' },
394
+ note: 'Returns CSV. Enum matches URL path segment.',
395
+ },
396
+ bulk_v2_upload_job_data: {
397
+ method: 'PUT',
398
+ path: '/jobs/ingest/{job_id}/batches',
399
+ urlKind: 'versioned',
400
+ rawStringBodyArg: 'csv_data',
401
+ contentTypeOverride: 'text/csv',
402
+ extraHeaders: { accept: 'application/json' },
403
+ note: 'Request body must be raw CSV bytes (not JSON). Adopt must substitute csv_data as raw body.',
404
+ },
405
+
406
+ bulk_v1_bulk_retrieve_batch_re_b03d6: {
407
+ method: 'GET',
408
+ path: '/job/{jobId}/batch/{batchId}/result/{batchResultId}',
409
+ urlKind: 'bulk-v1-async',
410
+ extraHeaders: { accept: 'text/csv' },
411
+ },
412
+ bulk_v1_bulk_retrieve_batch_result: {
413
+ method: 'GET',
414
+ path: '/job/{jobId}/batch/{batchId}/result',
415
+ urlKind: 'bulk-v1-async',
416
+ extraHeaders: { accept: 'text/csv' },
417
+ },
418
+ bulk_v1_get_job_query_result: {
419
+ method: 'GET',
420
+ path: '/jobs/query/{jobId}/results',
421
+ urlKind: 'versioned',
422
+ extraHeaders: { accept: 'text/csv' },
423
+ },
424
+ bulk_v1_bulk_create_batch: {
425
+ method: 'POST',
426
+ path: '/job/{jobId}/batch',
427
+ urlKind: 'bulk-v1-async',
428
+ rawStringBodyArg: 'csv_data',
429
+ contentTypeOverride: 'text/csv',
430
+ extraHeaders: { accept: 'application/json' },
431
+ note: 'Raw CSV body.',
432
+ },
433
+ bulk_v1_bulk_spec: {
434
+ method: 'POST',
435
+ path: '/job/{jobId}/spec',
436
+ urlKind: 'bulk-v1-async',
437
+ rawStringBodyArg: 'csv_data',
438
+ contentTypeOverride: 'text/csv',
439
+ extraHeaders: { accept: 'application/json' },
440
+ note: 'Raw CSV body for bulk spec.',
441
+ },
442
+
443
+ composite_create_acct_with_contact: {
444
+ method: 'POST',
445
+ path: '/composite/',
446
+ urlKind: 'versioned',
447
+ bodyExplicit: { compositeRequest: '{compositeRequest}' },
448
+ inputSchemaOverride: {
449
+ type: 'object',
450
+ properties: {
451
+ compositeRequest: {
452
+ type: 'array',
453
+ items: { type: 'object', additionalProperties: true },
454
+ description: 'Composite subrequests (e.g. POST Account then POST Contact with AccountId @{refAccount.id}).',
455
+ },
456
+ },
457
+ required: ['compositeRequest'],
458
+ },
459
+ note: 'MCP builds compositeRequest from account/contact objects.',
460
+ },
461
+ comp_opp_with_contact_role: {
462
+ method: 'POST',
463
+ path: '/composite/',
464
+ urlKind: 'versioned',
465
+ bodyExplicit: { compositeRequest: '{compositeRequest}' },
466
+ inputSchemaOverride: {
467
+ type: 'object',
468
+ properties: {
469
+ compositeRequest: { type: 'array', items: { type: 'object', additionalProperties: true } },
470
+ },
471
+ required: ['compositeRequest'],
472
+ },
473
+ note: 'MCP builds Opportunity + OpportunityContactRole requests.',
474
+ },
475
+ batch_get_records: {
476
+ method: 'POST',
477
+ path: '/composite/batch',
478
+ urlKind: 'versioned',
479
+ bodyExplicit: { batchRequests: '{batchRequests}', haltOnError: '{halt_on_error}' },
480
+ inputSchemaOverride: {
481
+ type: 'object',
482
+ properties: {
483
+ batchRequests: {
484
+ type: 'array',
485
+ items: {
486
+ type: 'object',
487
+ properties: {
488
+ method: { type: 'string' },
489
+ url: { type: 'string' },
490
+ },
491
+ required: ['url'],
492
+ },
493
+ },
494
+ haltOnError: { type: 'boolean' },
495
+ },
496
+ required: ['batchRequests'],
497
+ },
498
+ },
499
+ mass_transfer_ownership: {
500
+ method: 'PATCH',
501
+ path: '/composite/sobjects',
502
+ urlKind: 'versioned',
503
+ bodyExplicit: { allOrNone: '{all_or_none}', records: '{records}' },
504
+ inputSchemaOverride: {
505
+ type: 'object',
506
+ properties: {
507
+ all_or_none: { type: 'boolean' },
508
+ records: {
509
+ type: 'array',
510
+ items: { type: 'object', additionalProperties: true },
511
+ description: 'Each { attributes: { type }, id, OwnerId }',
512
+ },
513
+ },
514
+ required: ['records'],
515
+ },
516
+ note: 'MCP builds records from object_type, record_ids, new_owner_id.',
517
+ },
518
+
519
+ get_picklist_values: {
520
+ method: 'GET',
521
+ path: '/sobjects/{object_type}/describe',
522
+ urlKind: 'versioned',
523
+ note: 'Returns full describe; MCP extracts one field’s picklist client-side.',
524
+ },
525
+ get_record_types: {
526
+ method: 'GET',
527
+ path: '/sobjects/{object_type}/describe',
528
+ urlKind: 'versioned',
529
+ note: 'Use describe.recordTypeInfos; MCP summarizes.',
530
+ },
531
+
532
+ metadata_soap_describemetadata: {
533
+ method: 'POST',
534
+ path: '',
535
+ urlKind: 'soap-metadata',
536
+ rawStringBodyArg: 'soap_xml',
537
+ contentTypeOverride: 'text/xml; charset=UTF-8',
538
+ extraHeaders: { accept: 'text/xml', soapaction: '""' },
539
+ inputSchemaOverride: {
540
+ type: 'object',
541
+ properties: {
542
+ soap_xml: {
543
+ type: 'string',
544
+ description: 'Full SOAP XML envelope (SessionHeader with sessionId; describeMetadata body).',
545
+ },
546
+ },
547
+ required: ['soap_xml'],
548
+ },
549
+ note: 'MCP builds XML from as_of_version. Token must be embedded in soap_xml or use bearer per org setup.',
550
+ },
551
+ metadata_soap_describevaluetype: {
552
+ method: 'POST',
553
+ path: '',
554
+ urlKind: 'soap-metadata',
555
+ rawStringBodyArg: 'soap_xml',
556
+ contentTypeOverride: 'text/xml; charset=UTF-8',
557
+ extraHeaders: { accept: 'text/xml', soapaction: '""' },
558
+ inputSchemaOverride: {
559
+ type: 'object',
560
+ properties: { soap_xml: { type: 'string' } },
561
+ required: ['soap_xml'],
562
+ },
563
+ note: 'MCP substitutes metadata_type into template.',
564
+ },
565
+ metadata_soap_list_metadata: {
566
+ method: 'POST',
567
+ path: '',
568
+ urlKind: 'soap-metadata',
569
+ rawStringBodyArg: 'soap_xml',
570
+ contentTypeOverride: 'text/xml; charset=UTF-8',
571
+ extraHeaders: { accept: 'text/xml', soapaction: '""' },
572
+ inputSchemaOverride: {
573
+ type: 'object',
574
+ properties: { soap_xml: { type: 'string' } },
575
+ required: ['soap_xml'],
576
+ },
577
+ note: 'MCP builds listMetadata envelope from metadata_type, folder, as_of_version.',
578
+ },
579
+
580
+ post_chatter_message: {
581
+ method: 'POST',
582
+ path: '/chatter/feed-elements',
583
+ urlKind: 'versioned',
584
+ bodyExplicit: {
585
+ feedElementType: '{feedElementType}',
586
+ subjectId: '{subjectId}',
587
+ body: '{body}',
588
+ },
589
+ inputSchemaOverride: {
590
+ type: 'object',
591
+ properties: {
592
+ feedElementType: { type: 'string', description: 'Usually FeedItem' },
593
+ subjectId: { type: 'string' },
594
+ body: {
595
+ type: 'object',
596
+ additionalProperties: true,
597
+ description: '{ messageSegments: [{ type, text } | { type: Mention, id }] }',
598
+ },
599
+ },
600
+ required: ['subjectId', 'body'],
601
+ },
602
+ note: 'MCP maps message_text + mentions into body.messageSegments.',
603
+ },
604
+ get_record_feed: {
605
+ method: 'GET',
606
+ path: '/chatter/feeds/record/{RECORD_GROUP_ID}/feed-elements',
607
+ urlKind: 'versioned',
608
+ pathPlaceholderArgs: { RECORD_GROUP_ID: 'record_id' },
609
+ queryParamsExplicit: { pageSize: '{page_size}' },
610
+ },
611
+ upload_file_to_record: {
612
+ method: 'POST',
613
+ path: '/sobjects/ContentVersion',
614
+ urlKind: 'versioned',
615
+ bodyExplicit: {
616
+ Title: '{file_name}',
617
+ PathOnClient: '{file_name}',
618
+ VersionData: '{file_content_base64}',
619
+ FirstPublishLocationId: '{record_id}',
620
+ },
621
+ note: 'ContentVersion REST (base64). MCP uses multipart upload + feed-element link.',
622
+ },
623
+ get_user_profile: {
624
+ method: 'GET',
625
+ path: '/chatter/users/{user_id}',
626
+ urlKind: 'versioned',
627
+ note: 'Use user_id me for the connected user.',
628
+ },
629
+ list_groups: {
630
+ method: 'GET',
631
+ path: '/chatter/groups',
632
+ urlKind: 'versioned',
633
+ queryParamsExplicit: { q: '{query}', pageSize: '{limit}' },
634
+ inputSchemaOverride: {
635
+ type: 'object',
636
+ properties: {
637
+ query: { type: 'string' },
638
+ limit: { type: 'number', description: 'Maps to pageSize' },
639
+ },
640
+ required: [],
641
+ },
642
+ },
643
+
644
+ execute_apex: {
645
+ method: 'GET',
646
+ path: '/executeAnonymous',
647
+ urlKind: 'tooling',
648
+ queryParamsExplicit: { anonymousBody: '{apex_body}' },
649
+ },
650
+ get_apex_logs: {
651
+ method: 'GET',
652
+ path: '/query',
653
+ urlKind: 'tooling',
654
+ queryParamsExplicit: { q: '{q}' },
655
+ inputSchemaOverride: soqlQSchema('Tooling SOQL for ApexLog (MCP builds WHERE/LIMIT).'),
656
+ note: 'Pass full Tooling API SOQL as q.',
657
+ },
658
+ run_apex_tests: {
659
+ method: 'POST',
660
+ path: '/runTestsAsynchronous',
661
+ urlKind: 'tooling',
662
+ bodyExplicit: { classNames: '{class_names}' },
663
+ inputSchemaOverride: {
664
+ type: 'object',
665
+ properties: {
666
+ class_names: {
667
+ type: 'string',
668
+ description: 'Comma-separated Apex test class API names (MCP used array).',
669
+ },
670
+ },
671
+ required: ['class_names'],
672
+ },
673
+ },
674
+ query_tooling_api: {
675
+ method: 'GET',
676
+ path: '/query',
677
+ urlKind: 'tooling',
678
+ queryParamsExplicit: { q: '{query}' },
679
+ },
680
+ list_apex_classes: {
681
+ method: 'GET',
682
+ path: '/query',
683
+ urlKind: 'tooling',
684
+ queryParamsExplicit: { q: '{q}' },
685
+ inputSchemaOverride: soqlQSchema('Tooling SOQL for ApexClass (MCP builds name_filter/LIMIT).'),
686
+ note: 'Pass full Tooling SOQL as q.',
687
+ },
688
+
689
+ get_record_ui: {
690
+ method: 'GET',
691
+ path: '/record-ui/{RECORD_IDS}',
692
+ urlKind: 'ui-api',
693
+ pathPlaceholderArgs: { RECORD_IDS: 'record_id' },
694
+ queryParamsExplicit: { layoutTypes: '{layout_types}', modes: '{modes}' },
695
+ note: 'layout_types and modes: comma-separated strings (or JSON string).',
696
+ },
697
+ get_object_info: {
698
+ method: 'GET',
699
+ path: '/object-info/{SOBJECT_API_NAME}',
700
+ urlKind: 'ui-api',
701
+ pathPlaceholderArgs: { SOBJECT_API_NAME: 'object_api_name' },
702
+ },
703
+ get_picklist_values_ui: {
704
+ method: 'GET',
705
+ path: '/object-info/{SOBJECT_API_NAME}/picklist-values/{RECORD_TYPE_ID}',
706
+ urlKind: 'ui-api',
707
+ pathPlaceholderArgs: {
708
+ SOBJECT_API_NAME: 'object_api_name',
709
+ RECORD_TYPE_ID: 'record_type_id',
710
+ },
711
+ note: 'MCP may fetch default record type first; HTTP must pass record_type_id.',
712
+ },
713
+ get_layout: {
714
+ method: 'GET',
715
+ path: '/layout/{SOBJECT_API_NAME}',
716
+ urlKind: 'ui-api',
717
+ pathPlaceholderArgs: { SOBJECT_API_NAME: 'object_api_name' },
718
+ queryParamsExplicit: {
719
+ layoutTypes: '{layout_type}',
720
+ recordTypeId: '{record_type_id}',
721
+ modes: 'View',
722
+ },
723
+ },
724
+
725
+ analyze_sentiment: {
726
+ method: 'POST',
727
+ path: '/language/sentiment',
728
+ urlKind: 'einstein-platform',
729
+ bodyExplicit: { modelId: '{model_id}', document: '{text}' },
730
+ note: 'Einstein Language: real API is often multipart/form-data; JSON may not work—prefer MCP if calls fail.',
731
+ },
732
+ classify_intent: {
733
+ method: 'POST',
734
+ path: '/language/intent',
735
+ urlKind: 'einstein-platform',
736
+ bodyExplicit: { modelId: '{model_id}', document: '{text}' },
737
+ note: 'Often multipart; JSON fallback.',
738
+ },
739
+ predict_image: {
740
+ method: 'POST',
741
+ path: '/vision/predict',
742
+ urlKind: 'einstein-platform',
743
+ bodyExplicit: {
744
+ modelId: '{model_id}',
745
+ sampleLocation: '{image_url}',
746
+ sampleBase64Content: '{image_base64}',
747
+ },
748
+ note: 'Provide image_url XOR image_base64. Often multipart; JSON fallback.',
749
+ },
750
+
751
+ publish_platform_event: {
752
+ method: 'POST',
753
+ path: '/sobjects/{event_api_name}',
754
+ urlKind: 'versioned',
755
+ wholeBodyPlaceholderArg: 'event_data',
756
+ inputSchemaOverride: {
757
+ type: 'object',
758
+ properties: {
759
+ event_api_name: {
760
+ type: 'string',
761
+ description: 'Platform event API name including __e suffix.',
762
+ },
763
+ event_data: { type: 'object', additionalProperties: true },
764
+ },
765
+ required: ['event_api_name'],
766
+ },
767
+ note: 'JSON body is the event fields. MCP wraps event_name → apiName.',
768
+ },
769
+ list_platform_events: {
770
+ method: 'GET',
771
+ path: '/query',
772
+ urlKind: 'tooling',
773
+ queryParamsLiteral: {
774
+ q: "SELECT QualifiedApiName, Label, DeveloperName, DurableId FROM EntityDefinition WHERE QualifiedApiName LIKE '%__e' ORDER BY QualifiedApiName LIMIT 500",
775
+ },
776
+ inputSchemaOverride: { type: 'object', properties: {}, required: [] },
777
+ },
778
+ create_streaming_topic: {
779
+ method: 'POST',
780
+ path: '/sobjects/PushTopic',
781
+ urlKind: 'versioned',
782
+ bodyExplicit: {
783
+ Name: '{name}',
784
+ Query: '{query}',
785
+ NotifyForFields: '{notify_for_fields}',
786
+ ApiVersion: '{api_version}',
787
+ },
788
+ inputSchemaOverride: {
789
+ type: 'object',
790
+ properties: {
791
+ name: { type: 'string' },
792
+ query: { type: 'string' },
793
+ notify_for_fields: { type: 'string' },
794
+ api_version: { type: 'string', description: 'Numeric API version e.g. 59 (MCP defaults from env).' },
795
+ },
796
+ required: ['name', 'query'],
797
+ },
798
+ note: 'MCP defaults notify_for_fields and ApiVersion.',
799
+ },
800
+
801
+ graphql_query: {
802
+ method: 'POST',
803
+ path: '',
804
+ urlKind: 'graphql',
805
+ bodyExplicit: { query: '{query}', variables: '{variables}' },
806
+ },
807
+ graphql_query_accounts_with_contacts: {
808
+ method: 'POST',
809
+ path: '',
810
+ urlKind: 'graphql',
811
+ bodyLiteral: {
812
+ query: `query accountsWithContacts {
813
+ uiapi {
814
+ query {
815
+ Account {
816
+ edges {
817
+ node {
818
+ Id
819
+ Name { value }
820
+ Contacts {
821
+ edges {
822
+ node {
823
+ Id
824
+ Name { value }
825
+ Email { value }
826
+ }
827
+ }
828
+ }
829
+ }
830
+ }
831
+ }
832
+ }
833
+ }
834
+ }`,
835
+ },
836
+ inputSchemaOverride: { type: 'object', properties: {}, required: [] },
837
+ },
838
+
839
+ get_product_catalog: {
840
+ method: 'GET',
841
+ path: '/query/',
842
+ urlKind: 'versioned',
843
+ queryParamsExplicit: { q: '{q}' },
844
+ inputSchemaOverride: soqlQSchema('SOQL for PricebookEntry rows (MCP resolves Standard Price Book).'),
845
+ note: 'MCP resolves pricebook and active filters; via HTTP pass full SOQL as q.',
846
+ },
847
+ create_order_from_opportunity: {
848
+ method: 'POST',
849
+ path: '/sobjects/Order',
850
+ urlKind: 'versioned',
851
+ bodyExplicit: {
852
+ AccountId: '{account_id}',
853
+ OpportunityId: '{opportunity_id}',
854
+ Pricebook2Id: '{pricebook_id}',
855
+ EffectiveDate: '{effective_date}',
856
+ Status: 'Draft',
857
+ },
858
+ inputSchemaOverride: {
859
+ type: 'object',
860
+ properties: {
861
+ account_id: { type: 'string' },
862
+ opportunity_id: { type: 'string' },
863
+ pricebook_id: { type: 'string' },
864
+ effective_date: { type: 'string' },
865
+ },
866
+ required: ['account_id', 'opportunity_id', 'pricebook_id', 'effective_date'],
867
+ },
868
+ note: 'MCP also creates OrderItems from opportunity lines; HTTP is Order header only.',
869
+ },
870
+ get_subscription_status: {
871
+ method: 'GET',
872
+ path: '/query/',
873
+ urlKind: 'versioned',
874
+ queryParamsExplicit: { q: '{q}' },
875
+ inputSchemaOverride: soqlQSchema(
876
+ 'SOQL on Order + OrderItems for an Account (MCP builds AccountId filter).'
877
+ ),
878
+ note: 'Pass full SOQL as q.',
879
+ },
880
+ };
881
+
882
+ function soqlQSchema(desc) {
883
+ return {
884
+ type: 'object',
885
+ properties: {
886
+ q: { type: 'string', description: desc },
887
+ },
888
+ required: ['q'],
889
+ };
890
+ }