Personal access tokens for the MCP server and the GraphQL API
Maintainers usually reply within 2 days
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- graphql, typescript
- Domain
- authentication, backend-api-design, frontend, security
Research direction
Start by reading the referenced auth plugin, auth-context provider, MCP auth files, and upstream GraphQL client, then review the existing API-key helper and connector-gaps document. Trace how JWT identity, memberships, forwarding, rate limits, and audit logging currently work before deciding the PAT design. Done means the listed acceptance criteria pass, including creation and revocation through the client, scope and membership enforcement, 401 responses, and the required checks.
Written by the indexing model from the issue text.
Description
Part of #4611 (step M4, phase 4).
Context
Some MCP hosts, as well as headless and CI clients, cannot complete interactive OAuth.
The current workaround should not be recommended. It means copying the web app's access token from the browser into a client's Authorization header. This works, because both the MCP server and the GraphQL API accept any valid Auth0 access token for the shared audience. But the token:
- is short-lived and never refreshes;
- carries the user's full API power;
- is taken from the SPA's
localStorage.
The existing API keys are not a substitute:
- They live in
accounter_schema.api_keys, are sent asX-API-Key, and are managed withgenerateApiKey/listApiKeys/revokeApiKey. - They are restricted to the
scraperandgmail_listenerroles (packages/server/src/modules/auth/helpers/api-keys.helper.ts). - Each key is pinned to one business.
- The MCP server only accepts JWTs (
packages/mcp-server/src/auth/token.ts,verifier.ts), so it can't take an API key.
Scope
Token model. User-scoped personal access tokens (PATs) that are:
- hashed at rest;
- named;
- required to expire;
- revocable;
- tracked by last use;
- least privilege: read-only by default, with explicit opt-in for write scopes;
- optionally restricted to a subset of the user's businesses.
Server. Add a PAT path to packages/server/src/plugins/auth-plugin.ts and auth-context.provider.ts. It resolves to the owning user's identity and memberships, intersected with the token's scopes and businesses.
MCP server.
- Accept PATs alongside JWTs and forward them upstream.
src/upstream/graphql-client.tscurrently forwardsAuthorization. - Key rate limits and audit lines by user.
Client. Add create, list and revoke UI, either on the Account page from #4615 or under Access Management.
Audit. Write audit-log entries when a token is created, used and revoked.
Acceptance criteria
- A user creates a read-only PAT, uses it in an MCP client's header config and against GraphQL, then revokes it.
- Revoked and expired tokens get 401.
- A PAT never grants more than its owner currently has. Removing a membership takes effect immediately.
-
yarn generate,yarn lintandyarn testpass.
Dependencies
Phase 4. Independent of #4616 and #4617. The UI may reuse the Account page from #4615.
References
packages/server/src/plugins/auth-plugin.tspackages/server/src/modules/auth/providers/auth-context.provider.tspackages/server/src/modules/auth/helpers/api-keys.helper.tspackages/mcp-server/src/auth/,src/upstream/graphql-client.tspackages/mcp-server/docs/connector-gaps-and-decisions.md(gap 3: shared audience)
- Dominant language
- TypeScript
- Stars
- 30
- Forks
- 8
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 176
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Urigo/accounter-fullstack
-
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
Urigo/accounter-fullstack#4604 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Urigo/accounter-fullstack#4583 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Urigo/accounter-fullstack#4580 ·
Maintainers usually reply within 2 days
-
Document PG18 migration conventions: NOT NULL NOT VALID, and generated columns default to VIRTUALOpen
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Urigo/accounter-fullstack#4366 ·
Maintainers usually reply within 2 days
-
documentation
Difficulty 4/5 3-5 days Newbie friendliness 55/100
Urigo/accounter-fullstack#4619 ·
Maintainers usually reply within 2 days
All issues in Urigo/accounter-fullstack
Similar issues
-
triage
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
github/docs#46222 · 1 comment ·
Maintainers usually reply within 1 day
-
agent-ready area: config area: skills type: chore upstream: brain-kit
Difficulty 1/5 Under an hour Newbie friendliness 95/100
-
enhancement priority:low ready-for-dev
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 1 day
-
bug escritorio mapa
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
marcosferr/reporte-ciudadano#4 · 1 comment ·
-
area: material/sort gemini-triaged needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
angular/components#33933 ·
Maintainers usually reply within 1 day