@mokoconsulting/mcp-mokogitea-api 1.2.0

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.
Files changed (86) hide show
  1. package/.gitattributes +94 -0
  2. package/.gitmessage +9 -0
  3. package/.mokogitea/ISSUE_TEMPLATE/adr.md +110 -0
  4. package/.mokogitea/ISSUE_TEMPLATE/bug_report.md +48 -0
  5. package/.mokogitea/ISSUE_TEMPLATE/config.yml +18 -0
  6. package/.mokogitea/ISSUE_TEMPLATE/documentation.md +52 -0
  7. package/.mokogitea/ISSUE_TEMPLATE/enterprise_support.md +85 -0
  8. package/.mokogitea/ISSUE_TEMPLATE/feature_request.md +51 -0
  9. package/.mokogitea/ISSUE_TEMPLATE/firewall-request.md +190 -0
  10. package/.mokogitea/ISSUE_TEMPLATE/mcp_api_integration.md +48 -0
  11. package/.mokogitea/ISSUE_TEMPLATE/mcp_connection_issue.md +67 -0
  12. package/.mokogitea/ISSUE_TEMPLATE/mcp_tool_request.md +49 -0
  13. package/.mokogitea/ISSUE_TEMPLATE/question.md +82 -0
  14. package/.mokogitea/ISSUE_TEMPLATE/rfc.md +126 -0
  15. package/.mokogitea/ISSUE_TEMPLATE/security.md +51 -0
  16. package/.mokogitea/ISSUE_TEMPLATE/version.md +24 -0
  17. package/.mokogitea/auto-assign.yml +76 -0
  18. package/.mokogitea/auto-dev-issue.yml +207 -0
  19. package/.mokogitea/auto-release.yml +337 -0
  20. package/.mokogitea/branch-protection.yml +251 -0
  21. package/.mokogitea/changelog-validation.yml +101 -0
  22. package/.mokogitea/codeql-analysis.yml +115 -0
  23. package/.mokogitea/copilot-agent.yml +44 -0
  24. package/.mokogitea/deploy-demo.yml +734 -0
  25. package/.mokogitea/deploy-dev.yml +700 -0
  26. package/.mokogitea/enterprise-firewall-setup.yml +758 -0
  27. package/.mokogitea/manifest.xml +25 -0
  28. package/.mokogitea/mcp-auto-release.yml +278 -0
  29. package/.mokogitea/mcp-build-test.yml +65 -0
  30. package/.mokogitea/mcp-sdk-check.yml +109 -0
  31. package/.mokogitea/mcp-tool-inventory.yml +61 -0
  32. package/.mokogitea/pr-branch-check.yml +90 -0
  33. package/.mokogitea/repository-cleanup.yml +525 -0
  34. package/.mokogitea/standards-compliance.yml +2614 -0
  35. package/.mokogitea/sync-version-on-merge.yml +133 -0
  36. package/.mokogitea/workflows/auto-assign.yml +76 -0
  37. package/.mokogitea/workflows/auto-bump.yml +66 -0
  38. package/.mokogitea/workflows/auto-dev-issue.yml +207 -0
  39. package/.mokogitea/workflows/auto-release.yml +341 -0
  40. package/.mokogitea/workflows/branch-cleanup.yml +48 -0
  41. package/.mokogitea/workflows/cascade-dev.yml +10 -0
  42. package/.mokogitea/workflows/changelog-validation.yml +101 -0
  43. package/.mokogitea/workflows/ci-generic.yml +204 -0
  44. package/.mokogitea/workflows/cleanup.yml +87 -0
  45. package/.mokogitea/workflows/codeql-analysis.yml +115 -0
  46. package/.mokogitea/workflows/copilot-agent.yml +44 -0
  47. package/.mokogitea/workflows/deploy-manual.yml +126 -0
  48. package/.mokogitea/workflows/enterprise-firewall-setup.yml +758 -0
  49. package/.mokogitea/workflows/gitleaks.yml +96 -0
  50. package/.mokogitea/workflows/issue-branch.yml +73 -0
  51. package/.mokogitea/workflows/mcp-auto-release.yml +280 -0
  52. package/.mokogitea/workflows/mcp-build-test.yml +65 -0
  53. package/.mokogitea/workflows/mcp-sdk-check.yml +109 -0
  54. package/.mokogitea/workflows/mcp-tool-inventory.yml +61 -0
  55. package/.mokogitea/workflows/notify.yml +70 -0
  56. package/.mokogitea/workflows/npm-publish.yml +51 -0
  57. package/.mokogitea/workflows/pr-check.yml +508 -0
  58. package/.mokogitea/workflows/pre-release.yml +11 -0
  59. package/.mokogitea/workflows/repo-health.yml +711 -0
  60. package/.mokogitea/workflows/repository-cleanup.yml +525 -0
  61. package/.mokogitea/workflows/security-audit.yml +82 -0
  62. package/.mokogitea/workflows/standards-compliance.yml +2614 -0
  63. package/.mokogitea/workflows/sync-version-on-merge.yml +130 -0
  64. package/.mokogitea/workflows/update-server.yml +312 -0
  65. package/CHANGELOG.md +145 -0
  66. package/CLAUDE.md +43 -0
  67. package/CONTRIBUTING.md +161 -0
  68. package/README.md +286 -0
  69. package/SECURITY.md +91 -0
  70. package/automation/ci-issue-reporter.sh +237 -0
  71. package/config.example.json +13 -0
  72. package/dist/client.d.ts +15 -0
  73. package/dist/client.js +104 -0
  74. package/dist/config.d.ts +4 -0
  75. package/dist/config.js +48 -0
  76. package/dist/index.d.ts +3 -0
  77. package/dist/index.js +1119 -0
  78. package/dist/types.d.ts +20 -0
  79. package/dist/types.js +16 -0
  80. package/package.json +34 -0
  81. package/scripts/setup.mjs +40 -0
  82. package/src/client.ts +120 -0
  83. package/src/config.ts +58 -0
  84. package/src/index.ts +1712 -0
  85. package/src/types.ts +37 -0
  86. package/tsconfig.json +19 -0
@@ -0,0 +1,20 @@
1
+ export interface GiteaConnection {
2
+ baseUrl: string;
3
+ token: string;
4
+ /** Skip TLS certificate verification (self-signed certs) */
5
+ insecure?: boolean;
6
+ }
7
+ export interface GitHubBackupConfig {
8
+ token: string;
9
+ org: string;
10
+ }
11
+ export interface GiteaConfig {
12
+ connections: Record<string, GiteaConnection>;
13
+ defaultConnection: string;
14
+ github?: GitHubBackupConfig;
15
+ }
16
+ export interface ApiResponse {
17
+ status: number;
18
+ data: unknown;
19
+ }
20
+ //# sourceMappingURL=types.d.ts.map
package/dist/types.js ADDED
@@ -0,0 +1,16 @@
1
+ /* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
2
+ *
3
+ * This file is part of a Moko Consulting project.
4
+ *
5
+ * SPDX-License-Identifier: GPL-3.0-or-later
6
+ *
7
+ * FILE INFORMATION
8
+ * DEFGROUP: gitea-api-mcp.Types
9
+ * INGROUP: gitea-api-mcp
10
+ * REPO: https://git.mokoconsulting.tech/MokoConsulting/gitea-api-mcp
11
+ * PATH: /src/types.ts
12
+ * VERSION: 01.00.00
13
+ * BRIEF: TypeScript type definitions for Gitea API MCP server
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=types.js.map
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@mokoconsulting/mcp-mokogitea-api",
3
+ "version": "1.2.0",
4
+ "description": "MCP server for Gitea REST API v1 operations",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "mokogitea-api-mcp": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "start": "node dist/index.js",
14
+ "setup": "node scripts/setup.mjs",
15
+ "clean": "rm -rf dist/"
16
+ },
17
+ "dependencies": {
18
+ "@modelcontextprotocol/sdk": "^1.12.1",
19
+ "zod": "^3.24.4"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^22.15.3",
23
+ "typescript": "^5.8.3"
24
+ },
25
+ "engines": {
26
+ "node": ">=20.0.0"
27
+ },
28
+ "license": "GPL-3.0-or-later",
29
+ "author": "Moko Consulting <hello@mokoconsulting.tech>",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://git.mokoconsulting.tech/MokoConsulting/gitea-api-mcp.git"
33
+ }
34
+ }
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ /* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
3
+ * SPDX-License-Identifier: GPL-3.0-or-later
4
+ * BRIEF: Interactive setup — prompts for Gitea connection details
5
+ */
6
+ import { createInterface } from 'node:readline/promises';
7
+ import { readFile, writeFile } from 'node:fs/promises';
8
+ import { resolve } from 'node:path';
9
+ import { homedir } from 'node:os';
10
+
11
+ const CONFIG_PATH = resolve(homedir(), '.gitea-api-mcp.json');
12
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
13
+
14
+ async function prompt(q, d) { const a = await rl.question(`${q}${d ? ` [${d}]` : ''}: `); return a.trim() || d || ''; }
15
+ async function promptRequired(q) { let a = ''; while (!a) { a = (await rl.question(`${q}: `)).trim(); if (!a) console.log(' Required.'); } return a; }
16
+
17
+ async function main() {
18
+ console.log('\n=== gitea-api-mcp Setup ===\n');
19
+ let existing = null;
20
+ try { existing = JSON.parse(await readFile(CONFIG_PATH, 'utf-8')); console.log(`Existing: ${Object.keys(existing.connections).join(', ')}\n`); } catch {}
21
+
22
+ const name = await prompt('Connection name', 'moko');
23
+ const baseUrl = await promptRequired('Gitea URL (e.g. https://git.mokoconsulting.tech)');
24
+ const token = await promptRequired('Access token (Settings > Applications > Generate Token)');
25
+ const insecure = (await prompt('Skip TLS verification? (y/N)', 'N')).toLowerCase() === 'y';
26
+
27
+ const conn = { baseUrl: baseUrl.replace(/\/+$/, ''), token };
28
+ if (insecure) conn.insecure = true;
29
+
30
+ const config = existing ?? { defaultConnection: name, connections: {} };
31
+ config.connections[name] = conn;
32
+ if (!existing) config.defaultConnection = name;
33
+ else if ((await prompt(`Set "${name}" as default? (y/N)`, 'N')).toLowerCase() === 'y') config.defaultConnection = name;
34
+
35
+ await writeFile(CONFIG_PATH, JSON.stringify(config, null, '\t') + '\n', 'utf-8');
36
+ console.log(`\nConfig written to ${CONFIG_PATH}\n`);
37
+ rl.close();
38
+ }
39
+
40
+ main().catch(e => { console.error(e.message); rl.close(); process.exit(1); });
package/src/client.ts ADDED
@@ -0,0 +1,120 @@
1
+ /* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
2
+ *
3
+ * This file is part of a Moko Consulting project.
4
+ *
5
+ * SPDX-License-Identifier: GPL-3.0-or-later
6
+ *
7
+ * FILE INFORMATION
8
+ * DEFGROUP: gitea-api-mcp.Client
9
+ * INGROUP: gitea-api-mcp
10
+ * REPO: https://git.mokoconsulting.tech/MokoConsulting/gitea-api-mcp
11
+ * PATH: /src/client.ts
12
+ * VERSION: 01.00.00
13
+ * BRIEF: HTTP client for Gitea REST API v1
14
+ */
15
+
16
+ import * as https from 'node:https';
17
+ import * as http from 'node:http';
18
+ import type { GiteaConnection, ApiResponse } from './types.js';
19
+
20
+ const API_PREFIX = '/api/v1';
21
+ const TIMEOUT_MS = 30_000;
22
+
23
+ export class GiteaClient {
24
+ private readonly base_url: string;
25
+ private readonly headers: Record<string, string>;
26
+ private readonly insecure: boolean;
27
+
28
+ constructor(conn: GiteaConnection) {
29
+ this.base_url = conn.baseUrl.replace(/\/+$/, '') + API_PREFIX;
30
+ this.headers = {
31
+ 'Authorization': `token ${conn.token}`,
32
+ 'Content-Type': 'application/json',
33
+ 'Accept': 'application/json',
34
+ };
35
+ this.insecure = conn.insecure ?? false;
36
+ }
37
+
38
+ async get(endpoint: string, params?: Record<string, string>): Promise<ApiResponse> {
39
+ return this.request(this.buildUrl(endpoint, params), 'GET');
40
+ }
41
+
42
+ async post(endpoint: string, body?: unknown): Promise<ApiResponse> {
43
+ return this.request(this.buildUrl(endpoint), 'POST', body);
44
+ }
45
+
46
+ async patch(endpoint: string, body: unknown): Promise<ApiResponse> {
47
+ return this.request(this.buildUrl(endpoint), 'PATCH', body);
48
+ }
49
+
50
+ async put(endpoint: string, body: unknown): Promise<ApiResponse> {
51
+ return this.request(this.buildUrl(endpoint), 'PUT', body);
52
+ }
53
+
54
+ async delete(endpoint: string, body?: unknown): Promise<ApiResponse> {
55
+ return this.request(this.buildUrl(endpoint), 'DELETE', body);
56
+ }
57
+
58
+ private buildUrl(endpoint: string, params?: Record<string, string>): string {
59
+ const path = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
60
+ const url = new URL(`${this.base_url}${path}`);
61
+ if (params) {
62
+ for (const [key, value] of Object.entries(params)) {
63
+ url.searchParams.set(key, value);
64
+ }
65
+ }
66
+ return url.toString();
67
+ }
68
+
69
+ private request(url: string, method: string, body?: unknown): Promise<ApiResponse> {
70
+ return new Promise((resolve, reject) => {
71
+ const parsed = new URL(url);
72
+ const is_https = parsed.protocol === 'https:';
73
+ const transport = is_https ? https : http;
74
+
75
+ const options: https.RequestOptions = {
76
+ hostname: parsed.hostname,
77
+ port: parsed.port || (is_https ? 443 : 80),
78
+ path: parsed.pathname + parsed.search,
79
+ method,
80
+ headers: { ...this.headers },
81
+ timeout: TIMEOUT_MS,
82
+ };
83
+
84
+ if (this.insecure && is_https) {
85
+ options.rejectUnauthorized = false;
86
+ }
87
+
88
+ const payload = body !== undefined ? JSON.stringify(body) : undefined;
89
+ if (payload) {
90
+ (options.headers as Record<string, string>)['Content-Length'] = Buffer.byteLength(payload).toString();
91
+ }
92
+
93
+ const req = transport.request(options, (res) => {
94
+ const chunks: Buffer[] = [];
95
+ res.on('data', (chunk: Buffer) => chunks.push(chunk));
96
+ res.on('end', () => {
97
+ const raw = Buffer.concat(chunks).toString('utf-8');
98
+ let data: unknown;
99
+ try {
100
+ data = JSON.parse(raw);
101
+ } catch {
102
+ data = raw;
103
+ }
104
+ resolve({ status: res.statusCode ?? 0, data });
105
+ });
106
+ });
107
+
108
+ req.on('error', (err) => reject(err));
109
+ req.on('timeout', () => {
110
+ req.destroy();
111
+ reject(new Error('Request timed out'));
112
+ });
113
+
114
+ if (payload) {
115
+ req.write(payload);
116
+ }
117
+ req.end();
118
+ });
119
+ }
120
+ }
package/src/config.ts ADDED
@@ -0,0 +1,58 @@
1
+ /* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
2
+ *
3
+ * This file is part of a Moko Consulting project.
4
+ *
5
+ * SPDX-License-Identifier: GPL-3.0-or-later
6
+ *
7
+ * FILE INFORMATION
8
+ * DEFGROUP: gitea-api-mcp.Config
9
+ * INGROUP: gitea-api-mcp
10
+ * REPO: https://git.mokoconsulting.tech/MokoConsulting/gitea-api-mcp
11
+ * PATH: /src/config.ts
12
+ * VERSION: 01.00.00
13
+ * BRIEF: Configuration loader for Gitea API MCP connections
14
+ */
15
+
16
+ import { readFile } from 'node:fs/promises';
17
+ import { resolve } from 'node:path';
18
+ import { homedir } from 'node:os';
19
+ import type { GiteaConfig, GiteaConnection } from './types.js';
20
+
21
+ const CONFIG_FILENAME = '.mcp_mokogitea.json';
22
+
23
+ export async function loadConfig(): Promise<GiteaConfig> {
24
+ const config_path = process.env.GITEA_API_MCP_CONFIG
25
+ ? resolve(process.env.GITEA_API_MCP_CONFIG)
26
+ : resolve(homedir(), CONFIG_FILENAME);
27
+
28
+ try {
29
+ const raw = await readFile(config_path, 'utf-8');
30
+ const parsed = JSON.parse(raw) as Partial<GiteaConfig>;
31
+
32
+ if (!parsed.connections || Object.keys(parsed.connections).length === 0) {
33
+ throw new Error('No connections defined in config');
34
+ }
35
+
36
+ return {
37
+ connections: parsed.connections,
38
+ defaultConnection: parsed.defaultConnection ?? Object.keys(parsed.connections)[0],
39
+ };
40
+ } catch (err) {
41
+ const message = err instanceof Error ? err.message : String(err);
42
+ throw new Error(
43
+ `Failed to load config from ${config_path}: ${message}\n` +
44
+ `Create ${config_path} — see config.example.json for format.`,
45
+ );
46
+ }
47
+ }
48
+
49
+ export function getConnection(config: GiteaConfig, name?: string): GiteaConnection {
50
+ const key = name ?? config.defaultConnection;
51
+ const conn = config.connections[key];
52
+ if (!conn) {
53
+ throw new Error(
54
+ `Connection "${key}" not found. Available: ${Object.keys(config.connections).join(', ')}`,
55
+ );
56
+ }
57
+ return conn;
58
+ }