docs: rewrite README and docs for the full-access design, generate tool inventory
This commit is contained in:
1 parent
68bd8700dc
commit
7c7cfc05ff
13 files changed
+1693
-1026
No files matched your search
+95
-96
@@ -1,104 +1,103 @@
|
||||
# Configuration
|
||||
|
||||
Copy `.env.example` to `.env` and set values before starting:
|
||||
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](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](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:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
READ_ONLY=true
|
||||
TOOLSETS=repo,issue,pull,release,wiki
|
||||
```
|
||||
|
||||
## Local stdio transport (`aegis-gitea-mcp`)
|
||||
Everything except instance administration and credentials:
|
||||
|
||||
The local single-user server reads only two variables; a local `.env` file is
|
||||
supported via python-dotenv.
|
||||
```bash
|
||||
TOOLSETS=repo,issue,pull,release,wiki,org,team,hook,actions,package,notification,misc
|
||||
DISABLED_TOOLS=gitea_user_create_token
|
||||
```
|
||||
|
||||
| Variable | Required | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `GITEA_URL` | Yes | - | Base URL of your Gitea instance |
|
||||
| `GITEA_TOKEN` | Yes | - | Your Gitea Personal Access Token (the local identity) |
|
||||
| `AUDIT_LOG_PATH` | No | per-user state path | Audit log location (see below) |
|
||||
|
||||
The local adapter forces `OAUTH_MODE=false` and defaults `AUTH_ENABLED=false`
|
||||
(no API-key requirement) — the operator is the trusted PAT owner. `WRITE_MODE`,
|
||||
`WRITE_REPOSITORY_WHITELIST`, `POLICY_FILE_PATH`, `SECRET_DETECTION_MODE`,
|
||||
`RAW_API_ENABLED`, and `RAW_API_ALLOW_SENSITIVE` all behave exactly as on the
|
||||
server.
|
||||
|
||||
**Audit-log fallback.** When `AUDIT_LOG_PATH` is unset, the container default
|
||||
(`/var/log/aegis-mcp/audit.log`) is replaced with a writable per-user path:
|
||||
|
||||
- Windows: `%LOCALAPPDATA%\aegis-gitea-mcp\audit.log`
|
||||
- Linux/macOS: `$XDG_STATE_HOME/aegis-gitea-mcp/audit.log`, else
|
||||
`~/.local/state/aegis-gitea-mcp/audit.log`
|
||||
|
||||
## Raw API dispatch (`gitea_request`)
|
||||
|
||||
| Variable | Required | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `RAW_API_ENABLED` | No | `true` | Enable the generic `gitea_request` escape hatch |
|
||||
| `RAW_API_ALLOW_SENSITIVE` | No | `false` | Opt in to the admin/credential surface (`/admin`, `*tokens*`, `*secrets*`, `*hooks*`, `*keys*`, `applications/oauth2`, runner registration). Admin calls additionally require a verified site administrator. |
|
||||
|
||||
## OAuth/OIDC Settings (Primary)
|
||||
|
||||
| Variable | Required | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `GITEA_URL` | Yes | - | Base URL of your Gitea instance |
|
||||
| `OAUTH_MODE` | No | `false` | Enables OAuth-oriented validation settings |
|
||||
| `GITEA_OAUTH_CLIENT_ID` | Yes when `OAUTH_MODE=true` | - | OAuth client id |
|
||||
| `GITEA_OAUTH_CLIENT_SECRET` | Yes when `OAUTH_MODE=true` | - | OAuth client secret |
|
||||
| `OAUTH_EXPECTED_AUDIENCE` | No | empty | Additional accepted JWT audience beyond the MCP resource and Gitea client id |
|
||||
| `OAUTH_CACHE_TTL_SECONDS` | No | `300` | OIDC discovery/JWKS cache TTL |
|
||||
| `OAUTH_STATE_SECRET` | Yes when `OAUTH_MODE=true` | - | HMAC secret for signed OAuth state wrappers; must be at least 32 characters (e.g. `openssl rand -hex 32`) |
|
||||
| `OAUTH_REDIRECT_ALLOWLIST` | No | empty | Additional allowed redirect URIs for OAuth clients |
|
||||
|
||||
## MCP Server Settings
|
||||
|
||||
| Variable | Required | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `MCP_HOST` | No | `127.0.0.1` | Interface to bind to |
|
||||
| `MCP_PORT` | No | `8080` | Port to listen on |
|
||||
| `PUBLIC_BASE_URL` | No | empty | Public HTTPS base URL advertised in OAuth metadata (recommended behind reverse proxy) |
|
||||
| `ALLOW_INSECURE_BIND` | No | `false` | Explicit opt-in required for `0.0.0.0` bind |
|
||||
| `LOG_LEVEL` | No | `INFO` | `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` |
|
||||
| `STARTUP_VALIDATE_GITEA` | No | `true` | Validate OIDC discovery endpoint at startup |
|
||||
| `DCR_ENABLED` | No | `true` | Enable dynamic client registration at `/register` |
|
||||
| `DCR_STORAGE_PATH` | No | `/var/lib/aegis-mcp/dcr_clients.json` | Persisted OAuth client registry path. Written with owner-only (`0o600`) permissions on POSIX hosts |
|
||||
|
||||
## Security and Limits
|
||||
|
||||
| Variable | Required | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `MAX_AUTH_FAILURES` | No | `5` | Failed auth attempts before rate limiting |
|
||||
| `AUTH_FAILURE_WINDOW` | No | `300` | Window in seconds for auth failure counting |
|
||||
| `RATE_LIMIT_PER_MINUTE` | No | `60` | Per-IP request limit |
|
||||
| `TOKEN_RATE_LIMIT_PER_MINUTE` | No | `120` | Per-token request limit |
|
||||
| `MAX_FILE_SIZE_BYTES` | No | `1048576` | Max file payload returned by read tools |
|
||||
| `MAX_TOOL_RESPONSE_ITEMS` | No | `200` | Max list items in tool responses |
|
||||
| `MAX_TOOL_RESPONSE_CHARS` | No | `20000` | Max chars in text fields |
|
||||
| `REQUEST_TIMEOUT_SECONDS` | No | `30` | Upstream timeout for Gitea calls |
|
||||
| `SECRET_DETECTION_MODE` | No | `mask` | `off`, `mask`, `block` |
|
||||
| `REPO_AUTHZ_CACHE_TTL_SECONDS` | No | `60` | TTL for cached per-user repository permission checks |
|
||||
|
||||
## Write Mode
|
||||
|
||||
| Variable | Required | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `WRITE_MODE` | No | `false` | Enables write tools |
|
||||
| `WRITE_REPOSITORY_WHITELIST` | Required if write mode enabled and allow-all disabled | empty | Comma-separated `owner/repo` allow list |
|
||||
| `WRITE_ALLOW_ALL_TOKEN_REPOS` | No | `false` | Allow all repos accessible by token |
|
||||
|
||||
## Automation
|
||||
|
||||
| Variable | Required | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `AUTOMATION_ENABLED` | No | `false` | Enables automation endpoints |
|
||||
| `AUTOMATION_SCHEDULER_ENABLED` | No | `false` | Enables scheduler loop |
|
||||
| `AUTOMATION_STALE_DAYS` | No | `30` | Age threshold for stale issue checks |
|
||||
|
||||
## Legacy Compatibility Variables
|
||||
|
||||
These are retained for compatibility but not used for OAuth-protected MCP tool execution:
|
||||
|
||||
- `GITEA_TOKEN` — note: in **service-PAT** server mode and in the **local stdio**
|
||||
transport this is required and is the API identity (see above).
|
||||
- `MCP_API_KEYS`
|
||||
- `AUTH_ENABLED`
|
||||
(`gitea_user_create_token` must be a registered name, see [tools.md](tools.md); the server
|
||||
refuses to start if a name in `DISABLED_TOOLS` does not exist.)
|
||||
Reference in new issue
Block a user