@mokoconsulting/mcp-mokogitea-api 1.4.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mokogitea/workflows/auto-bump.yml +9 -9
- package/.mokogitea/workflows/auto-release.yml +90 -28
- package/.mokogitea/workflows/branch-cleanup.yml +1 -1
- package/.mokogitea/workflows/npm-publish.yml +69 -10
- package/.mokogitea/workflows/pr-check.yml +2 -2
- package/.mokogitea/workflows/pre-release.yml +244 -3
- package/.mokogitea/workflows/repo-health.yml +4 -3
- package/dist/client.js +20 -1
- package/dist/index.js +10 -2
- package/package.json +1 -1
- package/src/client.ts +15 -1
- package/src/index.ts +10 -2
- package/Dockerfile +0 -18
- package/dist/server.d.ts +0 -4
- package/dist/server.js +0 -12
- package/dist/sse.d.ts +0 -2
- package/dist/sse.js +0 -87
- package/src/server.ts +0 -16
- package/src/sse.ts +0 -100
- package/wiki/ARCHITECTURE.md +0 -144
- package/wiki/Home.md +0 -35
- package/wiki/INSTALLATION.md +0 -170
package/dist/index.js
CHANGED
|
@@ -1114,14 +1114,22 @@ server.tool('gitea_metadata_update', 'Update repo metadata settings (merges with
|
|
|
1114
1114
|
repo: z.string().describe('Repository name'),
|
|
1115
1115
|
name: z.string().optional().describe('Project name'),
|
|
1116
1116
|
org: z.string().optional().describe('Organization'),
|
|
1117
|
+
description: z.string().optional().describe('Project description'),
|
|
1117
1118
|
version: z.string().optional().describe('Version string (e.g. 06.00.00)'),
|
|
1118
1119
|
version_prefix: z.string().optional().describe('Tag prefix for version display (e.g. v1.26.1-moko.)'),
|
|
1119
1120
|
license_spdx: z.string().optional().describe('SPDX license identifier'),
|
|
1121
|
+
license_name: z.string().optional().describe('Human-readable license name (e.g. GNU General Public License v3)'),
|
|
1122
|
+
element_name: z.string().optional().describe('Extension element name (e.g. pkg_mokosuitecrm, mod_mokojoomhero)'),
|
|
1120
1123
|
platform: z.string().optional().describe('Platform (joomla, wordpress, dolibarr, go, mcp, platform, generic)'),
|
|
1124
|
+
standards_version: z.string().optional().describe('mokoplatform standards version (e.g. 05.01.00)'),
|
|
1125
|
+
standards_source: z.string().optional().describe('URL to standards repo'),
|
|
1126
|
+
maintainer: z.string().optional().describe('Maintainer name (e.g. Moko Consulting)'),
|
|
1127
|
+
maintainer_url: z.string().optional().describe('Maintainer website URL'),
|
|
1121
1128
|
info_url: z.string().optional().describe('Extension info/product page URL'),
|
|
1122
|
-
target_version: z.string().optional().describe('Target platform version regex (e.g.
|
|
1129
|
+
target_version: z.string().optional().describe('Target platform version regex (e.g. 6..*)'),
|
|
1123
1130
|
php_minimum: z.string().optional().describe('Minimum PHP version (e.g. 8.1)'),
|
|
1124
|
-
|
|
1131
|
+
language: z.string().optional().describe('Primary language (e.g. PHP, Go, TypeScript)'),
|
|
1132
|
+
extension_type: z.string().optional().describe('Extension type (component, module, plugin, package, template, library, file)'),
|
|
1125
1133
|
entry_point: z.string().optional().describe('Build entry point path'),
|
|
1126
1134
|
...ConnectionParam,
|
|
1127
1135
|
}, async ({ owner, repo, connection, ...fields }) => {
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -52,7 +52,21 @@ export class GiteaClient {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
async delete(endpoint: string, body?: unknown): Promise<ApiResponse> {
|
|
55
|
-
|
|
55
|
+
if (body === undefined) {
|
|
56
|
+
return this.request(this.buildUrl(endpoint), 'DELETE');
|
|
57
|
+
}
|
|
58
|
+
// Use fetch for DELETE+body — node:https drops the body on some
|
|
59
|
+
// proxy/TLS configurations, causing the server to see an empty request.
|
|
60
|
+
const url = this.buildUrl(endpoint);
|
|
61
|
+
const resp = await fetch(url, {
|
|
62
|
+
method: 'DELETE',
|
|
63
|
+
headers: { ...this.headers },
|
|
64
|
+
body: JSON.stringify(body),
|
|
65
|
+
});
|
|
66
|
+
const raw = await resp.text();
|
|
67
|
+
let data: unknown;
|
|
68
|
+
try { data = JSON.parse(raw); } catch { data = raw; }
|
|
69
|
+
return { status: resp.status, data };
|
|
56
70
|
}
|
|
57
71
|
|
|
58
72
|
private buildUrl(endpoint: string, params?: Record<string, string>): string {
|
package/src/index.ts
CHANGED
|
@@ -1720,14 +1720,22 @@ server.tool(
|
|
|
1720
1720
|
repo: z.string().describe('Repository name'),
|
|
1721
1721
|
name: z.string().optional().describe('Project name'),
|
|
1722
1722
|
org: z.string().optional().describe('Organization'),
|
|
1723
|
+
description: z.string().optional().describe('Project description'),
|
|
1723
1724
|
version: z.string().optional().describe('Version string (e.g. 06.00.00)'),
|
|
1724
1725
|
version_prefix: z.string().optional().describe('Tag prefix for version display (e.g. v1.26.1-moko.)'),
|
|
1725
1726
|
license_spdx: z.string().optional().describe('SPDX license identifier'),
|
|
1727
|
+
license_name: z.string().optional().describe('Human-readable license name (e.g. GNU General Public License v3)'),
|
|
1728
|
+
element_name: z.string().optional().describe('Extension element name (e.g. pkg_mokosuitecrm, mod_mokojoomhero)'),
|
|
1726
1729
|
platform: z.string().optional().describe('Platform (joomla, wordpress, dolibarr, go, mcp, platform, generic)'),
|
|
1730
|
+
standards_version: z.string().optional().describe('mokoplatform standards version (e.g. 05.01.00)'),
|
|
1731
|
+
standards_source: z.string().optional().describe('URL to standards repo'),
|
|
1732
|
+
maintainer: z.string().optional().describe('Maintainer name (e.g. Moko Consulting)'),
|
|
1733
|
+
maintainer_url: z.string().optional().describe('Maintainer website URL'),
|
|
1727
1734
|
info_url: z.string().optional().describe('Extension info/product page URL'),
|
|
1728
|
-
target_version: z.string().optional().describe('Target platform version regex (e.g.
|
|
1735
|
+
target_version: z.string().optional().describe('Target platform version regex (e.g. 6..*)'),
|
|
1729
1736
|
php_minimum: z.string().optional().describe('Minimum PHP version (e.g. 8.1)'),
|
|
1730
|
-
|
|
1737
|
+
language: z.string().optional().describe('Primary language (e.g. PHP, Go, TypeScript)'),
|
|
1738
|
+
extension_type: z.string().optional().describe('Extension type (component, module, plugin, package, template, library, file)'),
|
|
1731
1739
|
entry_point: z.string().optional().describe('Build entry point path'),
|
|
1732
1740
|
...ConnectionParam,
|
|
1733
1741
|
},
|
package/Dockerfile
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
FROM node:20-alpine
|
|
2
|
-
|
|
3
|
-
WORKDIR /app
|
|
4
|
-
|
|
5
|
-
COPY package.json package-lock.json ./
|
|
6
|
-
RUN npm ci --production=false
|
|
7
|
-
|
|
8
|
-
COPY tsconfig.json ./
|
|
9
|
-
COPY src/ ./src/
|
|
10
|
-
RUN npx tsc && npm prune --production
|
|
11
|
-
|
|
12
|
-
EXPOSE 3100
|
|
13
|
-
|
|
14
|
-
ENV PORT=3100
|
|
15
|
-
ENV NODE_ENV=production
|
|
16
|
-
|
|
17
|
-
# SSE mode by default for Docker deployments
|
|
18
|
-
CMD ["node", "dist/sse.js"]
|
package/dist/server.d.ts
DELETED
package/dist/server.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// Copyright 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
2
|
-
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
-
//
|
|
4
|
-
// Creates a configured MCP server instance for use by both stdio and SSE transports.
|
|
5
|
-
// Import index.ts to register all tools on its exported `server` singleton,
|
|
6
|
-
// then re-export a factory that initializes config and returns the server.
|
|
7
|
-
import { server, initConfig } from './index.js';
|
|
8
|
-
export function createMcpServer(cfg) {
|
|
9
|
-
initConfig(cfg);
|
|
10
|
-
return server;
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=server.js.map
|
package/dist/sse.d.ts
DELETED
package/dist/sse.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
// Copyright 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
2
|
-
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
-
//
|
|
4
|
-
// SSE transport entry point for MokoGitea MCP server.
|
|
5
|
-
// Run with: node dist/sse.js
|
|
6
|
-
// Or: GITEA_URL=https://gitea.example.com GITEA_TOKEN=xxx node dist/sse.js
|
|
7
|
-
//
|
|
8
|
-
// Listens on PORT (default 3100) and serves SSE at /sse with POST at /message.
|
|
9
|
-
import { createServer } from 'node:http';
|
|
10
|
-
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
|
11
|
-
import { createMcpServer } from './server.js';
|
|
12
|
-
import { loadConfig } from './config.js';
|
|
13
|
-
const PORT = parseInt(process.env.PORT ?? '3100', 10);
|
|
14
|
-
async function main() {
|
|
15
|
-
const config = await loadConfig();
|
|
16
|
-
const transports = new Map();
|
|
17
|
-
const httpServer = createServer(async (req, res) => {
|
|
18
|
-
// CORS headers for browser clients
|
|
19
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
20
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
21
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
|
22
|
-
if (req.method === 'OPTIONS') {
|
|
23
|
-
res.writeHead(204);
|
|
24
|
-
res.end();
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
// Health check
|
|
28
|
-
if (req.url === '/health') {
|
|
29
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
30
|
-
res.end(JSON.stringify({ status: 'ok', tools: 120 }));
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
// SSE endpoint - client connects here
|
|
34
|
-
if (req.url === '/sse' && req.method === 'GET') {
|
|
35
|
-
const transport = new SSEServerTransport('/message', res);
|
|
36
|
-
const sessionId = transport.sessionId;
|
|
37
|
-
transports.set(sessionId, transport);
|
|
38
|
-
const server = createMcpServer(config);
|
|
39
|
-
await server.connect(transport);
|
|
40
|
-
req.on('close', () => {
|
|
41
|
-
transports.delete(sessionId);
|
|
42
|
-
});
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
// Message endpoint - client sends tool calls here
|
|
46
|
-
if (req.url?.startsWith('/message') && req.method === 'POST') {
|
|
47
|
-
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
48
|
-
const sessionId = url.searchParams.get('sessionId');
|
|
49
|
-
if (!sessionId || !transports.has(sessionId)) {
|
|
50
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
51
|
-
res.end(JSON.stringify({ error: 'Invalid or missing sessionId' }));
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
const transport = transports.get(sessionId);
|
|
55
|
-
await transport.handlePostMessage(req, res);
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
// Root - info page
|
|
59
|
-
if (req.url === '/' || req.url === '') {
|
|
60
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
61
|
-
res.end(JSON.stringify({
|
|
62
|
-
name: '@mokoconsulting/mokogitea-mcp',
|
|
63
|
-
version: '1.1.0',
|
|
64
|
-
description: 'MCP server for Gitea and MokoGitea - 120+ tools',
|
|
65
|
-
endpoints: {
|
|
66
|
-
sse: '/sse',
|
|
67
|
-
message: '/message',
|
|
68
|
-
health: '/health',
|
|
69
|
-
},
|
|
70
|
-
docs: 'https://git.mokoconsulting.tech/MokoConsulting/mcp_mokogitea_api',
|
|
71
|
-
}));
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
res.writeHead(404);
|
|
75
|
-
res.end('Not found');
|
|
76
|
-
});
|
|
77
|
-
httpServer.listen(PORT, () => {
|
|
78
|
-
process.stderr.write(`MokoGitea MCP SSE server listening on port ${PORT}\n`);
|
|
79
|
-
process.stderr.write(` SSE: http://localhost:${PORT}/sse\n`);
|
|
80
|
-
process.stderr.write(` Health: http://localhost:${PORT}/health\n`);
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
main().catch((err) => {
|
|
84
|
-
process.stderr.write(`Fatal: ${err}\n`);
|
|
85
|
-
process.exit(1);
|
|
86
|
-
});
|
|
87
|
-
//# sourceMappingURL=sse.js.map
|
package/src/server.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
// Copyright 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
2
|
-
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
-
//
|
|
4
|
-
// Creates a configured MCP server instance for use by both stdio and SSE transports.
|
|
5
|
-
|
|
6
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
7
|
-
import type { GiteaConfig } from './types.js';
|
|
8
|
-
|
|
9
|
-
// Import index.ts to register all tools on its exported `server` singleton,
|
|
10
|
-
// then re-export a factory that initializes config and returns the server.
|
|
11
|
-
import { server, initConfig } from './index.js';
|
|
12
|
-
|
|
13
|
-
export function createMcpServer(cfg: GiteaConfig): McpServer {
|
|
14
|
-
initConfig(cfg);
|
|
15
|
-
return server;
|
|
16
|
-
}
|
package/src/sse.ts
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
// Copyright 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
2
|
-
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
-
//
|
|
4
|
-
// SSE transport entry point for MokoGitea MCP server.
|
|
5
|
-
// Run with: node dist/sse.js
|
|
6
|
-
// Or: GITEA_URL=https://gitea.example.com GITEA_TOKEN=xxx node dist/sse.js
|
|
7
|
-
//
|
|
8
|
-
// Listens on PORT (default 3100) and serves SSE at /sse with POST at /message.
|
|
9
|
-
|
|
10
|
-
import { createServer } from 'node:http';
|
|
11
|
-
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
|
12
|
-
import { createMcpServer } from './server.js';
|
|
13
|
-
import { loadConfig } from './config.js';
|
|
14
|
-
|
|
15
|
-
const PORT = parseInt(process.env.PORT ?? '3100', 10);
|
|
16
|
-
|
|
17
|
-
async function main(): Promise<void> {
|
|
18
|
-
const config = await loadConfig();
|
|
19
|
-
const transports = new Map<string, SSEServerTransport>();
|
|
20
|
-
|
|
21
|
-
const httpServer = createServer(async (req, res) => {
|
|
22
|
-
// CORS headers for browser clients
|
|
23
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
24
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
25
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
|
26
|
-
|
|
27
|
-
if (req.method === 'OPTIONS') {
|
|
28
|
-
res.writeHead(204);
|
|
29
|
-
res.end();
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Health check
|
|
34
|
-
if (req.url === '/health') {
|
|
35
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
36
|
-
res.end(JSON.stringify({ status: 'ok', tools: 120 }));
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// SSE endpoint - client connects here
|
|
41
|
-
if (req.url === '/sse' && req.method === 'GET') {
|
|
42
|
-
const transport = new SSEServerTransport('/message', res);
|
|
43
|
-
const sessionId = transport.sessionId;
|
|
44
|
-
transports.set(sessionId, transport);
|
|
45
|
-
|
|
46
|
-
const server = createMcpServer(config);
|
|
47
|
-
await server.connect(transport);
|
|
48
|
-
|
|
49
|
-
req.on('close', () => {
|
|
50
|
-
transports.delete(sessionId);
|
|
51
|
-
});
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Message endpoint - client sends tool calls here
|
|
56
|
-
if (req.url?.startsWith('/message') && req.method === 'POST') {
|
|
57
|
-
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
58
|
-
const sessionId = url.searchParams.get('sessionId');
|
|
59
|
-
if (!sessionId || !transports.has(sessionId)) {
|
|
60
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
61
|
-
res.end(JSON.stringify({ error: 'Invalid or missing sessionId' }));
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const transport = transports.get(sessionId)!;
|
|
65
|
-
await transport.handlePostMessage(req, res);
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Root - info page
|
|
70
|
-
if (req.url === '/' || req.url === '') {
|
|
71
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
72
|
-
res.end(JSON.stringify({
|
|
73
|
-
name: '@mokoconsulting/mokogitea-mcp',
|
|
74
|
-
version: '1.1.0',
|
|
75
|
-
description: 'MCP server for Gitea and MokoGitea - 120+ tools',
|
|
76
|
-
endpoints: {
|
|
77
|
-
sse: '/sse',
|
|
78
|
-
message: '/message',
|
|
79
|
-
health: '/health',
|
|
80
|
-
},
|
|
81
|
-
docs: 'https://git.mokoconsulting.tech/MokoConsulting/mcp_mokogitea_api',
|
|
82
|
-
}));
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
res.writeHead(404);
|
|
87
|
-
res.end('Not found');
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
httpServer.listen(PORT, () => {
|
|
91
|
-
process.stderr.write(`MokoGitea MCP SSE server listening on port ${PORT}\n`);
|
|
92
|
-
process.stderr.write(` SSE: http://localhost:${PORT}/sse\n`);
|
|
93
|
-
process.stderr.write(` Health: http://localhost:${PORT}/health\n`);
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
main().catch((err) => {
|
|
98
|
-
process.stderr.write(`Fatal: ${err}\n`);
|
|
99
|
-
process.exit(1);
|
|
100
|
-
});
|
package/wiki/ARCHITECTURE.md
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
← [Home](Home)
|
|
2
|
-
|
|
3
|
-
# Architecture
|
|
4
|
-
|
|
5
|
-
## Component Overview
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
src/
|
|
9
|
-
index.ts -- MCP server entry point, tool registrations (61 tools)
|
|
10
|
-
client.ts -- HTTP client for Gitea REST API v1
|
|
11
|
-
config.ts -- Configuration loader (multi-connection support)
|
|
12
|
-
types.ts -- TypeScript type definitions
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
### index.ts -- Server Entry Point
|
|
16
|
-
|
|
17
|
-
The main module that:
|
|
18
|
-
|
|
19
|
-
- Creates the `McpServer` instance with stdio transport
|
|
20
|
-
- Loads configuration on startup via `loadConfig()`
|
|
21
|
-
- Registers all 61 tools organized by category
|
|
22
|
-
- Provides shared parameter schemas (`OwnerRepo`, `PaginationParams`, `ConnectionParam`)
|
|
23
|
-
- Routes tool calls through `clientFor(connection)` to resolve the target Gitea instance
|
|
24
|
-
- Formats all API responses through `formatResponse()` for consistent MCP output
|
|
25
|
-
|
|
26
|
-
### client.ts -- HTTP Client
|
|
27
|
-
|
|
28
|
-
`GiteaClient` is a zero-dependency HTTP client built on `node:https` and `node:http`:
|
|
29
|
-
|
|
30
|
-
- Prepends `/api/v1` to all endpoint paths
|
|
31
|
-
- Sets `Authorization: token <token>` header on every request (Gitea's native auth format)
|
|
32
|
-
- Supports `GET`, `POST`, `PUT`, `PATCH`, `DELETE` methods
|
|
33
|
-
- Handles query parameter construction via `URL.searchParams`
|
|
34
|
-
- Parses JSON responses automatically
|
|
35
|
-
- 30-second request timeout
|
|
36
|
-
- Optional TLS certificate verification bypass (`insecure` flag)
|
|
37
|
-
|
|
38
|
-
### config.ts -- Configuration Loader
|
|
39
|
-
|
|
40
|
-
Loads the connection configuration from disk:
|
|
41
|
-
|
|
42
|
-
- Default path: `~/.gitea-api-mcp.json`
|
|
43
|
-
- Override via `GITEA_API_MCP_CONFIG` environment variable
|
|
44
|
-
- Validates that at least one connection exists
|
|
45
|
-
- Sets `defaultConnection` to the first connection if not explicitly specified
|
|
46
|
-
- `getConnection()` resolves a named connection or falls back to the default
|
|
47
|
-
|
|
48
|
-
### types.ts -- Type Definitions
|
|
49
|
-
|
|
50
|
-
Three core interfaces:
|
|
51
|
-
|
|
52
|
-
- `GiteaConnection` -- Single connection config (`baseUrl`, `token`, `insecure?`)
|
|
53
|
-
- `GiteaConfig` -- Full config with named connections map and default
|
|
54
|
-
- `ApiResponse` -- Standardized response wrapper (`status`, `data`)
|
|
55
|
-
|
|
56
|
-
## Design Decisions
|
|
57
|
-
|
|
58
|
-
### Token Authentication
|
|
59
|
-
|
|
60
|
-
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.
|
|
61
|
-
|
|
62
|
-
### Multi-Connection Architecture
|
|
63
|
-
|
|
64
|
-
Every tool accepts an optional `connection` parameter. This enables:
|
|
65
|
-
|
|
66
|
-
- Managing multiple Gitea instances from a single MCP server
|
|
67
|
-
- Switching between production, staging, and development instances
|
|
68
|
-
- Cross-instance operations within a single Claude Code session
|
|
69
|
-
|
|
70
|
-
The connection is resolved at call time, not at startup, so different tool calls can target different instances.
|
|
71
|
-
|
|
72
|
-
### node:https (Zero HTTP Dependencies)
|
|
73
|
-
|
|
74
|
-
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:
|
|
75
|
-
|
|
76
|
-
- Eliminates supply-chain risk from HTTP client dependencies
|
|
77
|
-
- Reduces `node_modules` size
|
|
78
|
-
- Avoids compatibility issues across Node.js versions
|
|
79
|
-
- Provides full control over TLS configuration (needed for `insecure` flag)
|
|
80
|
-
|
|
81
|
-
### Stdio Transport
|
|
82
|
-
|
|
83
|
-
The MCP server uses stdio transport (stdin/stdout) rather than HTTP/SSE. This means:
|
|
84
|
-
|
|
85
|
-
- No network ports are opened by the server
|
|
86
|
-
- Tokens are never exposed through HTTP endpoints
|
|
87
|
-
- The server runs as a child process of the MCP client
|
|
88
|
-
- Communication is process-local, reducing attack surface
|
|
89
|
-
|
|
90
|
-
### Shared Parameter Objects
|
|
91
|
-
|
|
92
|
-
Common parameter patterns are defined as reusable objects:
|
|
93
|
-
|
|
94
|
-
- `OwnerRepo` -- `{ owner, repo }` for all repository-scoped operations
|
|
95
|
-
- `PaginationParams` -- `{ page, limit }` for all list endpoints
|
|
96
|
-
- `ConnectionParam` -- `{ connection }` for multi-connection routing
|
|
97
|
-
|
|
98
|
-
This ensures consistency across all 61 tools and simplifies adding new tools.
|
|
99
|
-
|
|
100
|
-
## Data Flow
|
|
101
|
-
|
|
102
|
-
```
|
|
103
|
-
+-----------------+
|
|
104
|
-
| Claude Code / |
|
|
105
|
-
| MCP Client |
|
|
106
|
-
+--------+--------+
|
|
107
|
-
|
|
|
108
|
-
stdio (JSON-RPC)
|
|
109
|
-
|
|
|
110
|
-
+--------v--------+
|
|
111
|
-
| index.ts |
|
|
112
|
-
| McpServer |
|
|
113
|
-
| (tool router) |
|
|
114
|
-
+--------+--------+
|
|
115
|
-
|
|
|
116
|
-
+-----------+-----------+
|
|
117
|
-
| |
|
|
118
|
-
+------v------+ +-------v-------+
|
|
119
|
-
| config.ts | | client.ts |
|
|
120
|
-
| loadConfig | | GiteaClient |
|
|
121
|
-
| getConn | | (HTTP calls) |
|
|
122
|
-
+------+------+ +-------+-------+
|
|
123
|
-
| |
|
|
124
|
-
+------v------+ HTTPS / HTTP
|
|
125
|
-
| ~/.gitea- | |
|
|
126
|
-
| api-mcp.json| +--------v--------+
|
|
127
|
-
+-------------+ | Gitea Instance |
|
|
128
|
-
| /api/v1/* |
|
|
129
|
-
+-----------------+
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
1. Claude Code sends a JSON-RPC tool call over stdio
|
|
133
|
-
2. `McpServer` routes the call to the registered tool handler
|
|
134
|
-
3. The handler calls `clientFor(connection)` which resolves the connection from config
|
|
135
|
-
4. `GiteaClient` constructs the HTTP request and sends it to the Gitea API
|
|
136
|
-
5. The JSON response is wrapped in `formatResponse()` and returned to the MCP client
|
|
137
|
-
|
|
138
|
-
---
|
|
139
|
-
|
|
140
|
-
*Repo: [gitea-api-mcp](https://git.mokoconsulting.tech/MokoConsulting/gitea-api-mcp) . [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/mokoplatform/wiki/Home)*
|
|
141
|
-
|
|
142
|
-
| Revision | Date | Author | Description |
|
|
143
|
-
|---|---|---|---|
|
|
144
|
-
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
package/wiki/Home.md
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# gitea-api-mcp
|
|
2
|
-
|
|
3
|
-
MCP server for Gitea REST API v1 operations — 61 tools for repos, issues, PRs, releases, branches, actions, orgs, wiki, webhooks, and more
|
|
4
|
-
|
|
5
|
-
| Field | Value |
|
|
6
|
-
|---|---|
|
|
7
|
-
| **Language** | Markdown |
|
|
8
|
-
| **License** | GPL-3.0-or-later |
|
|
9
|
-
| **Platform** | [Gitea](https://git.mokoconsulting.tech/MokoConsulting/gitea-api-mcp) |
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Guides
|
|
14
|
-
|
|
15
|
-
| Page | Description |
|
|
16
|
-
|---|---|
|
|
17
|
-
| [INSTALLATION](INSTALLATION) | - **Node.js** >= 20.0.0 ([download](https://nodejs.org)) |
|
|
18
|
-
|
|
19
|
-
## Reference
|
|
20
|
-
|
|
21
|
-
| Page | Description |
|
|
22
|
-
|---|---|
|
|
23
|
-
| [ARCHITECTURE](ARCHITECTURE) | index.ts -- MCP server entry point, tool registrations (61 tools) |
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
> [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/mokoplatform/wiki/Home)
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
*Repo: [gitea-api-mcp](https://git.mokoconsulting.tech/MokoConsulting/gitea-api-mcp) . [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/mokoplatform/wiki/Home)*
|
|
32
|
-
|
|
33
|
-
| Revision | Date | Author | Description |
|
|
34
|
-
|---|---|---|---|
|
|
35
|
-
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|