84 lines
6.8 KiB
Markdown
84 lines
6.8 KiB
Markdown
# Troubleshooting
|
|
|
|
Start with the result of the failing call: errors carry `error.status`, `error.kind` and
|
|
Gitea's sanitized message, and the audit log has one event per call (see
|
|
[audit-logging.md](audit-logging.md)).
|
|
|
|
## The server does not start
|
|
|
|
| Message or exit | Cause and fix |
|
|
|---|---|
|
|
| Exit code 2, "GITEA_TOKEN" required (stdio) | stdio needs `GITEA_TOKEN`. Put it in the client's `env` block, or in an env file passed with `--env-file` (or `AEGIS_ENV_FILE`). A `.env` in the working directory counts only when it is a regular file you own with mode 0600. |
|
|
| Warning "ignoring ./.env: ..." | The working directory's `.env` is a symlink, owned by someone else or accessible to group or others, so its settings are not loaded. Run `chmod 600 .env`, or pass `--env-file PATH`. See "Which env file is read" in [configuration.md](configuration.md). |
|
|
| Exit code 2, "env file ... does not exist" | The file named by `--env-file` or `AEGIS_ENV_FILE` is missing or not a regular file. |
|
|
| Exit code 2, refuses a non-loopback bind | `MCP_HOST` is not loopback and there is no `MCP_BEARER_TOKEN` or complete OAuth setup. Set one of them, or bind `127.0.0.1` behind a reverse proxy. |
|
|
| Exit code 2, lists OAuth settings | `OAUTH_ENABLED=true` needs `GITEA_OAUTH_CLIENT_ID`, `GITEA_OAUTH_CLIENT_SECRET`, `TOKEN_ENCRYPTION_KEY` and `PUBLIC_BASE_URL`. |
|
|
| Exit code 2, "cannot decrypt .../oauth-store.json" | `TOKEN_ENCRYPTION_KEY` differs from the key the store was written with (or the file is damaged). The server does not wipe it. Restore the original key, or move `DATA_DIR/oauth-store.json` away to start over (signs every OAuth user out). |
|
|
| Exit code 2, "owned by another user" or "writable by group or others" (OAuth) | `DATA_DIR` must belong to the user the server runs as and not be group or world writable. Fix the owner or `chmod 700`. |
|
|
| Validation error naming a setting | See the rules in [configuration.md](configuration.md): URLs must be http(s) without credentials, `PUBLIC_BASE_URL` must be https, secrets need 32 characters, `OAUTH_SCOPES` accepts only granular scopes. |
|
|
| Startup error listing tool names | `DISABLED_TOOLS` contains names that are not registered. Check [tools.md](tools.md). |
|
|
|
|
## stdio client shows nothing or breaks
|
|
|
|
stdout carries only JSON-RPC. If a wrapper script prints to stdout before the server starts, the
|
|
client fails to parse the stream. Logs go to stderr; look at the client's MCP server log.
|
|
`uvx` needs access to the package index that hosts `aegis-gitea-mcp`, see
|
|
[packaging.md](packaging.md).
|
|
|
|
## Tool calls fail
|
|
|
|
| `kind` | Meaning |
|
|
|---|---|
|
|
| `unauthorized` (401) | Gitea rejected the token: wrong, expired or revoked. In OAuth mode the user signs in again. |
|
|
| `forbidden` (403) | The token or the user lacks the scope or permission. Admin tools return this for non-admins. Widen the token scopes (see "Token scopes" in the [README](../README.md)) or change the user's rights in Gitea. Sudo needs a site-admin token. |
|
|
| `not_found` (404) | The object does not exist, or Gitea hides it from this identity. Also returned for endpoints the Gitea version lacks. |
|
|
| `validation_failed` (422), `bad_request` (400) | Gitea rejected the values. The message says which. |
|
|
| `invalid_argument` | The arguments do not match the tool schema (missing, wrong type, extra property, bad owner or repository name). The message gives the path, not the value. |
|
|
| `timeout`, `upstream_unreachable` | Gitea did not answer within `REQUEST_TIMEOUT_SECONDS`, or the connection failed. Check `GITEA_URL` from the server's host (DNS, TLS, firewall). |
|
|
| `redirect` | Gitea answered with a redirect, which is never followed. Use the final URL (for example https) as `GITEA_URL`. |
|
|
| `payload_too_large` | The response is above `MAX_BINARY_BYTES`. Raise it or fetch a smaller object. |
|
|
| `secret_blocked` | `SECRET_DETECTION_MODE=block` withheld a result containing secret-like content. Use `mask` if that is acceptable. |
|
|
| `audit_unavailable` | The audit log could not be opened, so the call was refused before it reached Gitea. Fix the permissions of `AUDIT_LOG_PATH` (or `DATA_DIR`) and restart. |
|
|
| `rate_limited` (429) | Gitea or this server's `RATE_LIMIT_PER_MINUTE` limit. |
|
|
|
|
A result with a `truncated` object was cut to `MAX_TOOL_RESPONSE_ITEMS` or
|
|
`MAX_TOOL_RESPONSE_CHARS`. Use `page` and `limit` on paginated tools to walk through it.
|
|
|
|
A tool the client cannot see is probably filtered by `TOOLSETS`, `READ_ONLY` or
|
|
`DISABLED_TOOLS`. Calling a filtered or unknown tool is a protocol error.
|
|
|
|
## HTTP problems
|
|
|
|
- `GET /health` returns 503 `degraded`: the server cannot reach Gitea (the probe is cached for
|
|
10 seconds). Fix connectivity from the server's host.
|
|
- 401 on `/mcp`: no or wrong bearer token, and no valid OAuth token. The response has a
|
|
`WWW-Authenticate` header that points clients to the OAuth metadata.
|
|
- Request rejected with an invalid Host (421): the name you used is not allowed. Add it to
|
|
`ALLOWED_HOSTS` or set `PUBLIC_BASE_URL`. With a non-loopback `MCP_HOST` and neither variable
|
|
the server prints a warning at startup that says so.
|
|
- 429: the client exceeded `RATE_LIMIT_PER_MINUTE`. If every client seems to share one limit,
|
|
the proxy address is not in `FORWARDED_ALLOW_IPS`, so all requests look like they come from
|
|
the proxy.
|
|
- The server exits with code 2 and "cannot open the audit log": the audit file or its directory
|
|
is not writable. Fix the permissions, or point `AUDIT_LOG_PATH` or `DATA_DIR` at a writable
|
|
location (in Docker, check the volume ownership). The server never runs without an audit log.
|
|
- Responses arrive in one chunk or time out behind nginx: set `proxy_buffering off;`.
|
|
|
|
## OAuth sign-in
|
|
|
|
- The client reports that dynamic client registration is unsupported: OAuth is off. Set
|
|
`OAUTH_ENABLED=true` and the settings that go with it.
|
|
- Gitea shows a redirect URI error: the OAuth application's redirect URI must be exactly
|
|
`<PUBLIC_BASE_URL>/oauth/callback`. Re-run `setup --public-base-url ...` or fix it in Gitea.
|
|
- Signed in, but admin tools return 403: the user is not a site administrator. That is intended.
|
|
- Users are asked to sign in again after a restart: the `DATA_DIR` volume changed or was not
|
|
persistent (a changed `TOKEN_ENCRYPTION_KEY` stops startup instead, see above). Keep the key
|
|
stable and the volume persistent.
|
|
- The sign-in page says the request is invalid or expired: the consent page lives 10 minutes
|
|
and a form is single use. Start the sign-in again from the client. Registration or sign-in
|
|
refused with "too many": one client address may hold 20 pending sign-ins and register 20
|
|
clients per hour.
|
|
- After fixing OAuth settings the client still fails: some clients cache tokens. Disconnect the
|
|
server in the client and connect again, which starts a fresh flow. Users can also revoke the
|
|
application under Settings, Applications, Authorized OAuth2 Applications in Gitea.
|