5.9 KiB
Configuration
All settings are environment variables. They are read case-insensitively from the process
environment and from a .env file in the working directory (the environment wins). Unknown
variables are ignored. A blank value (KEY= in .env) counts as unset for the optional
secrets, URLs and paths. List values accept commas or whitespace as separators.
.env.example is the annotated template. uv run aegis-gitea-mcp setup fills one in for you
(see getting-started.md). Secret settings never appear in logs, errors or
repr output.
Requirements that depend on how the server is started are checked at start, not on import:
GITEA_TOKEN for stdio, authentication for a non-loopback HTTP bind, complete OAuth settings
when OAuth is on.
Gitea
| Variable | Default | Rules |
|---|---|---|
GITEA_URL |
required | http or https, must have a host, no credentials, query or fragment. A trailing /api/v1 is removed. |
GITEA_TOKEN |
unset | Token for stdio and for admin-token mode on HTTP. Its scopes bound what the server can do. Required for stdio (exit code 2 without it). |
Transport
| Variable | Default | Rules |
|---|---|---|
MCP_TRANSPORT |
stdio |
stdio or http. serve --transport overrides it. |
MCP_HOST |
127.0.0.1 |
Bind address for HTTP. A non-loopback value refuses to start unless HTTP auth is configured. |
MCP_PORT |
8080 |
1 to 65535. |
MCP_PATH |
/mcp |
Starts with a single /, no query, spaces or trailing slash, not just /. |
MCP_BEARER_TOKEN |
unset | Static bearer token for HTTP (admin identity). At least 32 characters. Generate with openssl rand -hex 32. |
PUBLIC_BASE_URL |
unset | Public URL behind a reverse proxy. Same URL rules as GITEA_URL, and https unless the host is loopback. Required for OAuth. |
ALLOWED_HOSTS |
empty | Extra Host header values accepted behind a proxy. The loopback names with the port and the host of PUBLIC_BASE_URL are always allowed. Other Host values are rejected (DNS-rebinding protection). |
Per-user OAuth (HTTP only)
| Variable | Default | Rules |
|---|---|---|
OAUTH_ENABLED |
false |
When true, the four settings below are required, or the server refuses to start (exit code 2, with the list of what is missing). |
GITEA_OAUTH_CLIENT_ID |
unset | Client id of the Gitea OAuth application (created by setup). |
GITEA_OAUTH_CLIENT_SECRET |
unset | Its client secret. |
TOKEN_ENCRYPTION_KEY |
unset | At least 32 characters. Encrypts stored user tokens. Losing it invalidates every stored login. |
OAUTH_SCOPES |
all write:<category> scopes |
Granular Gitea scopes only (read: or write: plus activitypub, admin, issue, misc, notification, organization, package, repository, user). Anything else is rejected, because Gitea grants full access for unknown scope strings. Must not be empty. |
PUBLIC_BASE_URL is also required for OAuth. The Gitea OAuth application's redirect URI is
<PUBLIC_BASE_URL>/oauth/callback.
State
| Variable | Default | Rules |
|---|---|---|
DATA_DIR |
~/.local/state/aegis-gitea-mcp (/var/lib/aegis-mcp in the image) |
~ is expanded. Holds the token store (oauth-tokens.json, mode 0600) and the audit log. |
AUDIT_LOG_PATH |
DATA_DIR/audit.log |
Path of the hash-chained audit log. See audit-logging.md. |
Tool exposure
Everything is enabled by default. These settings only narrow it. A filtered tool is neither listed nor callable.
| Variable | Default | Rules |
|---|---|---|
READ_ONLY |
false |
Expose only read-only (GET) operations. gitea_api_request stays listed but accepts only GET. |
TOOLSETS |
all |
Comma separated domains: admin, repo, issue, pull, release, wiki, org, team, user, actions, hook, package, notification, misc, or all. Unknown domains are rejected. gitea_api_request belongs to misc. |
DISABLED_TOOLS |
empty | Exact tool names to hide, lowercased on load. An unknown name is a startup error that lists the bad names. |
Limits and safety
| Variable | Default | Rules |
|---|---|---|
REQUEST_TIMEOUT_SECONDS |
30 |
1 to 600. Timeout of each Gitea request. |
MAX_TOOL_RESPONSE_ITEMS |
200 |
At least 1. Longer lists are cut and reported in truncated. |
MAX_TOOL_RESPONSE_CHARS |
60000 |
At least 1. Upper bound of one serialized result. |
MAX_BINARY_BYTES |
5242880 |
At least 1. Larger binary bodies fail with payload_too_large. |
SECRET_DETECTION_MODE |
mask |
off, mask or block. See below. |
LOG_LEVEL |
INFO |
DEBUG, INFO, WARNING, ERROR or CRITICAL. Logs go to stderr. |
EXPOSE_ERROR_DETAILS |
false |
When true, the exception class name is added to internal and transport errors. Never a stack trace. Do not enable in production. |
RATE_LIMIT_PER_MINUTE |
120 |
At least 1. Per client on the HTTP MCP endpoint, keyed by a hash of the Authorization header, else the client IP. Excess requests get 429. |
Secret detection: mask replaces secret-like strings in results with a placeholder, block
withholds a whole result that contains one (secret_blocked), off disables pattern matching.
The server's own tokens (Gitea token, bearer token, OAuth client secret, the calling user's
token) and secret values you submit in a request body are always redacted by exact match. The
tools that exist to return a new credential (create token, runner registration token, OAuth
application, deploy token) are exempt from pattern masking so the credential stays usable.
Profiles
Read-only assistant for issues and code:
READ_ONLY=true
TOOLSETS=repo,issue,pull,release,wiki
Everything except instance administration and credentials:
TOOLSETS=repo,issue,pull,release,wiki,org,team,hook,actions,package,notification,misc
DISABLED_TOOLS=gitea_user_create_token
(gitea_user_create_token must be a registered name, see tools.md; the server
refuses to start if a name in DISABLED_TOOLS does not exist.)