feat: harden gateway with policy engine, secure tools, and governance docs

This commit is contained in:
2026-02-14 16:05:56 +01:00
parent e17d34e6d7
commit 5969892af3
55 changed files with 4711 additions and 1587 deletions

View File

@@ -1,255 +1,61 @@
# API Reference
## HTTP Endpoints
### `GET /`
Returns basic server information. No authentication required.
**Response**
```json
{
"name": "AegisGitea MCP",
"version": "0.1.0",
"status": "running"
}
```
---
### `GET /health`
Health check endpoint. No authentication required.
**Response**
```json
{
"status": "healthy",
"gitea_connected": true
}
```
Returns HTTP 200 when healthy. Returns HTTP 503 when Gitea is unreachable.
---
### `GET /mcp/tools`
Returns the list of available MCP tools. No authentication required (needed for ChatGPT tool discovery).
**Response**
```json
{
"tools": [
{
"name": "list_repositories",
"description": "...",
"inputSchema": { ... }
}
]
}
```
---
### `POST /mcp/tool/call`
Executes an MCP tool. **Authentication required.**
**Request headers**
```
Authorization: Bearer <api-key>
Content-Type: application/json
```
**Request body**
```json
{
"name": "<tool-name>",
"arguments": { ... }
}
```
**Response**
```json
{
"content": [
{
"type": "text",
"text": "..."
}
],
"isError": false
}
```
On error, `isError` is `true` and `text` contains the error message.
---
### `GET /mcp/sse`
Server-Sent Events stream endpoint. Authentication required. Used for streaming MCP sessions.
---
### `POST /mcp/sse`
Sends a client message over an active SSE session. Authentication required.
---
## Authentication
All authenticated endpoints require a bearer token:
```
Authorization: Bearer <api-key>
```
Alternatively, the key can be passed as a query parameter (useful for tools that do not support custom headers):
```
GET /mcp/tool/call?api_key=<api-key>
```
---
## MCP Tools
### `list_repositories`
Lists all Gitea repositories accessible to the bot user.
**Arguments:** none
**Example response text**
```
Found 3 repositories:
1. myorg/backend - Backend API service [Python] ★ 42
2. myorg/frontend - React frontend [TypeScript] ★ 18
3. myorg/infra - Infrastructure as code [HCL] ★ 5
```
---
### `get_repository_info`
Returns metadata for a single repository.
**Arguments**
| Name | Type | Required | Description |
|---|---|---|---|
| `owner` | string | Yes | Repository owner (user or organisation) |
| `repo` | string | Yes | Repository name |
**Example response text**
```
Repository: myorg/backend
Description: Backend API service
Language: Python
Stars: 42
Forks: 3
Default branch: main
Private: false
URL: https://gitea.example.com/myorg/backend
```
---
### `get_file_tree`
Returns the file and directory structure of a repository.
**Arguments**
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| `owner` | string | Yes | — | Repository owner |
| `repo` | string | Yes | — | Repository name |
| `ref` | string | No | default branch | Branch, tag, or commit SHA |
| `recursive` | boolean | No | `false` | Recursively list all subdirectories |
> **Note:** Recursive mode is disabled by default to limit response size. Enable with care on large repositories.
**Example response text**
```
File tree for myorg/backend (ref: main):
src/
src/main.py
src/config.py
tests/
tests/test_main.py
README.md
requirements.txt
```
---
### `get_file_contents`
Returns the contents of a single file.
**Arguments**
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| `owner` | string | Yes | — | Repository owner |
| `repo` | string | Yes | — | Repository name |
| `filepath` | string | Yes | — | Path to the file within the repository |
| `ref` | string | No | default branch | Branch, tag, or commit SHA |
**Limits**
- Files larger than `MAX_FILE_SIZE_BYTES` (default 1 MB) are rejected.
- Binary files that cannot be decoded as UTF-8 are returned as raw base64.
**Example response text**
```
Contents of myorg/backend/src/main.py (ref: main):
import fastapi
...
```
---
## Error Responses
All errors follow this structure:
```json
{
"content": [
{
"type": "text",
"text": "Error: <description>"
}
],
"isError": true
}
```
Common error scenarios:
| Scenario | HTTP Status | `isError` |
|---|---|---|
| Missing or invalid API key | 401 | — (rejected before tool runs) |
| Rate limited IP address | 429 | — |
| Tool not found | 404 | — |
| Repository not found in Gitea | 200 | `true` |
| File too large | 200 | `true` |
| Gitea API unavailable | 200 | `true` |
## Endpoints
- `GET /`: server metadata.
- `GET /health`: health probe.
- `GET /metrics`: Prometheus metrics (when enabled).
- `POST /automation/webhook`: ingest policy-controlled webhook events.
- `POST /automation/jobs/run`: run policy-controlled automation jobs.
- `GET /mcp/tools`: list tool definitions.
- `POST /mcp/tool/call`: execute a tool (`Authorization: Bearer <api-key>` required except in explicitly disabled auth mode).
- `GET /mcp/sse` and `POST /mcp/sse`: MCP SSE transport.
## Automation Jobs
`POST /automation/jobs/run` supports:
- `dependency_hygiene_scan` (read-only scaffold).
- `stale_issue_detection` (read-only issue age analysis).
- `auto_issue_creation` (write-mode + whitelist + policy required).
## Read Tools
- `list_repositories`.
- `get_repository_info` (`owner`, `repo`).
- `get_file_tree` (`owner`, `repo`, optional `ref`, `recursive`).
- `get_file_contents` (`owner`, `repo`, `filepath`, optional `ref`).
- `search_code` (`owner`, `repo`, `query`, optional `ref`, `page`, `limit`).
- `list_commits` (`owner`, `repo`, optional `ref`, `page`, `limit`).
- `get_commit_diff` (`owner`, `repo`, `sha`).
- `compare_refs` (`owner`, `repo`, `base`, `head`).
- `list_issues` (`owner`, `repo`, optional `state`, `page`, `limit`, `labels`).
- `get_issue` (`owner`, `repo`, `issue_number`).
- `list_pull_requests` (`owner`, `repo`, optional `state`, `page`, `limit`).
- `get_pull_request` (`owner`, `repo`, `pull_number`).
- `list_labels` (`owner`, `repo`, optional `page`, `limit`).
- `list_tags` (`owner`, `repo`, optional `page`, `limit`).
- `list_releases` (`owner`, `repo`, optional `page`, `limit`).
## Write Tools (Write Mode Required)
- `create_issue` (`owner`, `repo`, `title`, optional `body`, `labels`, `assignees`).
- `update_issue` (`owner`, `repo`, `issue_number`, one or more of `title`, `body`, `state`).
- `create_issue_comment` (`owner`, `repo`, `issue_number`, `body`).
- `create_pr_comment` (`owner`, `repo`, `pull_number`, `body`).
- `add_labels` (`owner`, `repo`, `issue_number`, `labels`).
- `assign_issue` (`owner`, `repo`, `issue_number`, `assignees`).
## Validation and Limits
- All tool argument schemas reject unknown fields.
- List responses are capped by `MAX_TOOL_RESPONSE_ITEMS`.
- Text payloads are capped by `MAX_TOOL_RESPONSE_CHARS`.
- File reads are capped by `MAX_FILE_SIZE_BYTES`.
## Error Model
- Policy denial: HTTP `403`.
- Validation error: HTTP `400`.
- Auth error: HTTP `401`.
- Rate limit: HTTP `429`.
- Internal errors: HTTP `500` without stack traces in production.