clue2app-user-mcp
Officialby clue2solve
README.md
# clue2app-user-mcp
MCP server exposing coordinator's user/membership/role admin operations as
tools for LLM callers (agents, Claude Desktop, etc.). Every tool is a thin
passthrough to coordinator's `/api/users/*` endpoints — RBAC is enforced
entirely by coordinator using the caller's bearer token; this service does
not validate or interpret tokens itself.
## Tool catalog
| Group | Tool | Coordinator endpoint |
|---|---|---|
| users | `list_users` | `GET /api/users` |
| users | `get_user` | `GET /api/users/{id}` |
| users | `disable_user` | `POST /api/users/{id}/disable` |
| users | `enable_user` | `POST /api/users/{id}/enable` |
| users | `resolve_duplicate_users` | `POST /api/users/resolve-duplicates` |
| memberships | `list_user_memberships` | `GET /api/users/{id}/memberships` |
| roles | `grant_role` | `POST /api/users/{id}/roles` |
| roles | `revoke_role` | `DELETE /api/users/{id}/roles/{role}` |
## Local dev (stdio transport)
```bash
cd clue2app-user-mcp
python -m venv .venv && source .venv/bin/activate
pip install -e .
export COORDINATOR_URL=http://localhost:8081 # or your coordinator base URL
export COORDINATOR_TOKEN=<a coordinator-issued bearer token>
user-mcp # defaults to --transport=stdio
# or: python -m user_mcp.server --transport=stdio
```
Point an MCP-capable client (Claude Desktop, `mcp dev`, etc.) at the
`user-mcp` command with those two env vars set. stdio has no per-request
auth header, so the token is read once from `COORDINATOR_TOKEN` at startup
and reused for every tool call in that session.
### Quick smoke test
```bash
python -c "
import sys; sys.path.insert(0, 'src')
from user_mcp import server
print([t for t in dir(server) if not t.startswith('_')][:5])
"
```
## Hosted deploy (SSE transport)
The Knative/kpack deployment runs the SSE transport, which reads the bearer
token per-request from the inbound `Authorization: Bearer <token>` header —
each caller supplies their own token, so a single instance safely serves
many callers at different privilege levels.
```bash
python -m user_mcp.server --transport=sse --port=$PORT
```
This is exactly what `Procfile` runs. Paketo's Python buildpack detects
`pyproject.toml` directly (no `requirements.txt` needed, no `Dockerfile`
needed) and uses `python -m` so we don't depend on where the buildpack
places console-script shims in the launch image.
**Env vars**
| Var | Required | Notes |
|---|---|---|
| `COORDINATOR_URL` | yes | e.g. `http://coordinator.control.svc.cluster.local` in-cluster |
| `COORDINATOR_TOKEN` | stdio only | ignored by the SSE transport |
| `PORT` | no | Knative-injected; defaults to 8080 |
No secrets are baked into this service — every tool call carries its own
token, and the service holds nothing longer than the lifetime of a single
request.
## Endpoints
* `GET /sse` — MCP session endpoint (SSE transport)
* `POST /messages` — MCP message endpoint (SSE transport)
* `GET /health` — `200 {"status": "ok"}`, no coordinator round-trip. Wire
both `readinessProbe` and `livenessProbe` to this path — a coordinator
outage must not cascade into MCP pod restarts.
## Layout
```
src/user_mcp/
├── server.py # FastMCP init, CLI dispatch, /health, transport wiring
├── coord_client.py # httpx.AsyncClient wrapper, bearer passthrough
├── auth.py # bearer_from_context() using a contextvar
└── tools/
├── users.py # list/get/disable/enable/resolve_duplicates
├── memberships.py # list_user_memberships
└── roles.py # grant/revoke_role
```
TDQS
A3.9/5.0
Scored across 8 tools
Disambiguation5/5
Each tool has a clearly distinct purpose: disabling, enabling, fetching, granting roles, listing memberships, listing users, resolving duplicates, and revoking roles. No overlap or ambiguity.
Naming Consistency5/5
All tool names follow a consistent verb_noun pattern using snake_case (e.g., disable_user, grant_role). Naming is predictable and uniform.
Tool Count5/5
8 tools is well-scoped for user management, covering core operations without unnecessary bloat.
Completeness4/5
The set covers enable/disable, role management, and listing, but lacks create_user and delete_user, which are minor gaps for a user management server.
Maintenance
ActivityStale
ResponsivenessNo issues