Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5.5 KiB
Architecture
Component Overview
src/
index.ts -- MCP server entry point, tool registrations (61 tools)
client.ts -- HTTP client for Gitea REST API v1
config.ts -- Configuration loader (multi-connection support)
types.ts -- TypeScript type definitions
index.ts -- Server Entry Point
The main module that:
- Creates the
McpServerinstance with stdio transport - Loads configuration on startup via
loadConfig() - Registers all 61 tools organized by category
- Provides shared parameter schemas (
OwnerRepo,PaginationParams,ConnectionParam) - Routes tool calls through
clientFor(connection)to resolve the target Gitea instance - Formats all API responses through
formatResponse()for consistent MCP output
client.ts -- HTTP Client
GiteaClient is a zero-dependency HTTP client built on node:https and node:http:
- Prepends
/api/v1to all endpoint paths - Sets
Authorization: token <token>header on every request (Gitea's native auth format) - Supports
GET,POST,PUT,PATCH,DELETEmethods - Handles query parameter construction via
URL.searchParams - Parses JSON responses automatically
- 30-second request timeout
- Optional TLS certificate verification bypass (
insecureflag)
config.ts -- Configuration Loader
Loads the connection configuration from disk:
- Default path:
~/.gitea-api-mcp.json - Override via
GITEA_API_MCP_CONFIGenvironment variable - Validates that at least one connection exists
- Sets
defaultConnectionto the first connection if not explicitly specified getConnection()resolves a named connection or falls back to the default
types.ts -- Type Definitions
Three core interfaces:
GiteaConnection-- Single connection config (baseUrl,token,insecure?)GiteaConfig-- Full config with named connections map and defaultApiResponse-- Standardized response wrapper (status,data)
Design Decisions
Token Authentication
Gitea uses Authorization: token <access-token> as its native authentication header format, unlike GitHub's Bearer token format. This server uses the native Gitea format directly, ensuring compatibility with all Gitea versions without requiring OAuth2 setup.
Multi-Connection Architecture
Every tool accepts an optional connection parameter. This enables:
- Managing multiple Gitea instances from a single MCP server
- Switching between production, staging, and development instances
- Cross-instance operations within a single Claude Code session
The connection is resolved at call time, not at startup, so different tool calls can target different instances.
node:https (Zero HTTP Dependencies)
The HTTP client uses Node.js built-in node:https and node:http modules instead of third-party libraries (e.g., axios, node-fetch). This decision:
- Eliminates supply-chain risk from HTTP client dependencies
- Reduces
node_modulessize - Avoids compatibility issues across Node.js versions
- Provides full control over TLS configuration (needed for
insecureflag)
Stdio Transport
The MCP server uses stdio transport (stdin/stdout) rather than HTTP/SSE. This means:
- No network ports are opened by the server
- Tokens are never exposed through HTTP endpoints
- The server runs as a child process of the MCP client
- Communication is process-local, reducing attack surface
Shared Parameter Objects
Common parameter patterns are defined as reusable objects:
OwnerRepo--{ owner, repo }for all repository-scoped operationsPaginationParams--{ page, limit }for all list endpointsConnectionParam--{ connection }for multi-connection routing
This ensures consistency across all 61 tools and simplifies adding new tools.
Data Flow
+-----------------+
| Claude Code / |
| MCP Client |
+--------+--------+
|
stdio (JSON-RPC)
|
+--------v--------+
| index.ts |
| McpServer |
| (tool router) |
+--------+--------+
|
+-----------+-----------+
| |
+------v------+ +-------v-------+
| config.ts | | client.ts |
| loadConfig | | GiteaClient |
| getConn | | (HTTP calls) |
+------+------+ +-------+-------+
| |
+------v------+ HTTPS / HTTP
| ~/.gitea- | |
| api-mcp.json| +--------v--------+
+-------------+ | Gitea Instance |
| /api/v1/* |
+-----------------+
- Claude Code sends a JSON-RPC tool call over stdio
McpServerroutes the call to the registered tool handler- The handler calls
clientFor(connection)which resolves the connection from config GiteaClientconstructs the HTTP request and sends it to the Gitea API- The JSON response is wrapped in
formatResponse()and returned to the MCP client