This document describes how to deploy gnexus-creds and connect the MCP server to an AI agent.
gnexus-creds is one FastAPI application that serves:
/api/v1./auth.gnexus-auth profile webhook under /webhooks/gnexus-auth./mcp./mcp-protocol/.PostgreSQL is required. SQLite is not supported for production.
Create .env from .env.example and set real values:
GNEXUS_CREDS_ENV=production GNEXUS_CREDS_DATABASE_URL=postgresql+psycopg://gnexus_creds:change-me@postgres:5432/gnexus_creds GNEXUS_CREDS_MASTER_KEY=replace-with-a-long-random-master-key GNEXUS_CREDS_SESSION_SECRET=replace-with-a-long-random-session-secret GNEXUS_CREDS_SESSION_COOKIE_NAME=gnexus_creds_session GNEXUS_AUTH_BASE_URL=https://auth.gnexus.space GNEXUS_AUTH_CLIENT_ID=replace-with-client-id GNEXUS_AUTH_CLIENT_SECRET=replace-with-client-secret GNEXUS_AUTH_REDIRECT_URI=https://creds.gnexus.space/auth/callback GNEXUS_AUTH_WEBHOOK_SECRET=replace-with-webhook-secret GNEXUS_CREDS_MCP_RESOURCE_URL=https://creds.gnexus.space/mcp-protocol/ GNEXUS_CREDS_RATE_LIMIT_WINDOW_SECONDS=60 GNEXUS_CREDS_RATE_LIMIT_MAX_SENSITIVE_REQUESTS=120
For local development on port 8018, use HTTP values:
GNEXUS_CREDS_ENV=development GNEXUS_CREDS_DATABASE_URL=postgresql+psycopg://gnexus_creds:gnexus_creds@127.0.0.1:5432/gnexus_creds GNEXUS_CREDS_MASTER_KEY=local-long-random-master-key GNEXUS_CREDS_SESSION_SECRET=local-long-random-session-secret GNEXUS_AUTH_BASE_URL=http://gnexus-auth.local GNEXUS_AUTH_CLIENT_ID=gnexus-creds GNEXUS_AUTH_CLIENT_SECRET=replace-with-local-client-secret GNEXUS_AUTH_REDIRECT_URI=http://localhost:8018/auth/callback GNEXUS_AUTH_WEBHOOK_SECRET=replace-with-local-webhook-secret GNEXUS_CREDS_MCP_RESOURCE_URL=http://localhost:8018/mcp-protocol/
Production mode fails fast if default secrets are used or if public auth/MCP URLs do not use HTTPS.
Register gnexus-creds as an OAuth client in gnexus-auth.
Local development values:
gnexus-creds, or the value from GNEXUS_AUTH_CLIENT_ID.GNEXUS_AUTH_CLIENT_SECRET.http://localhost:8018/auth/callback.openid, email, profile.http://localhost:8018/webhooks/gnexus-auth.GNEXUS_AUTH_WEBHOOK_SECRET.Production values:
https://creds.gnexus.space/auth/callback.https://creds.gnexus.space/webhooks/gnexus-auth.https://auth.gnexus.space.User profile data and user status come from gnexus-auth. The supported system roles are:
useradminIf gnexus-auth sends a disabled, blocked, or deleted status, gnexus-creds keeps the local user data but blocks login.
Install backend dependencies:
uv sync --extra dev
Start PostgreSQL through Docker Compose:
docker-compose up -d postgres
Run migrations:
uv run alembic upgrade head
Build the frontend bundle served by FastAPI:
cd frontend npm install npm run build cd ..
Start the server on port 8018:
uv run uvicorn gnexus_creds.main:app --host 0.0.0.0 --port 8018 --reload
Open the UI:
http://localhost:8018/
Login starts through:
http://localhost:8018/auth/login
Prepare .env, then build and start PostgreSQL:
docker-compose build app docker-compose up -d postgres
Run migrations explicitly:
docker-compose run --rm app alembic upgrade head
Start the app:
docker-compose up -d app
The included docker-compose.yml maps the app to host port 8000:
ports: - "8000:8000"
For local testing on 8018, change it to:
ports: - "8018:8000"
The Docker image contains the built Vue UI. Migrations are not run automatically by the container.
The reverse proxy must forward these paths to the FastAPI app:
//api/v1/*/auth/*/webhooks/*/mcp/*/mcp-protocol/*/health/readyFor MCP Streamable HTTP, do not buffer or rewrite request bodies. Keep the trailing slash in the MCP URL:
https://creds.gnexus.space/mcp-protocol/
Liveness:
curl -fsS http://localhost:8018/health
Readiness, including database connectivity:
curl -fsS http://localhost:8018/ready
Apply migrations before every deploy:
uv run alembic upgrade head
or inside Docker:
docker-compose run --rm app alembic upgrade head
MCP uses gnexus-creds API tokens, not gnexus-auth access tokens.
Tokens.mcp, read
Allows search and metadata reads.
mcp, read, reveal
Allows search, metadata reads, and decrypted reveal.
mcp, read, reveal, write
Allows full MCP access, including creating and updating secrets.
The admin scope is not required for normal MCP access.
Only secrets with allow_mcp=true are visible through MCP. Archived secrets are not visible through normal MCP access.
Use the official Streamable HTTP endpoint when the AI agent supports MCP over HTTP:
https://creds.gnexus.space/mcp-protocol/
Local development:
http://localhost:8018/mcp-protocol/
The agent must send:
Authorization: Bearer <gnexus-creds-api-token>
Generic agent configuration shape:
{
"mcpServers": {
"gnexus-creds": {
"type": "streamable-http",
"url": "https://creds.gnexus.space/mcp-protocol/",
"headers": {
"Authorization": "Bearer <gnexus-creds-api-token>"
}
}
}
}
Some agents name the transport http, streamable_http, or mcp-http. Use the transport name expected by the concrete agent, but keep the URL and Authorization header unchanged.
stdio is not supported and should not be used: the AI agent and gnexus-creds server are expected to run on different hosts.
Use the legacy adapter only for clients that do not support MCP Streamable HTTP.
Discovery stream:
curl -N \ -H "Authorization: Bearer $GNEXUS_CREDS_MCP_TOKEN" \ http://localhost:8018/mcp/sse
Search secrets:
curl -sS \
-H "Authorization: Bearer $GNEXUS_CREDS_MCP_TOKEN" \
-H "Content-Type: application/json" \
-d '{"arguments":{"q":"github","limit":5}}' \
http://localhost:8018/mcp/tools/search_secrets
Reveal one secret:
curl -sS \
-H "Authorization: Bearer $GNEXUS_CREDS_MCP_TOKEN" \
-H "Content-Type: application/json" \
-d '{"arguments":{"secret_id":"<secret-uuid>"}}' \
http://localhost:8018/mcp/tools/reveal_secret
Create a secret:
curl -sS \
-H "Authorization: Bearer $GNEXUS_CREDS_MCP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"arguments": {
"title": "Example",
"purpose": "example.com",
"category": "site",
"tags": ["example"],
"allow_ui": true,
"allow_rest_api": true,
"allow_mcp": true,
"fields": [
{"name": "username", "value": "user@example.com", "encrypted": false},
{"name": "password", "value": "secret-password", "encrypted": true, "masked": true}
]
}
}' \
http://localhost:8018/mcp/tools/create_secret
Current tools:
search_secretsget_secretreveal_secretcreate_secretupdate_secretset_secret_statusarchive_secretSearch returns metadata and unencrypted fields only. Encrypted values are returned only by reveal_secret.
Reveal and write actions create audit events with channel=mcp.
401 Unauthorized:
Authorization header.403 Forbidden:
mcp scope.read, reveal, or write.gnexus-auth.Secret is missing from MCP search:
allow_mcp=false.OAuth callback fails:
GNEXUS_AUTH_REDIRECT_URI does not exactly match the client redirect URI in gnexus-auth.GNEXUS_AUTH_CLIENT_SECRET is wrong.GNEXUS_AUTH_BASE_URL points to the wrong auth instance.Production app refuses to start:
GNEXUS_CREDS_ENV=production requires HTTPS for auth redirect and MCP resource URLs..env.example must be replaced.