@burdenoff/mcp-libs 2026.1007.4 → 2026.1008.2
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.
|
@@ -53,9 +53,9 @@ Hint: ${hint}` : message;
|
|
|
53
53
|
// src/modules/devportal/operations.ts
|
|
54
54
|
var LIST_ORGANIZATIONS = `
|
|
55
55
|
query ListOrganizations($limit: Int, $offset: Int) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
myOrganizations(limit: $limit, offset: $offset) {
|
|
57
|
+
items { id name slug status }
|
|
58
|
+
total
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
`;
|
|
@@ -82,11 +82,11 @@ var UPDATE_ORGANIZATION = `
|
|
|
82
82
|
`;
|
|
83
83
|
var DELETE_ORGANIZATION = `
|
|
84
84
|
mutation DeleteOrganization($id: ID!) {
|
|
85
|
-
deleteOrganization(id: $id)
|
|
85
|
+
deleteOrganization(id: $id)
|
|
86
86
|
}
|
|
87
87
|
`;
|
|
88
88
|
var LIST_APPLICATIONS = `
|
|
89
|
-
query ListApplications($organizationId: ID, $status:
|
|
89
|
+
query ListApplications($organizationId: ID, $status: AppStatus, $limit: Int) {
|
|
90
90
|
applications(organizationId: $organizationId, status: $status, limit: $limit) {
|
|
91
91
|
edges { node { id name status installCount averageRating } }
|
|
92
92
|
totalCount
|
|
@@ -130,14 +130,7 @@ var PUBLISH_APPLICATION = `
|
|
|
130
130
|
`;
|
|
131
131
|
var DELETE_APPLICATION = `
|
|
132
132
|
mutation DeleteApplication($id: ID!) {
|
|
133
|
-
deleteApplication(id: $id)
|
|
134
|
-
}
|
|
135
|
-
`;
|
|
136
|
-
var APPLICATION_VERSIONS = `
|
|
137
|
-
query ApplicationVersions($applicationId: ID!) {
|
|
138
|
-
applicationVersions(applicationId: $applicationId) {
|
|
139
|
-
id version status isLatest isStable releaseNotes
|
|
140
|
-
}
|
|
133
|
+
deleteApplication(id: $id)
|
|
141
134
|
}
|
|
142
135
|
`;
|
|
143
136
|
var CREATE_APPLICATION_VERSION = `
|
|
@@ -155,15 +148,15 @@ var LIST_WEBHOOKS = `
|
|
|
155
148
|
}
|
|
156
149
|
`;
|
|
157
150
|
var CREATE_WEBHOOK = `
|
|
158
|
-
mutation CreateDevportalWebhook($input: CreateWebhookInput!) {
|
|
159
|
-
createWebhook(input: $input) {
|
|
160
|
-
id name url status
|
|
151
|
+
mutation CreateDevportalWebhook($applicationId: ID!, $input: CreateWebhookInput!) {
|
|
152
|
+
createWebhook(applicationId: $applicationId, input: $input) {
|
|
153
|
+
webhook { id name url events isActive status failureCount }
|
|
161
154
|
}
|
|
162
155
|
}
|
|
163
156
|
`;
|
|
164
157
|
var DELETE_WEBHOOK = `
|
|
165
158
|
mutation DeleteDevportalWebhook($id: ID!) {
|
|
166
|
-
deleteWebhook(id: $id)
|
|
159
|
+
deleteWebhook(id: $id)
|
|
167
160
|
}
|
|
168
161
|
`;
|
|
169
162
|
var APPLICATION_ANALYTICS = `
|
|
@@ -173,17 +166,11 @@ var APPLICATION_ANALYTICS = `
|
|
|
173
166
|
}
|
|
174
167
|
}
|
|
175
168
|
`;
|
|
176
|
-
var ORGANIZATION_REVENUE = `
|
|
177
|
-
query OrganizationRevenue($organizationId: ID!, $period: String!) {
|
|
178
|
-
organizationRevenue(organizationId: $organizationId, period: $period) {
|
|
179
|
-
totalEarnings currency netEarnings
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
`;
|
|
183
169
|
var ADMIN_REVIEWS = `
|
|
184
|
-
query AdminReviews($status:
|
|
185
|
-
|
|
186
|
-
edges { node { id applicationId
|
|
170
|
+
query AdminReviews($applicationId: ID!, $status: AppReviewStatus, $limit: Int, $offset: Int) {
|
|
171
|
+
appReviews(applicationId: $applicationId, status: $status, limit: $limit, offset: $offset) {
|
|
172
|
+
edges { cursor node { id applicationId } }
|
|
173
|
+
pageInfo { hasNextPage }
|
|
187
174
|
totalCount
|
|
188
175
|
}
|
|
189
176
|
}
|
|
@@ -203,71 +190,69 @@ var REJECT_APPLICATION = `
|
|
|
203
190
|
}
|
|
204
191
|
`;
|
|
205
192
|
var LIST_API_KEYS = `
|
|
206
|
-
query ApiKeys($
|
|
207
|
-
|
|
208
|
-
id
|
|
193
|
+
query ApiKeys($appId: ID!) {
|
|
194
|
+
appApiKeys(appId: $appId) {
|
|
195
|
+
apiKeys { id appId name prefix scopes expiresAt lastUsedAt createdAt }
|
|
209
196
|
}
|
|
210
197
|
}
|
|
211
198
|
`;
|
|
212
199
|
var CREATE_API_KEY = `
|
|
213
|
-
mutation CreateApiKey($input:
|
|
214
|
-
|
|
215
|
-
|
|
200
|
+
mutation CreateApiKey($input: GenerateAPIKeyInput!) {
|
|
201
|
+
generateAPIKey(input: $input) {
|
|
202
|
+
keyId apiKey apiSecret
|
|
216
203
|
}
|
|
217
204
|
}
|
|
218
205
|
`;
|
|
219
206
|
var REVOKE_API_KEY = `
|
|
220
|
-
mutation RevokeApiKey($
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
`;
|
|
224
|
-
var LIST_OAUTH_CLIENTS = `
|
|
225
|
-
query OAuthClients($applicationId: ID!) {
|
|
226
|
-
oauthClients(applicationId: $applicationId) {
|
|
227
|
-
id applicationId clientId name redirectUris grantTypes isActive createdAt
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
`;
|
|
231
|
-
var CREATE_OAUTH_CLIENT = `
|
|
232
|
-
mutation CreateOAuthClient($input: CreateOAuthClientInput!) {
|
|
233
|
-
createOAuthClient(input: $input) {
|
|
234
|
-
id applicationId clientId clientSecret name redirectUris grantTypes isActive createdAt
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
`;
|
|
238
|
-
var DELETE_OAUTH_CLIENT = `
|
|
239
|
-
mutation DeleteOAuthClient($id: ID!) {
|
|
240
|
-
deleteOAuthClient(id: $id) { success }
|
|
207
|
+
mutation RevokeApiKey($keyId: String!) {
|
|
208
|
+
revokeAPIKey(keyId: $keyId)
|
|
241
209
|
}
|
|
242
210
|
`;
|
|
243
211
|
var LIST_DELEGATIONS = `
|
|
244
|
-
query Delegations($
|
|
245
|
-
|
|
246
|
-
|
|
212
|
+
query Delegations($first: Int) {
|
|
213
|
+
currentUserDelegations(pagination: { limit: $first }) {
|
|
214
|
+
delegations {
|
|
215
|
+
id appId userId grantedBy grantedAt expiresAt scopes status workspaceIds
|
|
216
|
+
app { id name }
|
|
217
|
+
}
|
|
247
218
|
}
|
|
248
219
|
}
|
|
249
220
|
`;
|
|
250
221
|
var CREATE_DELEGATION = `
|
|
251
|
-
mutation CreateDelegation($input:
|
|
252
|
-
|
|
253
|
-
id
|
|
222
|
+
mutation CreateDelegation($input: GrantDelegationInput!) {
|
|
223
|
+
grantDelegation(input: $input) {
|
|
224
|
+
id appId userId grantedBy grantedAt expiresAt scopes workspaceIds status
|
|
254
225
|
}
|
|
255
226
|
}
|
|
256
227
|
`;
|
|
257
228
|
var REVOKE_DELEGATION = `
|
|
258
229
|
mutation RevokeDelegation($id: ID!) {
|
|
259
|
-
revokeDelegation(id: $id)
|
|
230
|
+
revokeDelegation(id: $id)
|
|
260
231
|
}
|
|
261
232
|
`;
|
|
262
233
|
|
|
263
234
|
// src/modules/devportal/tools.ts
|
|
264
|
-
var
|
|
235
|
+
var AppStatusEnum = zod.z.enum(["DRAFT", "REVIEW", "PUBLISHED", "ARCHIVED"]).describe("Application status");
|
|
236
|
+
var AppReviewStatusEnum = zod.z.enum(["PENDING", "APPROVED", "REJECTED"]).describe("Application review status");
|
|
237
|
+
function stubbedTool(server, _productName, toolName, title, description, featureNote, inputSchema, altSuggestions) {
|
|
238
|
+
server.registerTool(
|
|
239
|
+
toolName,
|
|
240
|
+
{
|
|
241
|
+
title,
|
|
242
|
+
description: `${description} [intentionally stubbed: ${featureNote} Use ${altSuggestions.join(", ")} instead.]`,
|
|
243
|
+
inputSchema
|
|
244
|
+
},
|
|
245
|
+
async () => errorResult(
|
|
246
|
+
`[stubbed] ${featureNote} Use ${altSuggestions.join(", ")} instead. The tool remains registered so callers receive a meaningful response instead of a schema-validation error.`
|
|
247
|
+
)
|
|
248
|
+
);
|
|
249
|
+
}
|
|
265
250
|
function registerDevportalTools(server, ctx, track) {
|
|
266
251
|
server.registerTool(
|
|
267
252
|
track(mcpToolName(ctx.productName, "devportal_orgs_list")),
|
|
268
253
|
{
|
|
269
254
|
title: "List Devportal Organizations",
|
|
270
|
-
description: "List publisher organizations.",
|
|
255
|
+
description: "List publisher organizations the caller owns (uses `myOrganizations` on the live supergraph).",
|
|
271
256
|
inputSchema: {
|
|
272
257
|
limit: zod.z.number().optional().describe("Page size (default 50)"),
|
|
273
258
|
offset: zod.z.number().optional().describe("Skip results")
|
|
@@ -277,8 +262,8 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
277
262
|
try {
|
|
278
263
|
const data = await ctx.gql.global.request(LIST_ORGANIZATIONS, { limit: limit ?? 50, offset: offset ?? 0 });
|
|
279
264
|
return jsonResult({
|
|
280
|
-
items: data.
|
|
281
|
-
totalCount: data.
|
|
265
|
+
items: data.myOrganizations.items,
|
|
266
|
+
totalCount: data.myOrganizations.total
|
|
282
267
|
});
|
|
283
268
|
} catch (error) {
|
|
284
269
|
ctx.logger.error("devportal_orgs_list failed", { error: String(error) });
|
|
@@ -315,19 +300,16 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
315
300
|
track(mcpToolName(ctx.productName, "devportal_orgs_create")),
|
|
316
301
|
{
|
|
317
302
|
title: "Create Publisher Organization",
|
|
318
|
-
description: "Create a publisher organization.",
|
|
303
|
+
description: "Create a publisher organization. The live supergraph requires `slug` \u2014 auto-derive from the name (kebab-case) if not supplied.",
|
|
319
304
|
inputSchema: {
|
|
320
305
|
name: zod.z.string().describe("Organization name"),
|
|
321
|
-
|
|
322
|
-
|
|
306
|
+
slug: zod.z.string().optional().describe("URL slug \u2014 auto-derived from `name` (kebab-case) when omitted"),
|
|
307
|
+
description: zod.z.string().optional()
|
|
323
308
|
}
|
|
324
309
|
},
|
|
325
|
-
async ({ name,
|
|
310
|
+
async ({ name, slug, description }) => {
|
|
326
311
|
try {
|
|
327
|
-
const input = {
|
|
328
|
-
name,
|
|
329
|
-
tier: (tier ?? "ORGANIZATION").toUpperCase()
|
|
330
|
-
};
|
|
312
|
+
const input = { name, slug: slug ?? slugify(name) };
|
|
331
313
|
if (description !== void 0) input.description = description;
|
|
332
314
|
const data = await ctx.gql.global.request(
|
|
333
315
|
CREATE_ORGANIZATION,
|
|
@@ -395,10 +377,10 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
395
377
|
track(mcpToolName(ctx.productName, "devportal_apps_list")),
|
|
396
378
|
{
|
|
397
379
|
title: "List Devportal Applications",
|
|
398
|
-
description: "List devportal applications.",
|
|
380
|
+
description: "List devportal applications. `status` is the live `AppStatus` enum (DRAFT|REVIEW|PUBLISHED|ARCHIVED).",
|
|
399
381
|
inputSchema: {
|
|
400
382
|
organizationId: zod.z.string().optional(),
|
|
401
|
-
status:
|
|
383
|
+
status: AppStatusEnum.optional(),
|
|
402
384
|
limit: zod.z.number().optional().describe("Page size (default 50)")
|
|
403
385
|
}
|
|
404
386
|
},
|
|
@@ -406,7 +388,7 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
406
388
|
try {
|
|
407
389
|
const data = await ctx.gql.global.request(LIST_APPLICATIONS, {
|
|
408
390
|
organizationId,
|
|
409
|
-
status
|
|
391
|
+
status,
|
|
410
392
|
limit: limit ?? 50
|
|
411
393
|
});
|
|
412
394
|
return jsonResult({
|
|
@@ -448,19 +430,19 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
448
430
|
track(mcpToolName(ctx.productName, "devportal_apps_create")),
|
|
449
431
|
{
|
|
450
432
|
title: "Create Devportal Application",
|
|
451
|
-
description:
|
|
433
|
+
description: 'Create a devportal application under the caller\'s default organization. The live `CreateApplicationInput` does NOT accept `organizationId` (was previously forwarded; rejected by the schema with "Field organizationId is not defined by type CreateApplicationInput").',
|
|
452
434
|
inputSchema: {
|
|
453
435
|
name: zod.z.string().describe("Application name"),
|
|
454
|
-
|
|
455
|
-
|
|
436
|
+
appType: AppStatusEnum.describe(
|
|
437
|
+
"API_INTEGRATION|WEB_APP|MOBILE_APP (default API_INTEGRATION)"
|
|
438
|
+
).optional(),
|
|
456
439
|
description: zod.z.string().optional()
|
|
457
440
|
}
|
|
458
441
|
},
|
|
459
|
-
async ({ name,
|
|
442
|
+
async ({ name, appType, description }) => {
|
|
460
443
|
try {
|
|
461
444
|
const input = {
|
|
462
445
|
name,
|
|
463
|
-
organizationId,
|
|
464
446
|
appType: (appType ?? "API_INTEGRATION").toUpperCase()
|
|
465
447
|
};
|
|
466
448
|
if (description !== void 0) input.description = description;
|
|
@@ -557,7 +539,7 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
557
539
|
track(mcpToolName(ctx.productName, "devportal_apps_delete")),
|
|
558
540
|
{
|
|
559
541
|
title: "Delete Devportal Application",
|
|
560
|
-
description: "Delete a devportal application.",
|
|
542
|
+
description: "Delete a devportal application. Live mutation returns Boolean! (no selection set).",
|
|
561
543
|
inputSchema: { id: zod.z.string().describe("Application ID") }
|
|
562
544
|
},
|
|
563
545
|
async ({ id }) => {
|
|
@@ -572,27 +554,17 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
572
554
|
}
|
|
573
555
|
}
|
|
574
556
|
);
|
|
575
|
-
|
|
557
|
+
stubbedTool(
|
|
558
|
+
server,
|
|
559
|
+
ctx.productName,
|
|
576
560
|
track(mcpToolName(ctx.productName, "devportal_apps_versions_list")),
|
|
561
|
+
"List Application Versions",
|
|
562
|
+
"List versions for an application.",
|
|
563
|
+
"`Query.applicationVersions(applicationId)` was removed from the alpha devportal supergraph; there is no surviving `versions` field on `app(applicationId)`.",
|
|
577
564
|
{
|
|
578
|
-
|
|
579
|
-
description: "List versions for an application.",
|
|
580
|
-
inputSchema: { applicationId: zod.z.string().describe("Application ID") }
|
|
565
|
+
applicationId: zod.z.string().describe("Application ID")
|
|
581
566
|
},
|
|
582
|
-
|
|
583
|
-
try {
|
|
584
|
-
const data = await ctx.gql.global.request(
|
|
585
|
-
APPLICATION_VERSIONS,
|
|
586
|
-
{ applicationId }
|
|
587
|
-
);
|
|
588
|
-
return jsonResult(data.applicationVersions);
|
|
589
|
-
} catch (error) {
|
|
590
|
-
ctx.logger.error("devportal_apps_versions_list failed", { error: String(error) });
|
|
591
|
-
return errorResult(
|
|
592
|
-
`Failed to list versions: ${error instanceof Error ? error.message : String(error)}`
|
|
593
|
-
);
|
|
594
|
-
}
|
|
595
|
-
}
|
|
567
|
+
[`\`_devportal_apps_versions_create\``, `\`_devportal_apps_analytics\``]
|
|
596
568
|
);
|
|
597
569
|
server.registerTool(
|
|
598
570
|
track(mcpToolName(ctx.productName, "devportal_apps_versions_create")),
|
|
@@ -628,7 +600,7 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
628
600
|
track(mcpToolName(ctx.productName, "devportal_apps_webhooks_list")),
|
|
629
601
|
{
|
|
630
602
|
title: "List Application Webhooks",
|
|
631
|
-
description: "List webhooks attached to an application.",
|
|
603
|
+
description: "List webhooks attached to an application (live global `Query.webhooks(applicationId)`).",
|
|
632
604
|
inputSchema: { applicationId: zod.z.string().describe("Application ID") }
|
|
633
605
|
},
|
|
634
606
|
async ({ applicationId }) => {
|
|
@@ -649,7 +621,7 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
649
621
|
track(mcpToolName(ctx.productName, "devportal_apps_webhooks_add")),
|
|
650
622
|
{
|
|
651
623
|
title: "Add Application Webhook",
|
|
652
|
-
description: "Add a webhook to an application.",
|
|
624
|
+
description: "Add a webhook to an application. The live mutation takes `applicationId` as a top-level argument plus `input: CreateWebhookInput!`. The result is `WebhookCreated { webhook { ... } }` (the type itself has no `id`).",
|
|
653
625
|
inputSchema: {
|
|
654
626
|
applicationId: zod.z.string().describe("Application ID"),
|
|
655
627
|
name: zod.z.string().describe("Webhook name"),
|
|
@@ -661,18 +633,14 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
661
633
|
async ({ applicationId, name, url, events, maxRetries }) => {
|
|
662
634
|
try {
|
|
663
635
|
const input = {
|
|
664
|
-
applicationId,
|
|
665
636
|
name,
|
|
666
637
|
url,
|
|
667
638
|
events,
|
|
668
639
|
retryEnabled: true,
|
|
669
640
|
maxRetries: maxRetries ?? 5
|
|
670
641
|
};
|
|
671
|
-
const data = await ctx.gql.global.request(
|
|
672
|
-
|
|
673
|
-
{ input }
|
|
674
|
-
);
|
|
675
|
-
return jsonResult(data.createWebhook);
|
|
642
|
+
const data = await ctx.gql.global.request(CREATE_WEBHOOK, { applicationId, input });
|
|
643
|
+
return jsonResult(data.createWebhook.webhook);
|
|
676
644
|
} catch (error) {
|
|
677
645
|
ctx.logger.error("devportal_apps_webhooks_add failed", { error: String(error) });
|
|
678
646
|
return errorResult(
|
|
@@ -685,7 +653,7 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
685
653
|
track(mcpToolName(ctx.productName, "devportal_apps_webhooks_remove")),
|
|
686
654
|
{
|
|
687
655
|
title: "Remove Application Webhook",
|
|
688
|
-
description: "Remove a webhook by ID.",
|
|
656
|
+
description: "Remove a webhook by ID. Live mutation returns Boolean! (no selection set).",
|
|
689
657
|
inputSchema: { id: zod.z.string().describe("Webhook ID") }
|
|
690
658
|
},
|
|
691
659
|
async ({ id }) => {
|
|
@@ -729,46 +697,43 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
729
697
|
}
|
|
730
698
|
}
|
|
731
699
|
);
|
|
732
|
-
|
|
700
|
+
stubbedTool(
|
|
701
|
+
server,
|
|
702
|
+
ctx.productName,
|
|
733
703
|
track(mcpToolName(ctx.productName, "devportal_revenue")),
|
|
704
|
+
"Organization Revenue",
|
|
705
|
+
"Get revenue summary for an organization.",
|
|
706
|
+
"`Query.organizationRevenue` (and any `revenue` field on `organization` / `app`) was removed from the alpha supergraph.",
|
|
734
707
|
{
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
inputSchema: {
|
|
738
|
-
organizationId: zod.z.string().describe("Organization ID"),
|
|
739
|
-
period: zod.z.string().optional().describe("LAST_7_DAYS|LAST_30_DAYS|YTD (default LAST_30_DAYS)")
|
|
740
|
-
}
|
|
708
|
+
organizationId: zod.z.string().describe("Organization ID"),
|
|
709
|
+
period: zod.z.string().optional().describe("LAST_7_DAYS|LAST_30_DAYS|YTD (default LAST_30_DAYS)")
|
|
741
710
|
},
|
|
742
|
-
|
|
743
|
-
try {
|
|
744
|
-
const data = await ctx.gql.global.request(ORGANIZATION_REVENUE, {
|
|
745
|
-
organizationId,
|
|
746
|
-
period: (period ?? "LAST_30_DAYS").toUpperCase()
|
|
747
|
-
});
|
|
748
|
-
return jsonResult(data.organizationRevenue);
|
|
749
|
-
} catch (error) {
|
|
750
|
-
ctx.logger.error("devportal_revenue failed", { error: String(error) });
|
|
751
|
-
return errorResult(
|
|
752
|
-
`Failed to fetch revenue: ${error instanceof Error ? error.message : String(error)}`
|
|
753
|
-
);
|
|
754
|
-
}
|
|
755
|
-
}
|
|
711
|
+
[`\`_billing_invoices_list\``, `\`_billing_subscriptions_list\``]
|
|
756
712
|
);
|
|
757
713
|
server.registerTool(
|
|
758
714
|
track(mcpToolName(ctx.productName, "devportal_admin_reviews_list")),
|
|
759
715
|
{
|
|
760
716
|
title: "List Admin Application Reviews",
|
|
761
|
-
description: "List applications in the admin review queue.",
|
|
717
|
+
description: "List applications in the admin review queue. Live query is `appReviews(applicationId, status, limit, offset)` (the unscoped `adminReviews` field was removed). `applicationId` is required, `status` filters the connection server-side, and pagination uses `limit` + `offset` (NOT `first`/`after`).",
|
|
762
718
|
inputSchema: {
|
|
763
|
-
|
|
719
|
+
applicationId: zod.z.string().describe("Application ID to scope the review queue to"),
|
|
720
|
+
status: AppReviewStatusEnum.optional(),
|
|
721
|
+
limit: zod.z.number().optional().describe("Page size (default 20)"),
|
|
722
|
+
offset: zod.z.number().optional().describe("Skip results")
|
|
764
723
|
}
|
|
765
724
|
},
|
|
766
|
-
async ({ status }) => {
|
|
725
|
+
async ({ applicationId, status, limit, offset }) => {
|
|
767
726
|
try {
|
|
768
|
-
const data = await ctx.gql.global.request(ADMIN_REVIEWS, {
|
|
727
|
+
const data = await ctx.gql.global.request(ADMIN_REVIEWS, {
|
|
728
|
+
applicationId,
|
|
729
|
+
status,
|
|
730
|
+
limit: limit ?? 20,
|
|
731
|
+
offset: offset ?? 0
|
|
732
|
+
});
|
|
769
733
|
return jsonResult({
|
|
770
|
-
items: data.
|
|
771
|
-
totalCount: data.
|
|
734
|
+
items: data.appReviews.edges.map((e) => e.node),
|
|
735
|
+
totalCount: data.appReviews.totalCount,
|
|
736
|
+
pageInfo: data.appReviews.pageInfo
|
|
772
737
|
});
|
|
773
738
|
} catch (error) {
|
|
774
739
|
ctx.logger.error("devportal_admin_reviews_list failed", { error: String(error) });
|
|
@@ -832,17 +797,15 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
832
797
|
track(mcpToolName(ctx.productName, "devportal_api_keys_list")),
|
|
833
798
|
{
|
|
834
799
|
title: "List API Keys",
|
|
835
|
-
description: "List API keys
|
|
800
|
+
description: "List API keys for an application. Live query is `appApiKeys(appId: ID!)`.",
|
|
836
801
|
inputSchema: {
|
|
837
|
-
applicationId: zod.z.string().describe("Application ID
|
|
802
|
+
applicationId: zod.z.string().describe("Application ID (forwarded as `appId`)")
|
|
838
803
|
}
|
|
839
804
|
},
|
|
840
805
|
async ({ applicationId }) => {
|
|
841
806
|
try {
|
|
842
|
-
const data = await ctx.gql.global.request(LIST_API_KEYS, {
|
|
843
|
-
|
|
844
|
-
});
|
|
845
|
-
return jsonResult(data.apiKeys);
|
|
807
|
+
const data = await ctx.gql.global.request(LIST_API_KEYS, { appId: applicationId });
|
|
808
|
+
return jsonResult(data.appApiKeys.apiKeys);
|
|
846
809
|
} catch (error) {
|
|
847
810
|
ctx.logger.error("devportal_api_keys_list failed", { error: String(error) });
|
|
848
811
|
return errorResult(
|
|
@@ -855,24 +818,26 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
855
818
|
track(mcpToolName(ctx.productName, "devportal_api_keys_create")),
|
|
856
819
|
{
|
|
857
820
|
title: "Create API Key",
|
|
858
|
-
description: "Mint a new API key
|
|
821
|
+
description: "Mint a new API key via `generateAPIKey(input: GenerateAPIKeyInput!)` (live auth mutation). Returns the full key including the one-time-visible `apiKey`/`apiSecret`.",
|
|
859
822
|
inputSchema: {
|
|
860
|
-
applicationId: zod.z.string().describe("Application ID
|
|
861
|
-
name: zod.z.string().min(1).describe("Human-readable name for the key
|
|
862
|
-
scopes: zod.z.array(zod.z.string()).
|
|
863
|
-
|
|
823
|
+
applicationId: zod.z.string().describe("Application ID (forwarded as `appId`)"),
|
|
824
|
+
name: zod.z.string().min(1).describe("Human-readable name for the key"),
|
|
825
|
+
scopes: zod.z.array(zod.z.string()).min(1).describe(
|
|
826
|
+
"Scope identifiers granted to the key \u2014 REQUIRED on the live `GenerateAPIKeyInput.scope`"
|
|
827
|
+
),
|
|
828
|
+
expiresAt: zod.z.string().optional().describe("ISO 8601 expiry timestamp")
|
|
864
829
|
}
|
|
865
830
|
},
|
|
866
831
|
async ({ applicationId, name, scopes, expiresAt }) => {
|
|
867
832
|
try {
|
|
868
|
-
const input = {
|
|
869
|
-
|
|
833
|
+
const input = {
|
|
834
|
+
appId: applicationId,
|
|
835
|
+
name,
|
|
836
|
+
scope: scopes
|
|
837
|
+
};
|
|
870
838
|
if (expiresAt !== void 0) input.expiresAt = expiresAt;
|
|
871
|
-
const data = await ctx.gql.global.request(
|
|
872
|
-
|
|
873
|
-
{ input }
|
|
874
|
-
);
|
|
875
|
-
return jsonResult(data.createApiKey);
|
|
839
|
+
const data = await ctx.gql.global.request(CREATE_API_KEY, { input });
|
|
840
|
+
return jsonResult({ ...data.generateAPIKey, name, scopes, applicationId });
|
|
876
841
|
} catch (error) {
|
|
877
842
|
ctx.logger.error("devportal_api_keys_create failed", { error: String(error) });
|
|
878
843
|
return errorResult(
|
|
@@ -885,12 +850,12 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
885
850
|
track(mcpToolName(ctx.productName, "devportal_api_keys_revoke")),
|
|
886
851
|
{
|
|
887
852
|
title: "Revoke API Key",
|
|
888
|
-
description: "Revoke an API key
|
|
889
|
-
inputSchema: { id: zod.z.string().describe("API key ID
|
|
853
|
+
description: "Revoke an API key via `revokeAPIKey(keyId: String!)` (live global mutation, returns Boolean!).",
|
|
854
|
+
inputSchema: { id: zod.z.string().describe("API key ID (forwarded as `keyId`)") }
|
|
890
855
|
},
|
|
891
856
|
async ({ id }) => {
|
|
892
857
|
try {
|
|
893
|
-
await ctx.gql.global.request(REVOKE_API_KEY, { id });
|
|
858
|
+
await ctx.gql.global.request(REVOKE_API_KEY, { keyId: id });
|
|
894
859
|
return jsonResult({ status: "success", message: "API key revoked", apiKeyId: id });
|
|
895
860
|
} catch (error) {
|
|
896
861
|
ctx.logger.error("devportal_api_keys_revoke failed", { error: String(error) });
|
|
@@ -900,100 +865,60 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
900
865
|
}
|
|
901
866
|
}
|
|
902
867
|
);
|
|
903
|
-
|
|
868
|
+
stubbedTool(
|
|
869
|
+
server,
|
|
870
|
+
ctx.productName,
|
|
904
871
|
track(mcpToolName(ctx.productName, "devportal_oauth_list")),
|
|
872
|
+
"List OAuth Clients",
|
|
873
|
+
"List OAuth 2.0 clients registered for a devportal application.",
|
|
874
|
+
"`Query.oauthClients(applicationId)` no longer exists on the alpha supergraph, and `app(id)` does not expose a nested `oauthClients` field either.",
|
|
905
875
|
{
|
|
906
|
-
|
|
907
|
-
description: "List OAuth 2.0 clients registered for a devportal application.",
|
|
908
|
-
inputSchema: {
|
|
909
|
-
applicationId: zod.z.string().describe("Application ID that owns the OAuth clients")
|
|
910
|
-
}
|
|
876
|
+
applicationId: zod.z.string().describe("Application ID")
|
|
911
877
|
},
|
|
912
|
-
|
|
913
|
-
try {
|
|
914
|
-
const data = await ctx.gql.global.request(
|
|
915
|
-
LIST_OAUTH_CLIENTS,
|
|
916
|
-
{ applicationId }
|
|
917
|
-
);
|
|
918
|
-
return jsonResult(data.oauthClients);
|
|
919
|
-
} catch (error) {
|
|
920
|
-
ctx.logger.error("devportal_oauth_list failed", { error: String(error) });
|
|
921
|
-
return errorResult(
|
|
922
|
-
`Failed to list OAuth clients: ${error instanceof Error ? error.message : String(error)}`
|
|
923
|
-
);
|
|
924
|
-
}
|
|
925
|
-
}
|
|
878
|
+
[`\`_auth_current_user_apps\``]
|
|
926
879
|
);
|
|
927
|
-
|
|
880
|
+
stubbedTool(
|
|
881
|
+
server,
|
|
882
|
+
ctx.productName,
|
|
928
883
|
track(mcpToolName(ctx.productName, "devportal_oauth_create")),
|
|
884
|
+
"Create OAuth Client",
|
|
885
|
+
"Register a new OAuth 2.0 client for an application.",
|
|
886
|
+
"`Mutation.createOAuthClient` (and `CreateOAuthClientInput`) have been removed from the alpha supergraph.",
|
|
929
887
|
{
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
name: zod.z.string().min(1).describe("Human-readable client name"),
|
|
935
|
-
redirectUris: zod.z.array(zod.z.string()).optional().describe("Allowed redirect URIs for authorization-code flows"),
|
|
936
|
-
grantTypes: zod.z.array(OAuthGrantTypeEnum).optional().describe("OAuth grant types the client is allowed to use")
|
|
937
|
-
}
|
|
888
|
+
applicationId: zod.z.string().describe("Application ID"),
|
|
889
|
+
name: zod.z.string().describe("Client name"),
|
|
890
|
+
redirectUris: zod.z.array(zod.z.string()).optional(),
|
|
891
|
+
grantTypes: zod.z.array(zod.z.string()).optional()
|
|
938
892
|
},
|
|
939
|
-
|
|
940
|
-
try {
|
|
941
|
-
const input = { applicationId, name };
|
|
942
|
-
if (redirectUris !== void 0) input.redirectUris = redirectUris;
|
|
943
|
-
if (grantTypes !== void 0) input.grantTypes = grantTypes;
|
|
944
|
-
const data = await ctx.gql.global.request(
|
|
945
|
-
CREATE_OAUTH_CLIENT,
|
|
946
|
-
{ input }
|
|
947
|
-
);
|
|
948
|
-
return jsonResult(data.createOAuthClient);
|
|
949
|
-
} catch (error) {
|
|
950
|
-
ctx.logger.error("devportal_oauth_create failed", { error: String(error) });
|
|
951
|
-
return errorResult(
|
|
952
|
-
`Failed to create OAuth client: ${error instanceof Error ? error.message : String(error)}`
|
|
953
|
-
);
|
|
954
|
-
}
|
|
955
|
-
}
|
|
893
|
+
[`\`_auth_current_user_apps\` (read-only on alpha)`]
|
|
956
894
|
);
|
|
957
|
-
|
|
895
|
+
stubbedTool(
|
|
896
|
+
server,
|
|
897
|
+
ctx.productName,
|
|
958
898
|
track(mcpToolName(ctx.productName, "devportal_oauth_delete")),
|
|
899
|
+
"Delete OAuth Client",
|
|
900
|
+
"Delete an OAuth 2.0 client by ID.",
|
|
901
|
+
"`Mutation.deleteOAuthClient` has been removed from the alpha supergraph (no successor field).",
|
|
959
902
|
{
|
|
960
|
-
|
|
961
|
-
description: "Delete an OAuth 2.0 client by ID. Returns `{ status, message, oauthClientId }`.",
|
|
962
|
-
inputSchema: { id: zod.z.string().describe("OAuth client ID") }
|
|
903
|
+
id: zod.z.string().describe("OAuth client ID")
|
|
963
904
|
},
|
|
964
|
-
|
|
965
|
-
try {
|
|
966
|
-
await ctx.gql.global.request(DELETE_OAUTH_CLIENT, { id });
|
|
967
|
-
return jsonResult({
|
|
968
|
-
status: "success",
|
|
969
|
-
message: "OAuth client deleted",
|
|
970
|
-
oauthClientId: id
|
|
971
|
-
});
|
|
972
|
-
} catch (error) {
|
|
973
|
-
ctx.logger.error("devportal_oauth_delete failed", { error: String(error) });
|
|
974
|
-
return errorResult(
|
|
975
|
-
`Failed to delete OAuth client: ${error instanceof Error ? error.message : String(error)}`
|
|
976
|
-
);
|
|
977
|
-
}
|
|
978
|
-
}
|
|
905
|
+
[`\`_auth_*\` surface for current OAuth flows`]
|
|
979
906
|
);
|
|
980
907
|
server.registerTool(
|
|
981
908
|
track(mcpToolName(ctx.productName, "devportal_delegations_list")),
|
|
982
909
|
{
|
|
983
910
|
title: "List Delegations",
|
|
984
|
-
description: "List workspace delegations issued to applications.
|
|
911
|
+
description: "List workspace delegations issued to applications. Live impl proxies through the global `Query.currentUserDelegations` (calls scoped to the caller). Note: in-scope filtering by application/workspace is not supported on the live schema \u2014 pass `first` to paginate.",
|
|
985
912
|
inputSchema: {
|
|
986
|
-
|
|
987
|
-
|
|
913
|
+
first: zod.z.number().optional().describe(
|
|
914
|
+
"Page size (default 50). Filter args from the old `delegations(...)` were dropped."
|
|
915
|
+
)
|
|
988
916
|
}
|
|
989
917
|
},
|
|
990
|
-
async ({
|
|
918
|
+
async ({ first }) => {
|
|
991
919
|
try {
|
|
992
|
-
const data = await ctx.gql.global.request(
|
|
993
|
-
|
|
994
|
-
{ applicationId, workspaceId }
|
|
995
|
-
);
|
|
996
|
-
return jsonResult(data.delegations);
|
|
920
|
+
const data = await ctx.gql.global.request(LIST_DELEGATIONS, { first: first ?? 50 });
|
|
921
|
+
return jsonResult(data.currentUserDelegations.delegations);
|
|
997
922
|
} catch (error) {
|
|
998
923
|
ctx.logger.error("devportal_delegations_list failed", { error: String(error) });
|
|
999
924
|
return errorResult(
|
|
@@ -1006,24 +931,27 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
1006
931
|
track(mcpToolName(ctx.productName, "devportal_delegations_create")),
|
|
1007
932
|
{
|
|
1008
933
|
title: "Create Delegation",
|
|
1009
|
-
description: "Grant a workspace delegation to an application
|
|
934
|
+
description: "Grant a workspace delegation to an application. Live impl is `grantDelegation(input: GrantDelegationInput!)` (renamed from `CreateDelegationInput`); `appId` replaces `applicationId`. The grant is implicitly to the calling actor \u2014 `GrantDelegationInput` does NOT take a `userId`.",
|
|
1010
935
|
inputSchema: {
|
|
1011
|
-
applicationId: zod.z.string().describe("Application ID receiving the delegation"),
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
936
|
+
applicationId: zod.z.string().describe("Application ID receiving the delegation (forwarded as `appId`)"),
|
|
937
|
+
scopes: zod.z.array(zod.z.string()).min(1).describe(
|
|
938
|
+
"Scope identifiers granted to the application \u2014 REQUIRED on the live GrantDelegationInput"
|
|
939
|
+
),
|
|
940
|
+
workspaceIds: zod.z.array(zod.z.string()).optional().describe(
|
|
941
|
+
"Optional list of workspace IDs scoping the delegation (forwarded as `workspaceIds`)"
|
|
942
|
+
),
|
|
943
|
+
expiresAt: zod.z.string().optional().describe(
|
|
944
|
+
"ISO 8601 expiry timestamp (DateTime scalar \u2014 must be a full ISO 8601 instant, not a date)"
|
|
945
|
+
)
|
|
1015
946
|
}
|
|
1016
947
|
},
|
|
1017
|
-
async ({ applicationId,
|
|
948
|
+
async ({ applicationId, scopes, workspaceIds, expiresAt }) => {
|
|
1018
949
|
try {
|
|
1019
|
-
const input = { applicationId,
|
|
1020
|
-
if (
|
|
950
|
+
const input = { appId: applicationId, scopes };
|
|
951
|
+
if (workspaceIds !== void 0) input.workspaceIds = workspaceIds;
|
|
1021
952
|
if (expiresAt !== void 0) input.expiresAt = expiresAt;
|
|
1022
|
-
const data = await ctx.gql.global.request(
|
|
1023
|
-
|
|
1024
|
-
{ input }
|
|
1025
|
-
);
|
|
1026
|
-
return jsonResult(data.createDelegation);
|
|
953
|
+
const data = await ctx.gql.global.request(CREATE_DELEGATION, { input });
|
|
954
|
+
return jsonResult(data.grantDelegation);
|
|
1027
955
|
} catch (error) {
|
|
1028
956
|
ctx.logger.error("devportal_delegations_create failed", { error: String(error) });
|
|
1029
957
|
return errorResult(
|
|
@@ -1036,8 +964,8 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
1036
964
|
track(mcpToolName(ctx.productName, "devportal_delegations_revoke")),
|
|
1037
965
|
{
|
|
1038
966
|
title: "Revoke Delegation",
|
|
1039
|
-
description: "Revoke a workspace delegation
|
|
1040
|
-
inputSchema: { id: zod.z.string().describe("Delegation ID
|
|
967
|
+
description: "Revoke a workspace delegation via `revokeDelegation(id: ID!)` (live schema, returns Boolean!; no selection set).",
|
|
968
|
+
inputSchema: { id: zod.z.string().describe("Delegation ID") }
|
|
1041
969
|
},
|
|
1042
970
|
async ({ id }) => {
|
|
1043
971
|
try {
|
|
@@ -1052,6 +980,9 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
1052
980
|
}
|
|
1053
981
|
);
|
|
1054
982
|
}
|
|
983
|
+
function slugify(s) {
|
|
984
|
+
return s.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "org";
|
|
985
|
+
}
|
|
1055
986
|
|
|
1056
987
|
// src/modules/devportal/index.ts
|
|
1057
988
|
var devportalModule = {
|