Adds a /mcp-tokens page so a logged-in user can mint, list, and revoke bearer tokens for the MCP server without curl. Stacks on #92 (which added the agent endpoints + MCP middleware) — once both land, a user can copy a token from the dashboard straight into their LLM client config.
Targets feat/m7.3-mcp-tenant-tokens (#92's branch) so the diff shown is only the UI changes. When #92 merges, this PR auto-retargets to main.
UX
Create: "Create Token" button → inline form with name input. On submit, the server function calls POST /api/v1/mcp-tokens. The raw token is shown once in a yellow banner with a copy button and a "won't be shown again" warning. User dismisses manually.
List: cards with name, prefix (mcpt_xxxx…), created date, last_used (or "never"). Revoked tokens render dimmed with a "revoked" pill.
Manual after deploy: log in, hit /mcp-tokens, create a token, copy it, paste into a fresh curl against comp-mcp-dev.meghsakha.com/mcp, confirm tools/list works. Revoke; confirm a subsequent call 401s.
Followups
No sidebar entry — matches mcp_servers (settings-style pages reached via direct URL). Worth a future Settings sub-menu pass.
When the agent adds token expiry + per-tool scope, the create modal grows extra fields.
## Summary
Adds a `/mcp-tokens` page so a logged-in user can mint, list, and revoke bearer tokens for the MCP server without curl. Stacks on **#92** (which added the agent endpoints + MCP middleware) — once both land, a user can copy a token from the dashboard straight into their LLM client config.
**Targets `feat/m7.3-mcp-tenant-tokens` (#92's branch)** so the diff shown is only the UI changes. When #92 merges, this PR auto-retargets to main.
## UX
- **Create**: "Create Token" button → inline form with name input. On submit, the server function calls `POST /api/v1/mcp-tokens`. The raw token is shown **once** in a yellow banner with a copy button and a "won't be shown again" warning. User dismisses manually.
- **List**: cards with name, prefix (`mcpt_xxxx…`), created date, last_used (or "never"). Revoked tokens render dimmed with a "revoked" pill.
- **Revoke**: trash button → confirm modal → soft delete.
- Toast feedback throughout.
## Files
| File | What |
|---|---|
| `infrastructure/mcp_tokens.rs` (new) | Three `#[server]` fns going through `agent_client` (auto-attaches the KC bearer + handles token refresh) |
| `pages/mcp_tokens.rs` (new) | The page component |
| `app.rs` | Adds `Route::McpTokensPage` at `/mcp-tokens` |
| `pages/mod.rs`, `infrastructure/mod.rs` | Module + re-export wiring |
## Test plan
- [x] `cargo fmt --all -- --check` clean
- [x] `cargo clippy -p compliance-dashboard --features server -- -D warnings` clean
- [x] `cargo clippy -p compliance-dashboard --features web --no-default-features -- -D warnings` clean
- [x] `cargo check` on both feature sets clean
- [ ] Manual after deploy: log in, hit `/mcp-tokens`, create a token, copy it, paste into a fresh curl against `comp-mcp-dev.meghsakha.com/mcp`, confirm tools/list works. Revoke; confirm a subsequent call 401s.
## Followups
- No sidebar entry — matches `mcp_servers` (settings-style pages reached via direct URL). Worth a future Settings sub-menu pass.
- When the agent adds token expiry + per-tool scope, the create modal grows extra fields.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
sharang
changed target branch from feat/m7.3-mcp-tenant-tokens to main2026-06-30 15:27:38 +00:00
Adds /mcp-tokens page that lets a logged-in user mint, list, and
revoke bearer tokens for the MCP server. Stacks on #92 (which added
the agent endpoints + middleware) — once both land, the loop is
closed: a user can copy a token from the dashboard straight into
their Claude Desktop / Cursor / ChatGPT MCP config.
UX
- "Create Token" button → inline form with name input.
- On submit, server function calls `POST /api/v1/mcp-tokens`. The
raw token is shown ONCE in a prominent yellow banner with a copy
button and a "won't be shown again" warning, then the user
dismisses it manually.
- List view: card per token with name, prefix `mcpt_xxxx…`, created
date, last_used (or "never"). Revoked tokens render dimmed with a
"revoked" pill. Active tokens have a trash button → confirm
modal → soft delete.
- Toast feedback on create/revoke success/failure.
Files
- infrastructure/mcp_tokens.rs (new) — three #[server] functions:
fetch_mcp_tokens, create_mcp_token, revoke_mcp_token. All go
through agent_client so the Keycloak Bearer is auto-attached;
the agent then enforces tenant scoping on every endpoint.
- pages/mcp_tokens.rs (new) — the page component itself.
- app.rs — adds Route::McpTokensPage at /mcp-tokens.
- pages/mod.rs, infrastructure/mod.rs — module + re-export wiring.
Timestamp format
- The agent serializes BSON DateTime as extended JSON
`{"$date":{"$numberLong":"..."}}`. Page has a small helper that
accepts that shape, plain ISO strings, or anything else
(best-effort). Same approach used elsewhere in the dashboard so
there's no new dependency.
Test plan
- cargo fmt --all clean
- cargo clippy -p compliance-dashboard --features server
-- -D warnings clean
- cargo clippy -p compliance-dashboard --features web
--no-default-features -- -D warnings clean
- cargo check on both feature sets clean
Followup
- No sidebar entry yet (matches mcp_servers — settings-style
pages are reached via direct URL today). Worth adding a
Settings sub-menu in a separate UX pass.
- Token expiry + per-tool scope when those land on the agent side
will need a small UI for the create modal (extra fields).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Adds a
/mcp-tokenspage so a logged-in user can mint, list, and revoke bearer tokens for the MCP server without curl. Stacks on #92 (which added the agent endpoints + MCP middleware) — once both land, a user can copy a token from the dashboard straight into their LLM client config.Targets
feat/m7.3-mcp-tenant-tokens(#92's branch) so the diff shown is only the UI changes. When #92 merges, this PR auto-retargets to main.UX
POST /api/v1/mcp-tokens. The raw token is shown once in a yellow banner with a copy button and a "won't be shown again" warning. User dismisses manually.mcpt_xxxx…), created date, last_used (or "never"). Revoked tokens render dimmed with a "revoked" pill.Files
infrastructure/mcp_tokens.rs(new)#[server]fns going throughagent_client(auto-attaches the KC bearer + handles token refresh)pages/mcp_tokens.rs(new)app.rsRoute::McpTokensPageat/mcp-tokenspages/mod.rs,infrastructure/mod.rsTest plan
cargo fmt --all -- --checkcleancargo clippy -p compliance-dashboard --features server -- -D warningscleancargo clippy -p compliance-dashboard --features web --no-default-features -- -D warningscleancargo checkon both feature sets clean/mcp-tokens, create a token, copy it, paste into a fresh curl againstcomp-mcp-dev.meghsakha.com/mcp, confirm tools/list works. Revoke; confirm a subsequent call 401s.Followups
mcp_servers(settings-style pages reached via direct URL). Worth a future Settings sub-menu pass.🤖 Generated with Claude Code
b3a8a97729toeb88656c43eb88656c43to7e07ebeb53