Skip to content

fix(mcp-server-admin): correct CreateApiKey GraphQL mutation#173

Merged
dsklyar merged 1 commit into
mainfrom
danielsklyar/zel-7752-agentic-assist-admin_create_api_key-graphql-mutation
Jun 2, 2026
Merged

fix(mcp-server-admin): correct CreateApiKey GraphQL mutation#173
dsklyar merged 1 commit into
mainfrom
danielsklyar/zel-7752-agentic-assist-admin_create_api_key-graphql-mutation

Conversation

@dsklyar
Copy link
Copy Markdown
Contributor

@dsklyar dsklyar commented Jun 1, 2026

Summary

The hand-rolled CreateApiKey mutation in @transcend-io/mcp-server-admin selected scopes without subfields and queried a non-existent top-level token field, so every admin_create_api_key invocation 400'd with GRAPHQL_VALIDATION_FAILED and Agentic Assist could not create API keys.

Related Issues

Changes

  • Mutation now selects apiKey { id title apiKey scopes { id name } createdAt } per the CreatedApiKey schema in transcend-io/main.
  • Adapter destructures the plain-text token out of data.createApiKey.apiKey.apiKey so the public { apiKey, token } return shape is unchanged — admin_create_api_key.ts and other downstream callers needed no edits.
  • The shared ApiKey type in @transcend-io/mcp-server-base already declares scopes: ApiKeyScope[], matching listApiKeys, so no type changes were required.

Test plan

  • pnpm --filter @transcend-io/mcp-server-admin test (7/7 pass)
  • pnpm --filter @transcend-io/mcp-server-admin typecheck
  • New regression test exercises AdminMixin.createApiKey against a stubbed fetch, asserting (a) the mutation body contains the corrected selection set and no top-level token, and (b) the token is sourced from the nested apiKey.apiKey field and not leaked back onto the returned apiKey object.
  • Pre-push hooks (turbo test, 17 packages) pass.
  • Reviewer: manual smoke via Agentic Assist after @transcend-io/mcp patch release lands in transcend-io/main.

Release

Includes a patch changeset for @transcend-io/mcp-server-admin. @transcend-io/mcp cascades automatically via updateInternalDependencies: "patch" in .changeset/config.json. Bumping @transcend-io/mcp in transcend-io/main/backend-services/transcend-mcp-server/package.json is out-of-scope for this PR (tracked on ZEL-7752).

Closes ZEL-7752.

Demo(s)

Before

Screenshot 2026-06-01 at 16 17 15

After

Screenshot 2026-06-01 at 16 11 02

The hand-rolled CreateApiKey mutation selected `scopes` without subfields
and queried a non-existent top-level `token` field, causing every
`admin_create_api_key` invocation to 400 with GRAPHQL_VALIDATION_FAILED.

Fixes ZEL-7752 by:
- selecting `scopes { id name }` per the CreatedApiKey schema
- reading the plain-text token from its real location at
  `createApiKey.apiKey.apiKey` and re-exposing it as `token` so the
  public `{ apiKey, token }` return shape is unchanged
- adding a regression test that exercises AdminMixin.createApiKey
  against a stubbed fetch to guard the mutation body and adapter
@linear-code
Copy link
Copy Markdown

linear-code Bot commented Jun 1, 2026

ZEL-7752

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jun 1, 2026

Open in StackBlitz

@transcend-io/airgap.js-types

pnpm add https://pkg.pr.new/@transcend-io/airgap.js-types@173
yarn add https://pkg.pr.new/@transcend-io/airgap.js-types@173.tgz

@transcend-io/cli

pnpm add https://pkg.pr.new/@transcend-io/cli@173
yarn add https://pkg.pr.new/@transcend-io/cli@173.tgz

@transcend-io/internationalization

pnpm add https://pkg.pr.new/@transcend-io/internationalization@173
yarn add https://pkg.pr.new/@transcend-io/internationalization@173.tgz

@transcend-io/privacy-types

pnpm add https://pkg.pr.new/@transcend-io/privacy-types@173
yarn add https://pkg.pr.new/@transcend-io/privacy-types@173.tgz

@transcend-io/sdk

pnpm add https://pkg.pr.new/@transcend-io/sdk@173
yarn add https://pkg.pr.new/@transcend-io/sdk@173.tgz

@transcend-io/type-utils

pnpm add https://pkg.pr.new/@transcend-io/type-utils@173
yarn add https://pkg.pr.new/@transcend-io/type-utils@173.tgz

@transcend-io/utils

pnpm add https://pkg.pr.new/@transcend-io/utils@173
yarn add https://pkg.pr.new/@transcend-io/utils@173.tgz

@transcend-io/mcp

pnpm add https://pkg.pr.new/@transcend-io/mcp@173
yarn add https://pkg.pr.new/@transcend-io/mcp@173.tgz

@transcend-io/mcp-server-admin

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-admin@173
yarn add https://pkg.pr.new/@transcend-io/mcp-server-admin@173.tgz

@transcend-io/mcp-server-assessment

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-assessment@173
yarn add https://pkg.pr.new/@transcend-io/mcp-server-assessment@173.tgz

@transcend-io/mcp-server-base

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-base@173
yarn add https://pkg.pr.new/@transcend-io/mcp-server-base@173.tgz

@transcend-io/mcp-server-consent

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-consent@173
yarn add https://pkg.pr.new/@transcend-io/mcp-server-consent@173.tgz

@transcend-io/mcp-server-discovery

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-discovery@173
yarn add https://pkg.pr.new/@transcend-io/mcp-server-discovery@173.tgz

@transcend-io/mcp-server-dsr

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-dsr@173
yarn add https://pkg.pr.new/@transcend-io/mcp-server-dsr@173.tgz

@transcend-io/mcp-server-inventory

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-inventory@173
yarn add https://pkg.pr.new/@transcend-io/mcp-server-inventory@173.tgz

@transcend-io/mcp-server-preferences

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-preferences@173
yarn add https://pkg.pr.new/@transcend-io/mcp-server-preferences@173.tgz

@transcend-io/mcp-server-workflows

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-workflows@173
yarn add https://pkg.pr.new/@transcend-io/mcp-server-workflows@173.tgz

commit: 9f1852b

Copy link
Copy Markdown
Member

@dawson-turechek-transcend dawson-turechek-transcend left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

createApiKey: { apiKey: ApiKey & { apiKey: string } };
}>(mutation, { input });
const { apiKey: token, ...apiKey } = data.createApiKey.apiKey;
return { apiKey, token };
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated spitballing: I'm curious how we might be able to keep these consistent with the backend or proactively detect a mismatch.

Putting the api definitions in a package is probably too much friction for development in the main repo.

Maybe we could eventually have a CI step to run these against staging BE?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the same thought yesterday and started to look into options on to how to use our staging schema to check in tools CI for any gql regressions. Will post PR for review once ready

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!

@dsklyar dsklyar added this pull request to the merge queue Jun 2, 2026
Merged via the queue into main with commit 6d32f5e Jun 2, 2026
4 checks passed
@dsklyar dsklyar deleted the danielsklyar/zel-7752-agentic-assist-admin_create_api_key-graphql-mutation branch June 2, 2026 16:24
dsklyar added a commit that referenced this pull request Jun 2, 2026
PR #173 (`fix(mcp-server-admin): correct CreateApiKey GraphQL mutation`)
landed on main while this branch was open. It addresses the same
CreateApiKey schema drift our 47801a1 already fixes, but as a
hand-rolled mutation rather than via the typed `graphql()` migration.

Resolution:
- packages/mcp/mcp-server-admin/src/graphql.ts: keep the typed
  graphql() form (strict superset of #173's fix).
- packages/mcp/mcp-server-admin/tests/admin.test.ts: keep all of
  #173's regression tests, with the two assertions that hard-coded
  the pre-migration mutation name (`CreateApiKey`) and return shape
  (`{ apiKey, token }`) updated to match the post-migration realities
  (`AdminCreateApiKey`, flat `CreatedApiKey`). The structural guards
  from #173 -- `scopes { id name }` is selected, no bare top-level
  `token`, plain-text token never leaks back onto the result -- are
  preserved verbatim.
- Both #173's changeset (`fix-admin-create-api-key-mutation.md`) and
  ours (`zel-7752-graphql-codegen-*.md`) are kept; changesets dedupe
  on next version PR with the highest bump winning.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants