@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.
|
@@ -4,9 +4,9 @@ import { z } from 'zod';
|
|
|
4
4
|
// src/modules/devportal/operations.ts
|
|
5
5
|
var LIST_ORGANIZATIONS = `
|
|
6
6
|
query ListOrganizations($limit: Int, $offset: Int) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
myOrganizations(limit: $limit, offset: $offset) {
|
|
8
|
+
items { id name slug status }
|
|
9
|
+
total
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
`;
|
|
@@ -33,11 +33,11 @@ var UPDATE_ORGANIZATION = `
|
|
|
33
33
|
`;
|
|
34
34
|
var DELETE_ORGANIZATION = `
|
|
35
35
|
mutation DeleteOrganization($id: ID!) {
|
|
36
|
-
deleteOrganization(id: $id)
|
|
36
|
+
deleteOrganization(id: $id)
|
|
37
37
|
}
|
|
38
38
|
`;
|
|
39
39
|
var LIST_APPLICATIONS = `
|
|
40
|
-
query ListApplications($organizationId: ID, $status:
|
|
40
|
+
query ListApplications($organizationId: ID, $status: AppStatus, $limit: Int) {
|
|
41
41
|
applications(organizationId: $organizationId, status: $status, limit: $limit) {
|
|
42
42
|
edges { node { id name status installCount averageRating } }
|
|
43
43
|
totalCount
|
|
@@ -81,14 +81,7 @@ var PUBLISH_APPLICATION = `
|
|
|
81
81
|
`;
|
|
82
82
|
var DELETE_APPLICATION = `
|
|
83
83
|
mutation DeleteApplication($id: ID!) {
|
|
84
|
-
deleteApplication(id: $id)
|
|
85
|
-
}
|
|
86
|
-
`;
|
|
87
|
-
var APPLICATION_VERSIONS = `
|
|
88
|
-
query ApplicationVersions($applicationId: ID!) {
|
|
89
|
-
applicationVersions(applicationId: $applicationId) {
|
|
90
|
-
id version status isLatest isStable releaseNotes
|
|
91
|
-
}
|
|
84
|
+
deleteApplication(id: $id)
|
|
92
85
|
}
|
|
93
86
|
`;
|
|
94
87
|
var CREATE_APPLICATION_VERSION = `
|
|
@@ -106,15 +99,15 @@ var LIST_WEBHOOKS = `
|
|
|
106
99
|
}
|
|
107
100
|
`;
|
|
108
101
|
var CREATE_WEBHOOK = `
|
|
109
|
-
mutation CreateDevportalWebhook($input: CreateWebhookInput!) {
|
|
110
|
-
createWebhook(input: $input) {
|
|
111
|
-
id name url status
|
|
102
|
+
mutation CreateDevportalWebhook($applicationId: ID!, $input: CreateWebhookInput!) {
|
|
103
|
+
createWebhook(applicationId: $applicationId, input: $input) {
|
|
104
|
+
webhook { id name url events isActive status failureCount }
|
|
112
105
|
}
|
|
113
106
|
}
|
|
114
107
|
`;
|
|
115
108
|
var DELETE_WEBHOOK = `
|
|
116
109
|
mutation DeleteDevportalWebhook($id: ID!) {
|
|
117
|
-
deleteWebhook(id: $id)
|
|
110
|
+
deleteWebhook(id: $id)
|
|
118
111
|
}
|
|
119
112
|
`;
|
|
120
113
|
var APPLICATION_ANALYTICS = `
|
|
@@ -124,17 +117,11 @@ var APPLICATION_ANALYTICS = `
|
|
|
124
117
|
}
|
|
125
118
|
}
|
|
126
119
|
`;
|
|
127
|
-
var ORGANIZATION_REVENUE = `
|
|
128
|
-
query OrganizationRevenue($organizationId: ID!, $period: String!) {
|
|
129
|
-
organizationRevenue(organizationId: $organizationId, period: $period) {
|
|
130
|
-
totalEarnings currency netEarnings
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
`;
|
|
134
120
|
var ADMIN_REVIEWS = `
|
|
135
|
-
query AdminReviews($status:
|
|
136
|
-
|
|
137
|
-
edges { node { id applicationId
|
|
121
|
+
query AdminReviews($applicationId: ID!, $status: AppReviewStatus, $limit: Int, $offset: Int) {
|
|
122
|
+
appReviews(applicationId: $applicationId, status: $status, limit: $limit, offset: $offset) {
|
|
123
|
+
edges { cursor node { id applicationId } }
|
|
124
|
+
pageInfo { hasNextPage }
|
|
138
125
|
totalCount
|
|
139
126
|
}
|
|
140
127
|
}
|
|
@@ -154,71 +141,69 @@ var REJECT_APPLICATION = `
|
|
|
154
141
|
}
|
|
155
142
|
`;
|
|
156
143
|
var LIST_API_KEYS = `
|
|
157
|
-
query ApiKeys($
|
|
158
|
-
|
|
159
|
-
id
|
|
144
|
+
query ApiKeys($appId: ID!) {
|
|
145
|
+
appApiKeys(appId: $appId) {
|
|
146
|
+
apiKeys { id appId name prefix scopes expiresAt lastUsedAt createdAt }
|
|
160
147
|
}
|
|
161
148
|
}
|
|
162
149
|
`;
|
|
163
150
|
var CREATE_API_KEY = `
|
|
164
|
-
mutation CreateApiKey($input:
|
|
165
|
-
|
|
166
|
-
|
|
151
|
+
mutation CreateApiKey($input: GenerateAPIKeyInput!) {
|
|
152
|
+
generateAPIKey(input: $input) {
|
|
153
|
+
keyId apiKey apiSecret
|
|
167
154
|
}
|
|
168
155
|
}
|
|
169
156
|
`;
|
|
170
157
|
var REVOKE_API_KEY = `
|
|
171
|
-
mutation RevokeApiKey($
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
`;
|
|
175
|
-
var LIST_OAUTH_CLIENTS = `
|
|
176
|
-
query OAuthClients($applicationId: ID!) {
|
|
177
|
-
oauthClients(applicationId: $applicationId) {
|
|
178
|
-
id applicationId clientId name redirectUris grantTypes isActive createdAt
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
`;
|
|
182
|
-
var CREATE_OAUTH_CLIENT = `
|
|
183
|
-
mutation CreateOAuthClient($input: CreateOAuthClientInput!) {
|
|
184
|
-
createOAuthClient(input: $input) {
|
|
185
|
-
id applicationId clientId clientSecret name redirectUris grantTypes isActive createdAt
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
`;
|
|
189
|
-
var DELETE_OAUTH_CLIENT = `
|
|
190
|
-
mutation DeleteOAuthClient($id: ID!) {
|
|
191
|
-
deleteOAuthClient(id: $id) { success }
|
|
158
|
+
mutation RevokeApiKey($keyId: String!) {
|
|
159
|
+
revokeAPIKey(keyId: $keyId)
|
|
192
160
|
}
|
|
193
161
|
`;
|
|
194
162
|
var LIST_DELEGATIONS = `
|
|
195
|
-
query Delegations($
|
|
196
|
-
|
|
197
|
-
|
|
163
|
+
query Delegations($first: Int) {
|
|
164
|
+
currentUserDelegations(pagination: { limit: $first }) {
|
|
165
|
+
delegations {
|
|
166
|
+
id appId userId grantedBy grantedAt expiresAt scopes status workspaceIds
|
|
167
|
+
app { id name }
|
|
168
|
+
}
|
|
198
169
|
}
|
|
199
170
|
}
|
|
200
171
|
`;
|
|
201
172
|
var CREATE_DELEGATION = `
|
|
202
|
-
mutation CreateDelegation($input:
|
|
203
|
-
|
|
204
|
-
id
|
|
173
|
+
mutation CreateDelegation($input: GrantDelegationInput!) {
|
|
174
|
+
grantDelegation(input: $input) {
|
|
175
|
+
id appId userId grantedBy grantedAt expiresAt scopes workspaceIds status
|
|
205
176
|
}
|
|
206
177
|
}
|
|
207
178
|
`;
|
|
208
179
|
var REVOKE_DELEGATION = `
|
|
209
180
|
mutation RevokeDelegation($id: ID!) {
|
|
210
|
-
revokeDelegation(id: $id)
|
|
181
|
+
revokeDelegation(id: $id)
|
|
211
182
|
}
|
|
212
183
|
`;
|
|
213
184
|
|
|
214
185
|
// src/modules/devportal/tools.ts
|
|
215
|
-
var
|
|
186
|
+
var AppStatusEnum = z.enum(["DRAFT", "REVIEW", "PUBLISHED", "ARCHIVED"]).describe("Application status");
|
|
187
|
+
var AppReviewStatusEnum = z.enum(["PENDING", "APPROVED", "REJECTED"]).describe("Application review status");
|
|
188
|
+
function stubbedTool(server, _productName, toolName, title, description, featureNote, inputSchema, altSuggestions) {
|
|
189
|
+
server.registerTool(
|
|
190
|
+
toolName,
|
|
191
|
+
{
|
|
192
|
+
title,
|
|
193
|
+
description: `${description} [intentionally stubbed: ${featureNote} Use ${altSuggestions.join(", ")} instead.]`,
|
|
194
|
+
inputSchema
|
|
195
|
+
},
|
|
196
|
+
async () => errorResult(
|
|
197
|
+
`[stubbed] ${featureNote} Use ${altSuggestions.join(", ")} instead. The tool remains registered so callers receive a meaningful response instead of a schema-validation error.`
|
|
198
|
+
)
|
|
199
|
+
);
|
|
200
|
+
}
|
|
216
201
|
function registerDevportalTools(server, ctx, track) {
|
|
217
202
|
server.registerTool(
|
|
218
203
|
track(mcpToolName(ctx.productName, "devportal_orgs_list")),
|
|
219
204
|
{
|
|
220
205
|
title: "List Devportal Organizations",
|
|
221
|
-
description: "List publisher organizations.",
|
|
206
|
+
description: "List publisher organizations the caller owns (uses `myOrganizations` on the live supergraph).",
|
|
222
207
|
inputSchema: {
|
|
223
208
|
limit: z.number().optional().describe("Page size (default 50)"),
|
|
224
209
|
offset: z.number().optional().describe("Skip results")
|
|
@@ -228,8 +213,8 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
228
213
|
try {
|
|
229
214
|
const data = await ctx.gql.global.request(LIST_ORGANIZATIONS, { limit: limit ?? 50, offset: offset ?? 0 });
|
|
230
215
|
return jsonResult({
|
|
231
|
-
items: data.
|
|
232
|
-
totalCount: data.
|
|
216
|
+
items: data.myOrganizations.items,
|
|
217
|
+
totalCount: data.myOrganizations.total
|
|
233
218
|
});
|
|
234
219
|
} catch (error) {
|
|
235
220
|
ctx.logger.error("devportal_orgs_list failed", { error: String(error) });
|
|
@@ -266,19 +251,16 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
266
251
|
track(mcpToolName(ctx.productName, "devportal_orgs_create")),
|
|
267
252
|
{
|
|
268
253
|
title: "Create Publisher Organization",
|
|
269
|
-
description: "Create a publisher organization.",
|
|
254
|
+
description: "Create a publisher organization. The live supergraph requires `slug` \u2014 auto-derive from the name (kebab-case) if not supplied.",
|
|
270
255
|
inputSchema: {
|
|
271
256
|
name: z.string().describe("Organization name"),
|
|
272
|
-
|
|
273
|
-
|
|
257
|
+
slug: z.string().optional().describe("URL slug \u2014 auto-derived from `name` (kebab-case) when omitted"),
|
|
258
|
+
description: z.string().optional()
|
|
274
259
|
}
|
|
275
260
|
},
|
|
276
|
-
async ({ name,
|
|
261
|
+
async ({ name, slug, description }) => {
|
|
277
262
|
try {
|
|
278
|
-
const input = {
|
|
279
|
-
name,
|
|
280
|
-
tier: (tier ?? "ORGANIZATION").toUpperCase()
|
|
281
|
-
};
|
|
263
|
+
const input = { name, slug: slug ?? slugify(name) };
|
|
282
264
|
if (description !== void 0) input.description = description;
|
|
283
265
|
const data = await ctx.gql.global.request(
|
|
284
266
|
CREATE_ORGANIZATION,
|
|
@@ -346,10 +328,10 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
346
328
|
track(mcpToolName(ctx.productName, "devportal_apps_list")),
|
|
347
329
|
{
|
|
348
330
|
title: "List Devportal Applications",
|
|
349
|
-
description: "List devportal applications.",
|
|
331
|
+
description: "List devportal applications. `status` is the live `AppStatus` enum (DRAFT|REVIEW|PUBLISHED|ARCHIVED).",
|
|
350
332
|
inputSchema: {
|
|
351
333
|
organizationId: z.string().optional(),
|
|
352
|
-
status:
|
|
334
|
+
status: AppStatusEnum.optional(),
|
|
353
335
|
limit: z.number().optional().describe("Page size (default 50)")
|
|
354
336
|
}
|
|
355
337
|
},
|
|
@@ -357,7 +339,7 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
357
339
|
try {
|
|
358
340
|
const data = await ctx.gql.global.request(LIST_APPLICATIONS, {
|
|
359
341
|
organizationId,
|
|
360
|
-
status
|
|
342
|
+
status,
|
|
361
343
|
limit: limit ?? 50
|
|
362
344
|
});
|
|
363
345
|
return jsonResult({
|
|
@@ -399,19 +381,19 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
399
381
|
track(mcpToolName(ctx.productName, "devportal_apps_create")),
|
|
400
382
|
{
|
|
401
383
|
title: "Create Devportal Application",
|
|
402
|
-
description:
|
|
384
|
+
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").',
|
|
403
385
|
inputSchema: {
|
|
404
386
|
name: z.string().describe("Application name"),
|
|
405
|
-
|
|
406
|
-
|
|
387
|
+
appType: AppStatusEnum.describe(
|
|
388
|
+
"API_INTEGRATION|WEB_APP|MOBILE_APP (default API_INTEGRATION)"
|
|
389
|
+
).optional(),
|
|
407
390
|
description: z.string().optional()
|
|
408
391
|
}
|
|
409
392
|
},
|
|
410
|
-
async ({ name,
|
|
393
|
+
async ({ name, appType, description }) => {
|
|
411
394
|
try {
|
|
412
395
|
const input = {
|
|
413
396
|
name,
|
|
414
|
-
organizationId,
|
|
415
397
|
appType: (appType ?? "API_INTEGRATION").toUpperCase()
|
|
416
398
|
};
|
|
417
399
|
if (description !== void 0) input.description = description;
|
|
@@ -508,7 +490,7 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
508
490
|
track(mcpToolName(ctx.productName, "devportal_apps_delete")),
|
|
509
491
|
{
|
|
510
492
|
title: "Delete Devportal Application",
|
|
511
|
-
description: "Delete a devportal application.",
|
|
493
|
+
description: "Delete a devportal application. Live mutation returns Boolean! (no selection set).",
|
|
512
494
|
inputSchema: { id: z.string().describe("Application ID") }
|
|
513
495
|
},
|
|
514
496
|
async ({ id }) => {
|
|
@@ -523,27 +505,17 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
523
505
|
}
|
|
524
506
|
}
|
|
525
507
|
);
|
|
526
|
-
|
|
508
|
+
stubbedTool(
|
|
509
|
+
server,
|
|
510
|
+
ctx.productName,
|
|
527
511
|
track(mcpToolName(ctx.productName, "devportal_apps_versions_list")),
|
|
512
|
+
"List Application Versions",
|
|
513
|
+
"List versions for an application.",
|
|
514
|
+
"`Query.applicationVersions(applicationId)` was removed from the alpha devportal supergraph; there is no surviving `versions` field on `app(applicationId)`.",
|
|
528
515
|
{
|
|
529
|
-
|
|
530
|
-
description: "List versions for an application.",
|
|
531
|
-
inputSchema: { applicationId: z.string().describe("Application ID") }
|
|
516
|
+
applicationId: z.string().describe("Application ID")
|
|
532
517
|
},
|
|
533
|
-
|
|
534
|
-
try {
|
|
535
|
-
const data = await ctx.gql.global.request(
|
|
536
|
-
APPLICATION_VERSIONS,
|
|
537
|
-
{ applicationId }
|
|
538
|
-
);
|
|
539
|
-
return jsonResult(data.applicationVersions);
|
|
540
|
-
} catch (error) {
|
|
541
|
-
ctx.logger.error("devportal_apps_versions_list failed", { error: String(error) });
|
|
542
|
-
return errorResult(
|
|
543
|
-
`Failed to list versions: ${error instanceof Error ? error.message : String(error)}`
|
|
544
|
-
);
|
|
545
|
-
}
|
|
546
|
-
}
|
|
518
|
+
[`\`_devportal_apps_versions_create\``, `\`_devportal_apps_analytics\``]
|
|
547
519
|
);
|
|
548
520
|
server.registerTool(
|
|
549
521
|
track(mcpToolName(ctx.productName, "devportal_apps_versions_create")),
|
|
@@ -579,7 +551,7 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
579
551
|
track(mcpToolName(ctx.productName, "devportal_apps_webhooks_list")),
|
|
580
552
|
{
|
|
581
553
|
title: "List Application Webhooks",
|
|
582
|
-
description: "List webhooks attached to an application.",
|
|
554
|
+
description: "List webhooks attached to an application (live global `Query.webhooks(applicationId)`).",
|
|
583
555
|
inputSchema: { applicationId: z.string().describe("Application ID") }
|
|
584
556
|
},
|
|
585
557
|
async ({ applicationId }) => {
|
|
@@ -600,7 +572,7 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
600
572
|
track(mcpToolName(ctx.productName, "devportal_apps_webhooks_add")),
|
|
601
573
|
{
|
|
602
574
|
title: "Add Application Webhook",
|
|
603
|
-
description: "Add a webhook to an application.",
|
|
575
|
+
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`).",
|
|
604
576
|
inputSchema: {
|
|
605
577
|
applicationId: z.string().describe("Application ID"),
|
|
606
578
|
name: z.string().describe("Webhook name"),
|
|
@@ -612,18 +584,14 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
612
584
|
async ({ applicationId, name, url, events, maxRetries }) => {
|
|
613
585
|
try {
|
|
614
586
|
const input = {
|
|
615
|
-
applicationId,
|
|
616
587
|
name,
|
|
617
588
|
url,
|
|
618
589
|
events,
|
|
619
590
|
retryEnabled: true,
|
|
620
591
|
maxRetries: maxRetries ?? 5
|
|
621
592
|
};
|
|
622
|
-
const data = await ctx.gql.global.request(
|
|
623
|
-
|
|
624
|
-
{ input }
|
|
625
|
-
);
|
|
626
|
-
return jsonResult(data.createWebhook);
|
|
593
|
+
const data = await ctx.gql.global.request(CREATE_WEBHOOK, { applicationId, input });
|
|
594
|
+
return jsonResult(data.createWebhook.webhook);
|
|
627
595
|
} catch (error) {
|
|
628
596
|
ctx.logger.error("devportal_apps_webhooks_add failed", { error: String(error) });
|
|
629
597
|
return errorResult(
|
|
@@ -636,7 +604,7 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
636
604
|
track(mcpToolName(ctx.productName, "devportal_apps_webhooks_remove")),
|
|
637
605
|
{
|
|
638
606
|
title: "Remove Application Webhook",
|
|
639
|
-
description: "Remove a webhook by ID.",
|
|
607
|
+
description: "Remove a webhook by ID. Live mutation returns Boolean! (no selection set).",
|
|
640
608
|
inputSchema: { id: z.string().describe("Webhook ID") }
|
|
641
609
|
},
|
|
642
610
|
async ({ id }) => {
|
|
@@ -680,46 +648,43 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
680
648
|
}
|
|
681
649
|
}
|
|
682
650
|
);
|
|
683
|
-
|
|
651
|
+
stubbedTool(
|
|
652
|
+
server,
|
|
653
|
+
ctx.productName,
|
|
684
654
|
track(mcpToolName(ctx.productName, "devportal_revenue")),
|
|
655
|
+
"Organization Revenue",
|
|
656
|
+
"Get revenue summary for an organization.",
|
|
657
|
+
"`Query.organizationRevenue` (and any `revenue` field on `organization` / `app`) was removed from the alpha supergraph.",
|
|
685
658
|
{
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
inputSchema: {
|
|
689
|
-
organizationId: z.string().describe("Organization ID"),
|
|
690
|
-
period: z.string().optional().describe("LAST_7_DAYS|LAST_30_DAYS|YTD (default LAST_30_DAYS)")
|
|
691
|
-
}
|
|
659
|
+
organizationId: z.string().describe("Organization ID"),
|
|
660
|
+
period: z.string().optional().describe("LAST_7_DAYS|LAST_30_DAYS|YTD (default LAST_30_DAYS)")
|
|
692
661
|
},
|
|
693
|
-
|
|
694
|
-
try {
|
|
695
|
-
const data = await ctx.gql.global.request(ORGANIZATION_REVENUE, {
|
|
696
|
-
organizationId,
|
|
697
|
-
period: (period ?? "LAST_30_DAYS").toUpperCase()
|
|
698
|
-
});
|
|
699
|
-
return jsonResult(data.organizationRevenue);
|
|
700
|
-
} catch (error) {
|
|
701
|
-
ctx.logger.error("devportal_revenue failed", { error: String(error) });
|
|
702
|
-
return errorResult(
|
|
703
|
-
`Failed to fetch revenue: ${error instanceof Error ? error.message : String(error)}`
|
|
704
|
-
);
|
|
705
|
-
}
|
|
706
|
-
}
|
|
662
|
+
[`\`_billing_invoices_list\``, `\`_billing_subscriptions_list\``]
|
|
707
663
|
);
|
|
708
664
|
server.registerTool(
|
|
709
665
|
track(mcpToolName(ctx.productName, "devportal_admin_reviews_list")),
|
|
710
666
|
{
|
|
711
667
|
title: "List Admin Application Reviews",
|
|
712
|
-
description: "List applications in the admin review queue.",
|
|
668
|
+
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`).",
|
|
713
669
|
inputSchema: {
|
|
714
|
-
|
|
670
|
+
applicationId: z.string().describe("Application ID to scope the review queue to"),
|
|
671
|
+
status: AppReviewStatusEnum.optional(),
|
|
672
|
+
limit: z.number().optional().describe("Page size (default 20)"),
|
|
673
|
+
offset: z.number().optional().describe("Skip results")
|
|
715
674
|
}
|
|
716
675
|
},
|
|
717
|
-
async ({ status }) => {
|
|
676
|
+
async ({ applicationId, status, limit, offset }) => {
|
|
718
677
|
try {
|
|
719
|
-
const data = await ctx.gql.global.request(ADMIN_REVIEWS, {
|
|
678
|
+
const data = await ctx.gql.global.request(ADMIN_REVIEWS, {
|
|
679
|
+
applicationId,
|
|
680
|
+
status,
|
|
681
|
+
limit: limit ?? 20,
|
|
682
|
+
offset: offset ?? 0
|
|
683
|
+
});
|
|
720
684
|
return jsonResult({
|
|
721
|
-
items: data.
|
|
722
|
-
totalCount: data.
|
|
685
|
+
items: data.appReviews.edges.map((e) => e.node),
|
|
686
|
+
totalCount: data.appReviews.totalCount,
|
|
687
|
+
pageInfo: data.appReviews.pageInfo
|
|
723
688
|
});
|
|
724
689
|
} catch (error) {
|
|
725
690
|
ctx.logger.error("devportal_admin_reviews_list failed", { error: String(error) });
|
|
@@ -783,17 +748,15 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
783
748
|
track(mcpToolName(ctx.productName, "devportal_api_keys_list")),
|
|
784
749
|
{
|
|
785
750
|
title: "List API Keys",
|
|
786
|
-
description: "List API keys
|
|
751
|
+
description: "List API keys for an application. Live query is `appApiKeys(appId: ID!)`.",
|
|
787
752
|
inputSchema: {
|
|
788
|
-
applicationId: z.string().describe("Application ID
|
|
753
|
+
applicationId: z.string().describe("Application ID (forwarded as `appId`)")
|
|
789
754
|
}
|
|
790
755
|
},
|
|
791
756
|
async ({ applicationId }) => {
|
|
792
757
|
try {
|
|
793
|
-
const data = await ctx.gql.global.request(LIST_API_KEYS, {
|
|
794
|
-
|
|
795
|
-
});
|
|
796
|
-
return jsonResult(data.apiKeys);
|
|
758
|
+
const data = await ctx.gql.global.request(LIST_API_KEYS, { appId: applicationId });
|
|
759
|
+
return jsonResult(data.appApiKeys.apiKeys);
|
|
797
760
|
} catch (error) {
|
|
798
761
|
ctx.logger.error("devportal_api_keys_list failed", { error: String(error) });
|
|
799
762
|
return errorResult(
|
|
@@ -806,24 +769,26 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
806
769
|
track(mcpToolName(ctx.productName, "devportal_api_keys_create")),
|
|
807
770
|
{
|
|
808
771
|
title: "Create API Key",
|
|
809
|
-
description: "Mint a new API key
|
|
772
|
+
description: "Mint a new API key via `generateAPIKey(input: GenerateAPIKeyInput!)` (live auth mutation). Returns the full key including the one-time-visible `apiKey`/`apiSecret`.",
|
|
810
773
|
inputSchema: {
|
|
811
|
-
applicationId: z.string().describe("Application ID
|
|
812
|
-
name: z.string().min(1).describe("Human-readable name for the key
|
|
813
|
-
scopes: z.array(z.string()).
|
|
814
|
-
|
|
774
|
+
applicationId: z.string().describe("Application ID (forwarded as `appId`)"),
|
|
775
|
+
name: z.string().min(1).describe("Human-readable name for the key"),
|
|
776
|
+
scopes: z.array(z.string()).min(1).describe(
|
|
777
|
+
"Scope identifiers granted to the key \u2014 REQUIRED on the live `GenerateAPIKeyInput.scope`"
|
|
778
|
+
),
|
|
779
|
+
expiresAt: z.string().optional().describe("ISO 8601 expiry timestamp")
|
|
815
780
|
}
|
|
816
781
|
},
|
|
817
782
|
async ({ applicationId, name, scopes, expiresAt }) => {
|
|
818
783
|
try {
|
|
819
|
-
const input = {
|
|
820
|
-
|
|
784
|
+
const input = {
|
|
785
|
+
appId: applicationId,
|
|
786
|
+
name,
|
|
787
|
+
scope: scopes
|
|
788
|
+
};
|
|
821
789
|
if (expiresAt !== void 0) input.expiresAt = expiresAt;
|
|
822
|
-
const data = await ctx.gql.global.request(
|
|
823
|
-
|
|
824
|
-
{ input }
|
|
825
|
-
);
|
|
826
|
-
return jsonResult(data.createApiKey);
|
|
790
|
+
const data = await ctx.gql.global.request(CREATE_API_KEY, { input });
|
|
791
|
+
return jsonResult({ ...data.generateAPIKey, name, scopes, applicationId });
|
|
827
792
|
} catch (error) {
|
|
828
793
|
ctx.logger.error("devportal_api_keys_create failed", { error: String(error) });
|
|
829
794
|
return errorResult(
|
|
@@ -836,12 +801,12 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
836
801
|
track(mcpToolName(ctx.productName, "devportal_api_keys_revoke")),
|
|
837
802
|
{
|
|
838
803
|
title: "Revoke API Key",
|
|
839
|
-
description: "Revoke an API key
|
|
840
|
-
inputSchema: { id: z.string().describe("API key ID
|
|
804
|
+
description: "Revoke an API key via `revokeAPIKey(keyId: String!)` (live global mutation, returns Boolean!).",
|
|
805
|
+
inputSchema: { id: z.string().describe("API key ID (forwarded as `keyId`)") }
|
|
841
806
|
},
|
|
842
807
|
async ({ id }) => {
|
|
843
808
|
try {
|
|
844
|
-
await ctx.gql.global.request(REVOKE_API_KEY, { id });
|
|
809
|
+
await ctx.gql.global.request(REVOKE_API_KEY, { keyId: id });
|
|
845
810
|
return jsonResult({ status: "success", message: "API key revoked", apiKeyId: id });
|
|
846
811
|
} catch (error) {
|
|
847
812
|
ctx.logger.error("devportal_api_keys_revoke failed", { error: String(error) });
|
|
@@ -851,100 +816,60 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
851
816
|
}
|
|
852
817
|
}
|
|
853
818
|
);
|
|
854
|
-
|
|
819
|
+
stubbedTool(
|
|
820
|
+
server,
|
|
821
|
+
ctx.productName,
|
|
855
822
|
track(mcpToolName(ctx.productName, "devportal_oauth_list")),
|
|
823
|
+
"List OAuth Clients",
|
|
824
|
+
"List OAuth 2.0 clients registered for a devportal application.",
|
|
825
|
+
"`Query.oauthClients(applicationId)` no longer exists on the alpha supergraph, and `app(id)` does not expose a nested `oauthClients` field either.",
|
|
856
826
|
{
|
|
857
|
-
|
|
858
|
-
description: "List OAuth 2.0 clients registered for a devportal application.",
|
|
859
|
-
inputSchema: {
|
|
860
|
-
applicationId: z.string().describe("Application ID that owns the OAuth clients")
|
|
861
|
-
}
|
|
827
|
+
applicationId: z.string().describe("Application ID")
|
|
862
828
|
},
|
|
863
|
-
|
|
864
|
-
try {
|
|
865
|
-
const data = await ctx.gql.global.request(
|
|
866
|
-
LIST_OAUTH_CLIENTS,
|
|
867
|
-
{ applicationId }
|
|
868
|
-
);
|
|
869
|
-
return jsonResult(data.oauthClients);
|
|
870
|
-
} catch (error) {
|
|
871
|
-
ctx.logger.error("devportal_oauth_list failed", { error: String(error) });
|
|
872
|
-
return errorResult(
|
|
873
|
-
`Failed to list OAuth clients: ${error instanceof Error ? error.message : String(error)}`
|
|
874
|
-
);
|
|
875
|
-
}
|
|
876
|
-
}
|
|
829
|
+
[`\`_auth_current_user_apps\``]
|
|
877
830
|
);
|
|
878
|
-
|
|
831
|
+
stubbedTool(
|
|
832
|
+
server,
|
|
833
|
+
ctx.productName,
|
|
879
834
|
track(mcpToolName(ctx.productName, "devportal_oauth_create")),
|
|
835
|
+
"Create OAuth Client",
|
|
836
|
+
"Register a new OAuth 2.0 client for an application.",
|
|
837
|
+
"`Mutation.createOAuthClient` (and `CreateOAuthClientInput`) have been removed from the alpha supergraph.",
|
|
880
838
|
{
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
name: z.string().min(1).describe("Human-readable client name"),
|
|
886
|
-
redirectUris: z.array(z.string()).optional().describe("Allowed redirect URIs for authorization-code flows"),
|
|
887
|
-
grantTypes: z.array(OAuthGrantTypeEnum).optional().describe("OAuth grant types the client is allowed to use")
|
|
888
|
-
}
|
|
839
|
+
applicationId: z.string().describe("Application ID"),
|
|
840
|
+
name: z.string().describe("Client name"),
|
|
841
|
+
redirectUris: z.array(z.string()).optional(),
|
|
842
|
+
grantTypes: z.array(z.string()).optional()
|
|
889
843
|
},
|
|
890
|
-
|
|
891
|
-
try {
|
|
892
|
-
const input = { applicationId, name };
|
|
893
|
-
if (redirectUris !== void 0) input.redirectUris = redirectUris;
|
|
894
|
-
if (grantTypes !== void 0) input.grantTypes = grantTypes;
|
|
895
|
-
const data = await ctx.gql.global.request(
|
|
896
|
-
CREATE_OAUTH_CLIENT,
|
|
897
|
-
{ input }
|
|
898
|
-
);
|
|
899
|
-
return jsonResult(data.createOAuthClient);
|
|
900
|
-
} catch (error) {
|
|
901
|
-
ctx.logger.error("devportal_oauth_create failed", { error: String(error) });
|
|
902
|
-
return errorResult(
|
|
903
|
-
`Failed to create OAuth client: ${error instanceof Error ? error.message : String(error)}`
|
|
904
|
-
);
|
|
905
|
-
}
|
|
906
|
-
}
|
|
844
|
+
[`\`_auth_current_user_apps\` (read-only on alpha)`]
|
|
907
845
|
);
|
|
908
|
-
|
|
846
|
+
stubbedTool(
|
|
847
|
+
server,
|
|
848
|
+
ctx.productName,
|
|
909
849
|
track(mcpToolName(ctx.productName, "devportal_oauth_delete")),
|
|
850
|
+
"Delete OAuth Client",
|
|
851
|
+
"Delete an OAuth 2.0 client by ID.",
|
|
852
|
+
"`Mutation.deleteOAuthClient` has been removed from the alpha supergraph (no successor field).",
|
|
910
853
|
{
|
|
911
|
-
|
|
912
|
-
description: "Delete an OAuth 2.0 client by ID. Returns `{ status, message, oauthClientId }`.",
|
|
913
|
-
inputSchema: { id: z.string().describe("OAuth client ID") }
|
|
854
|
+
id: z.string().describe("OAuth client ID")
|
|
914
855
|
},
|
|
915
|
-
|
|
916
|
-
try {
|
|
917
|
-
await ctx.gql.global.request(DELETE_OAUTH_CLIENT, { id });
|
|
918
|
-
return jsonResult({
|
|
919
|
-
status: "success",
|
|
920
|
-
message: "OAuth client deleted",
|
|
921
|
-
oauthClientId: id
|
|
922
|
-
});
|
|
923
|
-
} catch (error) {
|
|
924
|
-
ctx.logger.error("devportal_oauth_delete failed", { error: String(error) });
|
|
925
|
-
return errorResult(
|
|
926
|
-
`Failed to delete OAuth client: ${error instanceof Error ? error.message : String(error)}`
|
|
927
|
-
);
|
|
928
|
-
}
|
|
929
|
-
}
|
|
856
|
+
[`\`_auth_*\` surface for current OAuth flows`]
|
|
930
857
|
);
|
|
931
858
|
server.registerTool(
|
|
932
859
|
track(mcpToolName(ctx.productName, "devportal_delegations_list")),
|
|
933
860
|
{
|
|
934
861
|
title: "List Delegations",
|
|
935
|
-
description: "List workspace delegations issued to applications.
|
|
862
|
+
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.",
|
|
936
863
|
inputSchema: {
|
|
937
|
-
|
|
938
|
-
|
|
864
|
+
first: z.number().optional().describe(
|
|
865
|
+
"Page size (default 50). Filter args from the old `delegations(...)` were dropped."
|
|
866
|
+
)
|
|
939
867
|
}
|
|
940
868
|
},
|
|
941
|
-
async ({
|
|
869
|
+
async ({ first }) => {
|
|
942
870
|
try {
|
|
943
|
-
const data = await ctx.gql.global.request(
|
|
944
|
-
|
|
945
|
-
{ applicationId, workspaceId }
|
|
946
|
-
);
|
|
947
|
-
return jsonResult(data.delegations);
|
|
871
|
+
const data = await ctx.gql.global.request(LIST_DELEGATIONS, { first: first ?? 50 });
|
|
872
|
+
return jsonResult(data.currentUserDelegations.delegations);
|
|
948
873
|
} catch (error) {
|
|
949
874
|
ctx.logger.error("devportal_delegations_list failed", { error: String(error) });
|
|
950
875
|
return errorResult(
|
|
@@ -957,24 +882,27 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
957
882
|
track(mcpToolName(ctx.productName, "devportal_delegations_create")),
|
|
958
883
|
{
|
|
959
884
|
title: "Create Delegation",
|
|
960
|
-
description: "Grant a workspace delegation to an application
|
|
885
|
+
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`.",
|
|
961
886
|
inputSchema: {
|
|
962
|
-
applicationId: z.string().describe("Application ID receiving the delegation"),
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
887
|
+
applicationId: z.string().describe("Application ID receiving the delegation (forwarded as `appId`)"),
|
|
888
|
+
scopes: z.array(z.string()).min(1).describe(
|
|
889
|
+
"Scope identifiers granted to the application \u2014 REQUIRED on the live GrantDelegationInput"
|
|
890
|
+
),
|
|
891
|
+
workspaceIds: z.array(z.string()).optional().describe(
|
|
892
|
+
"Optional list of workspace IDs scoping the delegation (forwarded as `workspaceIds`)"
|
|
893
|
+
),
|
|
894
|
+
expiresAt: z.string().optional().describe(
|
|
895
|
+
"ISO 8601 expiry timestamp (DateTime scalar \u2014 must be a full ISO 8601 instant, not a date)"
|
|
896
|
+
)
|
|
966
897
|
}
|
|
967
898
|
},
|
|
968
|
-
async ({ applicationId,
|
|
899
|
+
async ({ applicationId, scopes, workspaceIds, expiresAt }) => {
|
|
969
900
|
try {
|
|
970
|
-
const input = { applicationId,
|
|
971
|
-
if (
|
|
901
|
+
const input = { appId: applicationId, scopes };
|
|
902
|
+
if (workspaceIds !== void 0) input.workspaceIds = workspaceIds;
|
|
972
903
|
if (expiresAt !== void 0) input.expiresAt = expiresAt;
|
|
973
|
-
const data = await ctx.gql.global.request(
|
|
974
|
-
|
|
975
|
-
{ input }
|
|
976
|
-
);
|
|
977
|
-
return jsonResult(data.createDelegation);
|
|
904
|
+
const data = await ctx.gql.global.request(CREATE_DELEGATION, { input });
|
|
905
|
+
return jsonResult(data.grantDelegation);
|
|
978
906
|
} catch (error) {
|
|
979
907
|
ctx.logger.error("devportal_delegations_create failed", { error: String(error) });
|
|
980
908
|
return errorResult(
|
|
@@ -987,8 +915,8 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
987
915
|
track(mcpToolName(ctx.productName, "devportal_delegations_revoke")),
|
|
988
916
|
{
|
|
989
917
|
title: "Revoke Delegation",
|
|
990
|
-
description: "Revoke a workspace delegation
|
|
991
|
-
inputSchema: { id: z.string().describe("Delegation ID
|
|
918
|
+
description: "Revoke a workspace delegation via `revokeDelegation(id: ID!)` (live schema, returns Boolean!; no selection set).",
|
|
919
|
+
inputSchema: { id: z.string().describe("Delegation ID") }
|
|
992
920
|
},
|
|
993
921
|
async ({ id }) => {
|
|
994
922
|
try {
|
|
@@ -1003,6 +931,9 @@ function registerDevportalTools(server, ctx, track) {
|
|
|
1003
931
|
}
|
|
1004
932
|
);
|
|
1005
933
|
}
|
|
934
|
+
function slugify(s) {
|
|
935
|
+
return s.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "org";
|
|
936
|
+
}
|
|
1006
937
|
|
|
1007
938
|
// src/modules/devportal/index.ts
|
|
1008
939
|
var devportalModule = {
|