docs: retarget setup to Claude connectors
test / test (push) Has been cancelled
lint / lint (push) Has been cancelled
docker / test (pull_request) Successful in 13s
docker / lint (pull_request) Successful in 2m3s
lint / lint (pull_request) Successful in 16s
test / test (pull_request) Successful in 14s
docker / docker-test (pull_request) Successful in 42s
docker / docker-publish (pull_request) Has been skipped

This commit is contained in:
2026-06-13 21:05:21 +02:00
parent 541124e92a
commit b275f5c0c2
10 changed files with 135 additions and 193 deletions
+40 -17
View File
@@ -1,8 +1,8 @@
# AegisGitea-MCP
Security-first MCP server for self-hosted Gitea with per-user OAuth2/OIDC authentication.
Security-first MCP server for self-hosted Gitea with per-user OAuth2/OIDC authentication for Claude, Claude Code, and Cowork.
AegisGitea-MCP exposes MCP tools over HTTP/SSE and validates each user token against Gitea so tool access follows each user's actual repository permissions.
AegisGitea-MCP exposes MCP tools over Streamable HTTP and a legacy SSE alias. Each user authenticates with Gitea through OAuth2/OIDC; repository authorization is checked per user before any service PAT call is allowed.
## Securing MCP with Gitea OAuth
@@ -10,7 +10,7 @@ AegisGitea-MCP exposes MCP tools over HTTP/SSE and validates each user token aga
1. Open `https://git.hiddenden.cafe/user/settings/applications` (or admin application settings).
2. Create an OAuth2 app.
3. Set redirect URI to the ChatGPT callback URL shown after creating a New App.
3. Set the redirect URI to this MCP server's callback: `https://<your-mcp-domain>/oauth/callback`.
4. Save the app and keep:
- `Client ID`
- `Client Secret`
@@ -32,19 +32,39 @@ GITEA_URL=https://git.hiddenden.cafe
OAUTH_MODE=true
GITEA_OAUTH_CLIENT_ID=<your-client-id>
GITEA_OAUTH_CLIENT_SECRET=<your-client-secret>
OAUTH_EXPECTED_AUDIENCE=<optional; defaults to client id>
PUBLIC_BASE_URL=https://<your-mcp-domain>
OAUTH_STATE_SECRET=<random-32-byte-minimum-secret>
```
### 3) Configure ChatGPT New App
`GITEA_TOKEN` is optional in OAuth mode. Without it, Gitea REST calls use the user's OAuth access token directly, so Gitea enforces permissions on every API call. With it, the token acts as a service PAT for API execution, but the MCP server first checks the requesting user's permission on the target repository through Gitea and denies the call if the user lacks the required read/write permission.
In ChatGPT New App:
### 3) Configure Claude, Claude Code, or Cowork
- MCP server URL: `https://<your-mcp-domain>/mcp/sse`
Claude's hosted, desktop, mobile, Claude Code, and Cowork surfaces share the same remote MCP connector infrastructure. There is no Claude-specific server code path.
In claude.ai:
1. Open **Settings > Connectors**.
2. Choose **Add custom connector**.
3. Paste `https://<your-mcp-domain>/mcp`.
4. Complete the OAuth consent flow. Dynamic Client Registration (`/register`) handles Claude client registration.
In Claude Code:
```bash
claude mcp add --transport http aegis-gitea https://<your-mcp-domain>/mcp
```
Cowork uses the same connector model and MCP URL.
Manual OAuth client configuration remains available for clients that do not use DCR:
- MCP server URL: `https://<your-mcp-domain>/mcp`
- Authentication: OAuth
- OAuth client ID: Gitea OAuth app client ID
- OAuth client secret: Gitea OAuth app client secret
- OAuth client ID: the client id returned by `/register` or your preconfigured client id
- OAuth client secret: only for confidential clients
After creation, copy the ChatGPT callback URL and add it to the Gitea OAuth app redirect URIs.
Hosted Claude callbacks are allowed by default: `https://claude.ai/api/mcp/auth_callback` and `https://claude.com/api/mcp/auth_callback`. Loopback redirects for Claude Code local development are allowed for `http://127.0.0.1:*` and `http://localhost:*`.
### 4) OAuth-protected MCP behavior
@@ -56,7 +76,7 @@ Example response:
```json
{
"resource": "https://git.hiddenden.cafe",
"resource": "https://gitea-mcp.hiddenden.cafe",
"authorization_servers": [
"https://gitea-mcp.hiddenden.cafe",
"https://git.hiddenden.cafe"
@@ -76,14 +96,16 @@ WWW-Authenticate: Bearer resource_metadata="https://<mcp-host>/.well-known/oauth
## Architecture
```text
ChatGPT App
Claude / Claude Code / Cowork
-> Authorization Code Flow
-> Gitea OAuth2/OIDC (issuer: https://git.hiddenden.cafe)
-> Access token
-> MCP Server (/mcp/sse, /mcp/tool/call)
-> MCP Server (/mcp, /mcp/sse, /mcp/tool/call)
-> OIDC discovery + JWKS cache
-> Scope enforcement (read:repository / write:repository)
-> Per-request Gitea API calls with Authorization: Bearer <user token>
-> Policy allow/deny
-> If GITEA_TOKEN is set: check Gitea collaborator permission for <user, repo>
-> Gitea API call with either the user token or the service PAT after authz
```
## Example curl
@@ -108,7 +130,7 @@ Authenticated tool call:
curl -s https://<mcp-host>/mcp/tool/call \
-H "Authorization: Bearer <user_access_token>" \
-H "Content-Type: application/json" \
-d '{"tool":"list_repositories","arguments":{}}'
-d '{"tool":"get_repository_info","arguments":{"owner":"acme","repo":"demo"}}'
```
## Threat model
@@ -120,8 +142,9 @@ curl -s https://<mcp-host>/mcp/tool/call \
- URLs leak via logs, proxies, browser history, and referers.
- bearer tokens must be sent in `Authorization` headers only.
- Per-user OAuth reduces lateral access:
- each call runs as the signed-in user.
- users only see repositories they already have permission for in Gitea.
- identity comes from Gitea OIDC/JWKS or userinfo validation.
- without `GITEA_TOKEN`, API calls use the user's token and Gitea enforces permissions.
- with `GITEA_TOKEN`, every repository-targeted call first checks the user's Gitea permission and fails closed if the check cannot be made.
## CI/CD
+5 -2
View File
@@ -12,14 +12,17 @@
- Returns OAuth protected resource metadata used by MCP clients.
- `GET /.well-known/oauth-authorization-server`
- Returns OAuth authorization server metadata.
- `POST /register`
- Registers an OAuth client and persists the client metadata.
- `POST /oauth/token`
- Proxies OAuth authorization-code token exchange to Gitea.
## MCP Endpoints
- `GET /mcp/tools`: list tool definitions.
- `POST /mcp/tool/call`: execute a tool.
- `GET /mcp/sse` and `POST /mcp/sse`: MCP SSE transport.
- `GET /mcp` and `POST /mcp`: streamable HTTP transport.
- `GET /mcp/sse` and `POST /mcp/sse`: MCP SSE transport alias.
- `POST /mcp/tool/call`: direct tool-call endpoint.
Authentication requirements:
+21 -14
View File
@@ -2,20 +2,22 @@
## Overview
AegisGitea MCP is a Python 3.10+ application built on **FastAPI**. It acts as a bridge between an AI client (such as ChatGPT) and a self-hosted Gitea instance, implementing the [Model Context Protocol (MCP)](https://modelcontextprotocol.io).
AegisGitea MCP is a Python 3.10+ application built on **FastAPI**. It acts as a bridge between an AI client (such as Claude, Claude Code, or Cowork) and a self-hosted Gitea instance, implementing the [Model Context Protocol (MCP)](https://modelcontextprotocol.io).
```
AI Client (ChatGPT)
AI Client (Claude / Claude Code / Cowork)
│ HTTP (Authorization: Bearer <key>)
┌────────────────────────────────────────────┐
│ FastAPI Server │
│ server.py │
│ - Route: GET/POST /mcp │
│ - Route: POST /mcp/tool/call │
│ - Route: GET /mcp/tools │
│ - Route: GET /health │
│ - SSE support (GET/POST /mcp/sse)
│ - Streamable HTTP transport
│ - Legacy SSE alias (GET/POST /mcp/sse) │
└───────┬───────────────────┬────────────────┘
│ │
┌────▼────┐ ┌────▼──────────────┐
@@ -91,7 +93,7 @@ Key methods:
| Method | Gitea endpoint |
|---|---|
| `get_current_user()` | `GET /api/v1/user` |
| `list_repositories()` | `GET /api/v1/repos/search` |
| `list_repositories()` | `GET /api/v1/user/repos` |
| `get_repository()` | `GET /api/v1/repos/{owner}/{repo}` |
| `get_file_contents()` | `GET /api/v1/repos/{owner}/{repo}/contents/{path}` |
| `get_tree()` | `GET /api/v1/repos/{owner}/{repo}/git/trees/{ref}` |
@@ -134,7 +136,7 @@ All handlers return a plain string. `server.py` wraps this in an `MCPToolCallRes
2. FastAPI routes the request to the tool-call handler in server.py
3. auth.validate_api_key() checks the Authorization header
3. OAuth middleware validates the Bearer token via Gitea OIDC/JWKS or userinfo
├── Fail → AuditLogger.log_access_denied() → HTTP 401 / 429
└── Pass → continue
@@ -142,27 +144,32 @@ All handlers return a plain string. `server.py` wraps this in an `MCPToolCallRes
5. Tool dispatcher looks up the tool by name (mcp_protocol.get_tool_by_name)
6. Tool handler function (tools/repository.py) is called
6. Policy engine checks read/write mode and repository/path policy
7. GiteaClient makes an async HTTP call to the Gitea API
7. If GITEA_TOKEN is configured, service-PAT authz checks
GET /repos/{owner}/{repo}/collaborators/{user}/permission
8. Result (or error) is returned to server.py
8. Tool handler function (tools/repository.py) is called
9. AuditLogger.log_tool_invocation(status="success" | "error")
9. GiteaClient makes an async HTTP call to the Gitea API
10. MCPToolCallResponse is returned to the client
10. Result (or error) is returned to server.py
11. AuditLogger.log_tool_invocation(status="success" | "error")
12. MCPToolCallResponse is returned to the client
```
---
## Key Design Decisions
**Read-only by design.** The MCP tools only read data from Gitea. No write operations are implemented.
**Read by default, writes opt-in.** Read tools are available by default. Write-capable tools require `WRITE_MODE=true`, repository write policy/whitelist approval, and `write:repository` authorization.
**Gitea controls access.** The server does not maintain its own repository ACL. The Gitea bot user's permissions are the source of truth. If the bot cannot access a repo, the server cannot either.
**Gitea controls repository access.** Without `GITEA_TOKEN`, Gitea enforces repository permissions on API calls made with the user's token. With `GITEA_TOKEN`, the service PAT can only execute after the server verifies the requesting user's actual repository permission through Gitea and writes an audit denial if the check fails.
**Public tool discovery.** `GET /mcp/tools` requires no authentication so that ChatGPT's plugin system can discover the available tools without credentials. All other endpoints require authentication.
**Public tool discovery.** `GET /mcp/tools` requires no authentication so that MCP clients can discover the available tools without credentials. All other endpoints require authentication.
**Stateless server.** No database or persistent state beyond the audit log file. Rate limit counters are in-memory and reset on restart.
**Minimal persisted state.** The audit log is persisted for tamper-evident review. Dynamic OAuth client registrations are persisted when DCR is enabled. Rate limit counters and short-lived authz caches are in-memory and reset on restart.
**Async throughout.** FastAPI + `httpx.AsyncClient` means all Gitea API calls are non-blocking, allowing the server to handle concurrent requests efficiently.
+6 -1
View File
@@ -14,8 +14,10 @@ cp .env.example .env
| `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 | Expected JWT audience; defaults to client id |
| `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 |
| `OAUTH_REDIRECT_ALLOWLIST` | No | empty | Additional allowed redirect URIs for OAuth clients |
## MCP Server Settings
@@ -27,6 +29,8 @@ cp .env.example .env
| `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 |
## Security and Limits
@@ -41,6 +45,7 @@ cp .env.example .env
| `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
+38 -25
View File
@@ -4,7 +4,7 @@
- Python 3.10 or higher
- A running Gitea instance
- A Gitea bot user with access to the repositories you want to expose
- A Gitea OAuth2 application for this MCP server
- `make` (optional but recommended)
## 1. Install
@@ -31,14 +31,12 @@ pip install -e .
# dev: pip install -e ".[dev]"
```
## 2. Create a Gitea Bot User
## 2. Create a Gitea OAuth2 Application
1. In your Gitea instance, create a dedicated user (e.g. `ai-bot`).
2. Grant that user **read access** to any repositories the AI should be able to see.
3. Generate an API token for the bot user:
- Go to **User Settings** > **Applications** > **Generate Token**
- Give it a descriptive name (e.g. `aegis-mcp-token`)
- Copy the token — you will not be able to view it again.
1. In Gitea, open **User Settings > Applications**.
2. Create an OAuth2 application for AegisGitea-MCP.
3. Set the redirect URI to `https://<host>/oauth/callback`.
4. Copy the client ID and client secret.
## 3. Configure
@@ -48,27 +46,31 @@ Copy the example environment file and fill in your values:
cp .env.example .env
```
Minimum required settings in `.env`:
Minimum OAuth settings in `.env`:
```env
GITEA_URL=https://gitea.example.com
GITEA_TOKEN=<your-bot-user-token>
AUTH_ENABLED=true
MCP_API_KEYS=<your-generated-api-key>
OAUTH_MODE=true
GITEA_OAUTH_CLIENT_ID=<your-gitea-oauth-client-id>
GITEA_OAUTH_CLIENT_SECRET=<your-gitea-oauth-client-secret>
PUBLIC_BASE_URL=https://<host>
OAUTH_STATE_SECRET=<random-32-byte-minimum-secret>
```
`GITEA_TOKEN` is optional. If it is set, use a narrowly scoped service PAT and only grant it repository access you are prepared to expose after per-user authorization checks. If it is not set, Gitea REST calls use the authenticated user's OAuth token directly.
See [Configuration](configuration.md) for the full list of settings.
## 4. Generate an API Key
## 4. Optional Standard API Key Mode
The MCP server requires clients to authenticate with a bearer token. Generate one:
For non-OAuth deployments, configure `GITEA_TOKEN` and `MCP_API_KEYS`. Generate an API key with:
```bash
make generate-key
# or: python scripts/generate_api_key.py
```
Copy the printed key into `MCP_API_KEYS` in your `.env` file.
Copy the printed key into `MCP_API_KEYS` in your `.env` file and set `OAUTH_MODE=false`.
## 5. Run
@@ -88,24 +90,35 @@ curl http://localhost:8080/health
## 6. Connect an AI Client
### ChatGPT
### Claude
Use this single URL in the ChatGPT MCP connector:
In claude.ai, open **Settings > Connectors > Add custom connector** and paste:
```
http://<host>:8080/mcp/sse?api_key=<your-api-key>
https://<host>/mcp
```
ChatGPT uses the SSE transport: it opens a persistent GET stream on this URL and sends tool call messages back via POST to the same URL. The `api_key` query parameter is the recommended method because the ChatGPT interface does not support setting custom request headers.
Claude discovers OAuth metadata, registers through `/register`, and uses PKCE S256 automatically.
### Other MCP clients
### Claude Code
Clients that support custom headers can use:
```bash
claude mcp add --transport http aegis-gitea https://<host>/mcp
```
- **SSE URL:** `http://<host>:8080/mcp/sse`
- **Tool discovery URL:** `http://<host>:8080/mcp/tools` (no auth required)
- **Tool call URL:** `http://<host>:8080/mcp/tool/call`
- **Authentication:** `Authorization: Bearer <your-api-key>`
Claude Code uses the same remote MCP and OAuth metadata. Local development loopback callbacks are allowed by default.
### Cowork
Cowork uses the same connector infrastructure and MCP URL as Claude.
### SSE compatibility
If your client still expects SSE transport, use:
- **SSE URL:** `https://<host>/mcp/sse`
- **Tool discovery URL:** `https://<host>/mcp/tools` (no auth required)
- **Tool call URL:** `https://<host>/mcp/tool/call`
For a production deployment behind a reverse proxy, see [Deployment](deployment.md).
+1 -1
View File
@@ -4,7 +4,7 @@ AegisGitea MCP is a security-first [Model Context Protocol (MCP)](https://modelc
## Overview
AegisGitea MCP acts as a secure bridge between AI assistants (such as ChatGPT) and your Gitea instance. It exposes a limited set of read-only tools that allow an AI to browse repositories and read file contents, while enforcing strict authentication, rate limiting, and comprehensive audit logging.
AegisGitea MCP acts as a secure bridge between AI assistants (such as Claude, Claude Code, or Cowork) and your Gitea instance. It exposes read tools and opt-in write tools while enforcing per-user OAuth, repository authorization, policy checks, rate limiting, and tamper-evident audit logging.
**Version:** 0.1.0 (Alpha)
**License:** MIT
+15 -14
View File
@@ -1,15 +1,15 @@
# Troubleshooting
## "Internal server error (-32603)" from ChatGPT
## "Internal server error (-32603)" from Claude
**Symptom:** ChatGPT shows `Internal server error` with JSON-RPC error code `-32603` when trying to use Gitea tools.
**Symptom:** Claude shows `Internal server error` with JSON-RPC error code `-32603` when trying to use Gitea tools.
**Cause:** The OAuth token stored by ChatGPT was issued without Gitea API scopes (e.g. `read:repository`). This happens when the initial authorization request didn't include the correct `scope` parameter. The token passes OIDC validation (openid/profile/email) but gets **403 Forbidden** from Gitea's REST API.
**Cause:** In user-token mode, the OAuth token stored by the client may have been issued without Gitea API scopes (e.g. `read:repository`). In service-PAT mode, the call may fail because the authenticated user does not have the required repository permission or the permission probe cannot be completed.
**Fix:**
1. In Gitea: Go to **Settings > Applications > Authorized OAuth2 Applications** and revoke the MCP application.
2. In ChatGPT: Go to **Settings > Connected apps** and disconnect the Gitea integration.
3. Re-authorize: Use the ChatGPT integration again. It will trigger a fresh OAuth flow with the correct scopes (`read:repository`).
2. In Claude: disconnect the MCP server and authenticate again.
3. Re-authorize: Use the MCP connector again. It will trigger a fresh OAuth flow. For repository-targeted calls in service-PAT mode, also verify the signed-in Gitea user has read/write access to the target repository.
**Verification:** Check the server logs for `oauth_auth_summary`. A working token shows:
```
@@ -24,19 +24,19 @@ oauth_token_lacks_api_scope: status=403 login=alice
**Symptom:** Tool calls return 403 with a message about re-authorizing.
**Cause:** Same root cause as above — the OAuth token doesn't have the required Gitea API scopes. The middleware's API scope probe detected this and returned a clear error instead of letting it fail deep in the tool handler.
**Cause:** The OAuth token does not have the required API scope in user-token mode, or the per-user repository permission check denied the request in service-PAT mode.
**Fix:** Same as above — revoke and re-authorize.
**Fix:** Revoke and re-authorize if the token lacks API scope. If the error mentions repository permission, grant the signed-in Gitea user the required repository access or use a repository they can access.
## ChatGPT caches stale tokens
## Claude caches stale tokens
**Symptom:** After fixing the OAuth configuration, ChatGPT still sends the old token.
**Symptom:** After fixing the OAuth configuration, Claude still sends the old token.
**Cause:** ChatGPT caches access tokens and doesn't automatically re-authenticate when the server configuration changes.
**Cause:** The client caches access tokens and doesn't automatically re-authenticate when the server configuration changes.
**Fix:**
1. In ChatGPT: **Settings > Connected apps** > disconnect the integration.
2. Start a new conversation and use the integration again this forces a fresh OAuth flow.
1. Disconnect the server in the client.
2. Start a new conversation and use the integration again - this forces a fresh OAuth flow.
## How OAuth scopes work with Gitea
@@ -48,9 +48,9 @@ Gitea's OAuth2/OIDC implementation uses **granular scopes** for API access:
| `write:repository` | Create/edit issues, PRs, comments, files |
| `openid` | OIDC identity (login, email) |
When an OAuth application requests authorization, the `scope` parameter in the authorize URL determines what permissions the resulting token has. If only OIDC scopes are requested (e.g. `openid profile email`), the token will validate via the userinfo endpoint but will be rejected by Gitea's REST API with 403.
When an OAuth application requests authorization, the `scope` parameter in the authorize URL determines what permissions the resulting token has. If only OIDC scopes are requested (e.g. `openid profile email`), the token can establish identity but may not be usable for direct Gitea REST calls. When `GITEA_TOKEN` is configured, the server uses OIDC for identity and checks the user's repository permission before using the service PAT.
The MCP server's `openapi-gpt.yaml` file controls which scopes ChatGPT requests. Ensure it includes:
The MCP server's OAuth metadata controls which scopes the client requests. Ensure it includes:
```yaml
scopes:
read:repository: "Read access to Gitea repositories"
@@ -73,3 +73,4 @@ Every authenticated request emits a structured log line:
- `api_probe=fail:403` — token lacks API scopes, request rejected with re-auth guidance
- `api_probe=skip:cached` — previous probe passed, cached result used
- `api_probe=skip:error` — network error during probe, request allowed to proceed
- `repository_permission_denied` in the audit log — the user lacks required read/write permission for a service-PAT call
-110
View File
@@ -1,110 +0,0 @@
openapi: "3.1.0"
info:
title: AegisGitea MCP
description: >
AI access to your self-hosted Gitea instance via the AegisGitea MCP server.
Each user authenticates with their own Gitea account via OAuth2.
version: "0.2.0"
servers:
- url: "https://YOUR_MCP_SERVER_DOMAIN"
description: >
Replace YOUR_MCP_SERVER_DOMAIN with the public hostname of your AegisGitea-MCP instance.
components:
securitySchemes:
gitea_oauth:
type: oauth2
flows:
authorizationCode:
# Replace YOUR_GITEA_DOMAIN with your self-hosted Gitea instance hostname.
authorizationUrl: "https://YOUR_GITEA_DOMAIN/login/oauth/authorize"
# The token URL must point to the MCP server's OAuth proxy endpoint.
tokenUrl: "https://YOUR_MCP_SERVER_DOMAIN/oauth/token"
scopes:
read:repository: "Read access to Gitea repositories"
write:repository: "Write access to Gitea repositories"
security:
- gitea_oauth:
- read:repository
paths:
/mcp/tools:
get:
operationId: listTools
summary: List available MCP tools
description: Returns all tools available on this MCP server. Public endpoint, no authentication required.
security: []
responses:
"200":
description: List of available MCP tools
content:
application/json:
schema:
type: object
properties:
tools:
type: array
items:
type: object
properties:
name:
type: string
description:
type: string
/mcp/tool/call:
post:
operationId: callTool
summary: Execute an MCP tool
description: >
Execute a named MCP tool with the provided arguments.
The authenticated user's Gitea token is used for all Gitea API calls,
so only repositories and data accessible to the user will be returned.
security:
- gitea_oauth:
- read:repository
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- tool
- arguments
properties:
tool:
type: string
description: Name of the MCP tool to execute
example: list_repositories
arguments:
type: object
description: Tool-specific arguments
example: {}
correlation_id:
type: string
description: Optional correlation ID for request tracing
responses:
"200":
description: Tool execution result
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
result:
type: object
correlation_id:
type: string
"401":
description: Authentication required or token invalid
"403":
description: Policy denied the request
"404":
description: Tool not found
"429":
description: Rate limit exceeded
+4 -4
View File
@@ -19,7 +19,7 @@ def main() -> None:
print()
# Get optional description
description = input("Enter description for this key (e.g., 'ChatGPT Business'): ").strip()
description = input("Enter description for this key (e.g., 'Claude Code'): ").strip()
if not description:
description = "Generated key"
@@ -56,15 +56,15 @@ def main() -> None:
print()
print(" docker-compose restart aegis-mcp")
print()
print("3. Configure ChatGPT Business:")
print("3. Configure your MCP client:")
print()
print(" - Go to ChatGPT Settings > MCP Servers")
print(" - Add the server in your MCP client settings")
print(" - Add custom header:")
print(f" Authorization: Bearer {api_key}")
print()
print("4. Test the connection:")
print()
print(" Ask ChatGPT: 'List my Gitea repositories'")
print(" Ask the client: 'List my Gitea repositories'")
print()
print("-" * 70)
print()
+5 -5
View File
@@ -92,7 +92,7 @@ def main() -> None:
key_list.append(new_key)
new_keys_str = ",".join(key_list)
print("\n✓ New key will be added (total: {} keys)".format(len(key_list)))
print("\n⚠️ IMPORTANT: Remove old keys manually after updating ChatGPT config")
print("\n⚠️ IMPORTANT: Remove old keys manually after updating the client config")
elif choice == "1":
# Replace with only new key
new_keys_str = new_key
@@ -129,19 +129,19 @@ def main() -> None:
print()
print(" docker-compose restart aegis-mcp")
print()
print("2. Update ChatGPT Business configuration:")
print("2. Update your MCP client configuration:")
print()
print(" - Go to ChatGPT Settings > MCP Servers")
print(" - Update the MCP server entry in your client")
print(" - Update Authorization header:")
print(f" Authorization: Bearer {new_key}")
print()
print("3. Test the connection:")
print()
print(" Ask ChatGPT: 'List my Gitea repositories'")
print(" Ask the client: 'List my Gitea repositories'")
print()
print("4. If using grace period (option 2):")
print()
print(" - After confirming ChatGPT works with new key")
print(" - After confirming the client works with the new key")
print(" - Manually remove old keys from .env")
print(" - Restart server again")
print()