@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
- organizations(limit: $limit, offset: $offset) {
8
- edges { node { id name slug status } }
9
- totalCount pageInfo { hasNextPage }
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) { success }
36
+ deleteOrganization(id: $id)
37
37
  }
38
38
  `;
39
39
  var LIST_APPLICATIONS = `
40
- query ListApplications($organizationId: ID, $status: String, $limit: Int) {
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) { success }
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) { success }
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: String) {
136
- adminReviews(status: $status) {
137
- edges { node { id applicationId reviewStatus reviewNotes } }
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($applicationId: ID!) {
158
- apiKeys(applicationId: $applicationId) {
159
- id applicationId name prefix scopes lastUsedAt isActive createdAt
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: CreateApiKeyInput!) {
165
- createApiKey(input: $input) {
166
- id applicationId name prefix token scopes isActive createdAt
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($id: ID!) {
172
- revokeApiKey(id: $id) { success }
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($applicationId: ID, $workspaceId: ID) {
196
- delegations(applicationId: $applicationId, workspaceId: $workspaceId) {
197
- id applicationId workspaceId scopes status expiresAt createdAt
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: CreateDelegationInput!) {
203
- createDelegation(input: $input) {
204
- id applicationId workspaceId scopes status expiresAt
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) { success }
181
+ revokeDelegation(id: $id)
211
182
  }
212
183
  `;
213
184
 
214
185
  // src/modules/devportal/tools.ts
215
- var OAuthGrantTypeEnum = z.enum(["AUTHORIZATION_CODE", "CLIENT_CREDENTIALS", "REFRESH_TOKEN", "PASSWORD", "IMPLICIT"]).describe("OAuth 2.0 grant type");
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.organizations.edges.map((e) => e.node),
232
- totalCount: data.organizations.totalCount
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
- description: z.string().optional(),
273
- tier: z.string().optional().describe("INDIVIDUAL|ORGANIZATION|ENTERPRISE (default ORGANIZATION)")
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, description, tier }) => {
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: z.string().optional().describe("DRAFT|REVIEW|PUBLISHED|ARCHIVED"),
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: status ? status.toUpperCase() : void 0,
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: "Create a devportal application.",
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
- organizationId: z.string().describe("Owning organization ID"),
406
- appType: z.string().optional().describe("API_INTEGRATION|WEB_APP|MOBILE_APP (default API_INTEGRATION)"),
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, organizationId, appType, description }) => {
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
- server.registerTool(
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
- title: "List Application Versions",
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
- async ({ applicationId }) => {
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
- CREATE_WEBHOOK,
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
- server.registerTool(
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
- title: "Organization Revenue",
687
- description: "Get revenue summary for an organization.",
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
- async ({ organizationId, period }) => {
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
- status: z.string().optional().describe("PENDING|APPROVED|REJECTED (default PENDING)")
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, { status: (status ?? "PENDING").toUpperCase() });
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.adminReviews.edges.map((e) => e.node),
722
- totalCount: data.adminReviews.totalCount
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 issued for a devportal application. Returns an array of key metadata (no secret material).",
751
+ description: "List API keys for an application. Live query is `appApiKeys(appId: ID!)`.",
787
752
  inputSchema: {
788
- applicationId: z.string().describe("Application ID that owns the API keys")
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
- applicationId
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 for an application. Returns the full key including the one-time-visible `token` \u2014 surface it once and never persist server-side after handoff.",
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 that will own the key"),
812
- name: z.string().min(1).describe("Human-readable name for the key (audit/UI label)"),
813
- scopes: z.array(z.string()).optional().describe("Scope identifiers granted to the key (omit for default scopes)"),
814
- expiresAt: z.string().optional().describe("ISO 8601 expiry timestamp (omit for non-expiring key)")
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 = { applicationId, name };
820
- if (scopes !== void 0) input.scopes = scopes;
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
- CREATE_API_KEY,
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 by ID. Revocation is irreversible. Returns `{ status, message, apiKeyId }`.",
840
- inputSchema: { id: z.string().describe("API key ID to revoke") }
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
- server.registerTool(
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
- title: "List OAuth Clients",
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
- async ({ applicationId }) => {
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
- server.registerTool(
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
- title: "Create OAuth Client",
882
- description: "Register a new OAuth 2.0 client for an application. Returns the client including the one-time-visible `clientSecret`.",
883
- inputSchema: {
884
- applicationId: z.string().describe("Application ID that will own the client"),
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
- async ({ applicationId, name, redirectUris, grantTypes }) => {
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
- server.registerTool(
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
- title: "Delete OAuth Client",
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
- async ({ id }) => {
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. Filter by application or workspace.",
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
- applicationId: z.string().optional().describe("Filter by application ID"),
938
- workspaceId: z.string().optional().describe("Filter by workspace ID")
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 ({ applicationId, workspaceId }) => {
869
+ async ({ first }) => {
942
870
  try {
943
- const data = await ctx.gql.global.request(
944
- LIST_DELEGATIONS,
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 with the given scopes. Returns the persisted delegation.",
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
- workspaceId: z.string().describe("Workspace ID granting the delegation"),
964
- scopes: z.array(z.string()).optional().describe("Scope identifiers granted to the application (omit for default scope set)"),
965
- expiresAt: z.string().optional().describe("ISO 8601 expiry timestamp (omit for non-expiring delegation)")
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, workspaceId, scopes, expiresAt }) => {
899
+ async ({ applicationId, scopes, workspaceIds, expiresAt }) => {
969
900
  try {
970
- const input = { applicationId, workspaceId };
971
- if (scopes !== void 0) input.scopes = scopes;
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
- CREATE_DELEGATION,
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 by ID. Returns `{ status, message, delegationId }`.",
991
- inputSchema: { id: z.string().describe("Delegation ID to revoke") }
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 = {