@ric_/forgejo-mcp 0.1.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.
- package/LICENSE +21 -0
- package/README.md +302 -0
- package/dist/client.d.ts +35 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +107 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +86 -0
- package/dist/config.js.map +1 -0
- package/dist/http.d.ts +3 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +108 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +27 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/admin.d.ts +4 -0
- package/dist/tools/admin.d.ts.map +1 -0
- package/dist/tools/admin.js +261 -0
- package/dist/tools/admin.js.map +1 -0
- package/dist/tools/helpers.d.ts +16 -0
- package/dist/tools/helpers.d.ts.map +1 -0
- package/dist/tools/helpers.js +30 -0
- package/dist/tools/helpers.js.map +1 -0
- package/dist/tools/issues.d.ts +4 -0
- package/dist/tools/issues.d.ts.map +1 -0
- package/dist/tools/issues.js +337 -0
- package/dist/tools/issues.js.map +1 -0
- package/dist/tools/organizations.d.ts +4 -0
- package/dist/tools/organizations.d.ts.map +1 -0
- package/dist/tools/organizations.js +232 -0
- package/dist/tools/organizations.js.map +1 -0
- package/dist/tools/pullrequests.d.ts +4 -0
- package/dist/tools/pullrequests.d.ts.map +1 -0
- package/dist/tools/pullrequests.js +251 -0
- package/dist/tools/pullrequests.js.map +1 -0
- package/dist/tools/repository.d.ts +4 -0
- package/dist/tools/repository.d.ts.map +1 -0
- package/dist/tools/repository.js +437 -0
- package/dist/tools/repository.js.map +1 -0
- package/dist/tools/users.d.ts +4 -0
- package/dist/tools/users.d.ts.map +1 -0
- package/dist/tools/users.js +204 -0
- package/dist/tools/users.js.map +1 -0
- package/dist/validation.d.ts +35 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +68 -0
- package/dist/validation.js.map +1 -0
- package/package.json +49 -0
package/dist/http.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createServer as createHttpServer } from "node:http";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
5
|
+
import { parseCliArgs, resolveConfig } from "./config.js";
|
|
6
|
+
import { createServer } from "./server.js";
|
|
7
|
+
/** Simple in-memory rate limiter per IP */
|
|
8
|
+
class RateLimiter {
|
|
9
|
+
requests = new Map();
|
|
10
|
+
maxRequests;
|
|
11
|
+
windowMs;
|
|
12
|
+
constructor(maxRequests = 100, windowMs = 60_000) {
|
|
13
|
+
this.maxRequests = maxRequests;
|
|
14
|
+
this.windowMs = windowMs;
|
|
15
|
+
}
|
|
16
|
+
isAllowed(ip) {
|
|
17
|
+
const now = Date.now();
|
|
18
|
+
const entry = this.requests.get(ip);
|
|
19
|
+
if (!entry || now > entry.resetAt) {
|
|
20
|
+
this.requests.set(ip, { count: 1, resetAt: now + this.windowMs });
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
entry.count++;
|
|
24
|
+
return entry.count <= this.maxRequests;
|
|
25
|
+
}
|
|
26
|
+
/** Periodically clean up expired entries */
|
|
27
|
+
cleanup() {
|
|
28
|
+
const now = Date.now();
|
|
29
|
+
for (const [ip, entry] of this.requests) {
|
|
30
|
+
if (now > entry.resetAt) {
|
|
31
|
+
this.requests.delete(ip);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function main() {
|
|
37
|
+
const cliArgs = parseCliArgs(process.argv.slice(2));
|
|
38
|
+
const config = resolveConfig(cliArgs);
|
|
39
|
+
const port = cliArgs.port || parseInt(process.env.PORT || "3000", 10);
|
|
40
|
+
// Optional bearer token for HTTP endpoint authentication
|
|
41
|
+
const apiKey = process.env.FORGEJO_MCP_API_KEY;
|
|
42
|
+
if (!apiKey) {
|
|
43
|
+
console.error("WARNING: No FORGEJO_MCP_API_KEY set. The HTTP endpoint is UNAUTHENTICATED.\n" +
|
|
44
|
+
" Anyone who can reach this server will have full access to your Forgejo token's permissions.\n" +
|
|
45
|
+
" Set FORGEJO_MCP_API_KEY to require Bearer token authentication.\n" +
|
|
46
|
+
" Only run unauthenticated on localhost or behind a reverse proxy with its own auth.");
|
|
47
|
+
}
|
|
48
|
+
const server = createServer(config);
|
|
49
|
+
const rateLimiter = new RateLimiter(parseInt(process.env.RATE_LIMIT_MAX || "100", 10), parseInt(process.env.RATE_LIMIT_WINDOW_MS || "60000", 10));
|
|
50
|
+
// Cleanup rate limiter every 5 minutes
|
|
51
|
+
setInterval(() => rateLimiter.cleanup(), 300_000).unref();
|
|
52
|
+
const transport = new StreamableHTTPServerTransport({
|
|
53
|
+
sessionIdGenerator: () => randomUUID(),
|
|
54
|
+
});
|
|
55
|
+
await server.connect(transport);
|
|
56
|
+
const httpServer = createHttpServer(async (req, res) => {
|
|
57
|
+
const url = new URL(req.url || "/", `http://localhost:${port}`);
|
|
58
|
+
const clientIp = req.socket.remoteAddress || "unknown";
|
|
59
|
+
// Rate limiting
|
|
60
|
+
if (!rateLimiter.isAllowed(clientIp)) {
|
|
61
|
+
res.writeHead(429, { "Content-Type": "application/json" });
|
|
62
|
+
res.end(JSON.stringify({ error: "Too many requests" }));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// Authentication check for MCP endpoints
|
|
66
|
+
if (url.pathname === "/mcp" && apiKey) {
|
|
67
|
+
const authHeader = req.headers.authorization;
|
|
68
|
+
if (!authHeader || authHeader !== `Bearer ${apiKey}`) {
|
|
69
|
+
res.writeHead(401, { "Content-Type": "application/json" });
|
|
70
|
+
res.end(JSON.stringify({ error: "Unauthorized. Provide Bearer token via Authorization header." }));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Security headers
|
|
75
|
+
res.setHeader("X-Content-Type-Options", "nosniff");
|
|
76
|
+
res.setHeader("X-Frame-Options", "DENY");
|
|
77
|
+
if (url.pathname === "/mcp" && req.method === "POST") {
|
|
78
|
+
await transport.handleRequest(req, res);
|
|
79
|
+
}
|
|
80
|
+
else if (url.pathname === "/mcp" && req.method === "GET") {
|
|
81
|
+
await transport.handleRequest(req, res);
|
|
82
|
+
}
|
|
83
|
+
else if (url.pathname === "/mcp" && req.method === "DELETE") {
|
|
84
|
+
await transport.handleRequest(req, res);
|
|
85
|
+
}
|
|
86
|
+
else if (url.pathname === "/health") {
|
|
87
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
88
|
+
res.end(JSON.stringify({ status: "ok", version: "0.1.0" }));
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
92
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
httpServer.listen(port, () => {
|
|
96
|
+
console.error(`Forgejo MCP server (HTTP) listening on port ${port}`);
|
|
97
|
+
console.error(` MCP endpoint: http://localhost:${port}/mcp`);
|
|
98
|
+
console.error(` Health check: http://localhost:${port}/health`);
|
|
99
|
+
console.error(` Connected to: ${config.baseUrl}`);
|
|
100
|
+
console.error(` Authentication: ${apiKey ? "enabled (Bearer token)" : "DISABLED"}`);
|
|
101
|
+
console.error(` Rate limiting: ${process.env.RATE_LIMIT_MAX || "100"} req/min per IP`);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
main().catch((error) => {
|
|
105
|
+
console.error("Fatal error:", error);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { parseCliArgs, resolveConfig } from "./config.js";
|
|
4
|
+
import { createServer } from "./server.js";
|
|
5
|
+
async function main() {
|
|
6
|
+
const cliArgs = parseCliArgs(process.argv.slice(2));
|
|
7
|
+
const config = resolveConfig(cliArgs);
|
|
8
|
+
const server = createServer(config);
|
|
9
|
+
const transport = new StdioServerTransport();
|
|
10
|
+
await server.connect(transport);
|
|
11
|
+
}
|
|
12
|
+
main().catch((error) => {
|
|
13
|
+
console.error("Fatal error:", error);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
});
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAEpC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAQjD,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAuB7D"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { ForgejoClient } from "./client.js";
|
|
3
|
+
import { registerRepositoryTools } from "./tools/repository.js";
|
|
4
|
+
import { registerIssueTools } from "./tools/issues.js";
|
|
5
|
+
import { registerPullRequestTools } from "./tools/pullrequests.js";
|
|
6
|
+
import { registerOrganizationTools } from "./tools/organizations.js";
|
|
7
|
+
import { registerUserTools } from "./tools/users.js";
|
|
8
|
+
import { registerAdminTools } from "./tools/admin.js";
|
|
9
|
+
export function createServer(config) {
|
|
10
|
+
const server = new McpServer({
|
|
11
|
+
name: "forgejo-mcp",
|
|
12
|
+
version: "0.1.0",
|
|
13
|
+
}, {
|
|
14
|
+
capabilities: {
|
|
15
|
+
logging: {},
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
const client = new ForgejoClient(config);
|
|
19
|
+
registerRepositoryTools(server, client);
|
|
20
|
+
registerIssueTools(server, client);
|
|
21
|
+
registerPullRequestTools(server, client);
|
|
22
|
+
registerOrganizationTools(server, client);
|
|
23
|
+
registerUserTools(server, client);
|
|
24
|
+
registerAdminTools(server, client);
|
|
25
|
+
return server;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,UAAU,YAAY,CAAC,MAAqB;IAChD,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,OAAO;KACjB,EACD;QACE,YAAY,EAAE;YACZ,OAAO,EAAE,EAAE;SACZ;KACF,CACF,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IAEzC,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEnC,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/tools/admin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI7C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CA8VjF"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { formatResponse, formatError } from "./helpers.js";
|
|
3
|
+
import { zOwner, zPage, zLimit, zTemplateName, zMarkdownMode } from "../validation.js";
|
|
4
|
+
export function registerAdminTools(server, client) {
|
|
5
|
+
// ── Admin tools (require admin token) ──────────────────────────────
|
|
6
|
+
// 1. admin_list_users
|
|
7
|
+
server.tool("admin_list_users", "List all users (requires admin privileges)", {
|
|
8
|
+
page: zPage,
|
|
9
|
+
limit: zLimit,
|
|
10
|
+
}, async (params) => {
|
|
11
|
+
try {
|
|
12
|
+
const data = await client.get("/admin/users", {
|
|
13
|
+
page: params.page,
|
|
14
|
+
limit: params.limit,
|
|
15
|
+
});
|
|
16
|
+
return formatResponse(data);
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
return formatError(err);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
// 2. admin_create_user
|
|
23
|
+
server.tool("admin_create_user", "Create a new user (requires admin privileges)", {
|
|
24
|
+
username: zOwner.describe("Username for the new user"),
|
|
25
|
+
email: z.string().email().describe("Email address for the new user"),
|
|
26
|
+
password: z.string().min(6).max(255).describe("Password for the new user"),
|
|
27
|
+
must_change_password: z.boolean().optional().describe("Whether the user must change password on first login"),
|
|
28
|
+
}, async (params) => {
|
|
29
|
+
try {
|
|
30
|
+
const data = await client.post("/admin/users", {
|
|
31
|
+
username: params.username,
|
|
32
|
+
email: params.email,
|
|
33
|
+
password: params.password,
|
|
34
|
+
must_change_password: params.must_change_password,
|
|
35
|
+
});
|
|
36
|
+
return formatResponse(data);
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
return formatError(err);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
// 3. admin_delete_user
|
|
43
|
+
server.tool("admin_delete_user", "Delete a user (requires admin privileges)", {
|
|
44
|
+
username: zOwner.describe("Username of the user to delete"),
|
|
45
|
+
}, async (params) => {
|
|
46
|
+
try {
|
|
47
|
+
const data = await client.delete(`/admin/users/${params.username}`);
|
|
48
|
+
return formatResponse(data ?? "User deleted successfully");
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
return formatError(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
// 4. admin_edit_user
|
|
55
|
+
server.tool("admin_edit_user", "Edit an existing user (requires admin privileges)", {
|
|
56
|
+
username: zOwner.describe("Username of the user to edit"),
|
|
57
|
+
email: z.string().email().optional().describe("New email address for the user"),
|
|
58
|
+
active: z.boolean().optional().describe("Whether the user account is active"),
|
|
59
|
+
admin: z.boolean().optional().describe("Whether the user has admin privileges"),
|
|
60
|
+
}, async (params) => {
|
|
61
|
+
try {
|
|
62
|
+
const body = {};
|
|
63
|
+
if (params.email !== undefined)
|
|
64
|
+
body.email = params.email;
|
|
65
|
+
if (params.active !== undefined)
|
|
66
|
+
body.active = params.active;
|
|
67
|
+
if (params.admin !== undefined)
|
|
68
|
+
body.admin = params.admin;
|
|
69
|
+
const data = await client.patch(`/admin/users/${params.username}`, body);
|
|
70
|
+
return formatResponse(data);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
return formatError(err);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
// 5. admin_list_cron_jobs
|
|
77
|
+
server.tool("admin_list_cron_jobs", "List all cron jobs (requires admin privileges)", {}, async () => {
|
|
78
|
+
try {
|
|
79
|
+
const data = await client.get("/admin/cron");
|
|
80
|
+
return formatResponse(data);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
return formatError(err);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
// 6. admin_run_cron_job
|
|
87
|
+
server.tool("admin_run_cron_job", "Run a cron task by name (requires admin privileges)", {
|
|
88
|
+
task: zTemplateName.describe("Name of the cron task to run"),
|
|
89
|
+
}, async (params) => {
|
|
90
|
+
try {
|
|
91
|
+
const data = await client.post(`/admin/cron/${params.task}`);
|
|
92
|
+
return formatResponse(data ?? "Cron job triggered successfully");
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
return formatError(err);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
// 7. admin_list_hooks
|
|
99
|
+
server.tool("admin_list_hooks", "List system webhooks (requires admin privileges)", {}, async () => {
|
|
100
|
+
try {
|
|
101
|
+
const data = await client.get("/admin/hooks");
|
|
102
|
+
return formatResponse(data);
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
return formatError(err);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
// ── Miscellaneous tools ────────────────────────────────────────────
|
|
109
|
+
// 8. get_server_version
|
|
110
|
+
server.tool("get_server_version", "Get the Forgejo server version", {}, async () => {
|
|
111
|
+
try {
|
|
112
|
+
const data = await client.get("/version");
|
|
113
|
+
return formatResponse(data);
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
return formatError(err);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
// 9. render_markdown
|
|
120
|
+
server.tool("render_markdown", "Render markdown text to HTML", {
|
|
121
|
+
text: z.string().max(1_000_000).describe("Markdown text to render"),
|
|
122
|
+
mode: zMarkdownMode.describe("Render mode: gfm, comment, or plain"),
|
|
123
|
+
context: z.string().max(255).optional().describe("Context for resolving relative links (e.g. owner/repo)"),
|
|
124
|
+
}, async (params) => {
|
|
125
|
+
try {
|
|
126
|
+
const data = await client.post("/markdown", {
|
|
127
|
+
Text: params.text,
|
|
128
|
+
Mode: params.mode,
|
|
129
|
+
Context: params.context,
|
|
130
|
+
});
|
|
131
|
+
return formatResponse(data);
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
return formatError(err);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
// 10. render_markup
|
|
138
|
+
server.tool("render_markup", "Render markup text to HTML", {
|
|
139
|
+
text: z.string().max(1_000_000).describe("Markup text to render"),
|
|
140
|
+
mode: z.string().max(50).optional().describe("Render mode"),
|
|
141
|
+
context: z.string().max(255).optional().describe("Context for resolving relative links"),
|
|
142
|
+
wiki: z.boolean().optional().describe("Whether the content is wiki content"),
|
|
143
|
+
}, async (params) => {
|
|
144
|
+
try {
|
|
145
|
+
const data = await client.post("/markup", {
|
|
146
|
+
Text: params.text,
|
|
147
|
+
Mode: params.mode,
|
|
148
|
+
Context: params.context,
|
|
149
|
+
Wiki: params.wiki,
|
|
150
|
+
});
|
|
151
|
+
return formatResponse(data);
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
return formatError(err);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
// 11. list_gitignore_templates
|
|
158
|
+
server.tool("list_gitignore_templates", "List all available gitignore templates", {}, async () => {
|
|
159
|
+
try {
|
|
160
|
+
const data = await client.get("/gitignore/templates");
|
|
161
|
+
return formatResponse(data);
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
return formatError(err);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
// 12. get_gitignore_template
|
|
168
|
+
server.tool("get_gitignore_template", "Get a specific gitignore template by name", {
|
|
169
|
+
name: zTemplateName.describe("Name of the gitignore template"),
|
|
170
|
+
}, async (params) => {
|
|
171
|
+
try {
|
|
172
|
+
const data = await client.get(`/gitignore/templates/${params.name}`);
|
|
173
|
+
return formatResponse(data);
|
|
174
|
+
}
|
|
175
|
+
catch (err) {
|
|
176
|
+
return formatError(err);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
// 13. list_license_templates
|
|
180
|
+
server.tool("list_license_templates", "List all available license templates", {}, async () => {
|
|
181
|
+
try {
|
|
182
|
+
const data = await client.get("/licenses");
|
|
183
|
+
return formatResponse(data);
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
return formatError(err);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
// 14. get_license_template
|
|
190
|
+
server.tool("get_license_template", "Get a specific license template by name", {
|
|
191
|
+
name: zTemplateName.describe("Name of the license template"),
|
|
192
|
+
}, async (params) => {
|
|
193
|
+
try {
|
|
194
|
+
const data = await client.get(`/licenses/${params.name}`);
|
|
195
|
+
return formatResponse(data);
|
|
196
|
+
}
|
|
197
|
+
catch (err) {
|
|
198
|
+
return formatError(err);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
// 15. list_label_templates
|
|
202
|
+
server.tool("list_label_templates", "List all available label templates", {}, async () => {
|
|
203
|
+
try {
|
|
204
|
+
const data = await client.get("/label/templates");
|
|
205
|
+
return formatResponse(data);
|
|
206
|
+
}
|
|
207
|
+
catch (err) {
|
|
208
|
+
return formatError(err);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
// 16. get_label_template
|
|
212
|
+
server.tool("get_label_template", "Get a specific label template by name", {
|
|
213
|
+
name: zTemplateName.describe("Name of the label template"),
|
|
214
|
+
}, async (params) => {
|
|
215
|
+
try {
|
|
216
|
+
const data = await client.get(`/label/templates/${params.name}`);
|
|
217
|
+
return formatResponse(data);
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
return formatError(err);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
// 17. get_nodeinfo
|
|
224
|
+
server.tool("get_nodeinfo", "Get the Forgejo instance NodeInfo", {}, async () => {
|
|
225
|
+
try {
|
|
226
|
+
const data = await client.get("/nodeinfo");
|
|
227
|
+
return formatResponse(data);
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
return formatError(err);
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
// ── Actions tools ──────────────────────────────────────────────────
|
|
234
|
+
// 18. list_action_runners_jobs
|
|
235
|
+
server.tool("list_action_runners_jobs", "List action runner jobs (requires admin privileges)", {
|
|
236
|
+
page: zPage,
|
|
237
|
+
limit: zLimit,
|
|
238
|
+
}, async (params) => {
|
|
239
|
+
try {
|
|
240
|
+
const data = await client.get("/admin/runners/jobs", {
|
|
241
|
+
page: params.page,
|
|
242
|
+
limit: params.limit,
|
|
243
|
+
});
|
|
244
|
+
return formatResponse(data);
|
|
245
|
+
}
|
|
246
|
+
catch (err) {
|
|
247
|
+
return formatError(err);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
// 19. get_runner_registration_token
|
|
251
|
+
server.tool("get_runner_registration_token", "Get a runner registration token (requires admin privileges)", {}, async () => {
|
|
252
|
+
try {
|
|
253
|
+
const data = await client.get("/admin/runners/registration-token");
|
|
254
|
+
return formatResponse(data);
|
|
255
|
+
}
|
|
256
|
+
catch (err) {
|
|
257
|
+
return formatError(err);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=admin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/tools/admin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAiB,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtG,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,MAAqB;IACzE,sEAAsE;IAEtE,sBAAsB;IACtB,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB,4CAA4C,EAC5C;QACE,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,MAAM;KACd,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE;gBAC5C,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,KAAK,EAAE,MAAM,CAAC,KAAK;aACpB,CAAC,CAAC;YACH,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,uBAAuB;IACvB,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,+CAA+C,EAC/C;QACE,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QACtD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;QACpE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QAC1E,oBAAoB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sDAAsD,CAAC;KAC9G,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE;gBAC7C,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;aAClD,CAAC,CAAC;YACH,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,uBAAuB;IACvB,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,2CAA2C,EAC3C;QACE,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,gCAAgC,CAAC;KAC5D,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,gBAAgB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YACpE,OAAO,cAAc,CAAC,IAAI,IAAI,2BAA2B,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,qBAAqB;IACrB,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,mDAAmD,EACnD;QACE,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,8BAA8B,CAAC;QACzD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;QAC/E,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;QAC7E,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;KAChF,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAA4B,EAAE,CAAC;YACzC,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;gBAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;YAC1D,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;gBAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAC7D,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;gBAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;YAC1D,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,gBAAgB,MAAM,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAC;YACzE,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,0BAA0B;IAC1B,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,gDAAgD,EAChD,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YAC7C,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,wBAAwB;IACxB,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,qDAAqD,EACrD;QACE,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,8BAA8B,CAAC;KAC7D,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YAC7D,OAAO,cAAc,CAAC,IAAI,IAAI,iCAAiC,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,sBAAsB;IACtB,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB,kDAAkD,EAClD,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAC9C,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,sEAAsE;IAEtE,wBAAwB;IACxB,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,gCAAgC,EAChC,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC1C,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,qBAAqB;IACrB,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,8BAA8B,EAC9B;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC;QACnE,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,qCAAqC,CAAC;QACnE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wDAAwD,CAAC;KAC3G,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE;gBAC1C,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB,CAAC,CAAC;YACH,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,oBAAoB;IACpB,MAAM,CAAC,IAAI,CACT,eAAe,EACf,4BAA4B,EAC5B;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QACjE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;QAC3D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;QACxF,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;KAC7E,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE;gBACxC,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,IAAI,EAAE,MAAM,CAAC,IAAI;aAClB,CAAC,CAAC;YACH,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,+BAA+B;IAC/B,MAAM,CAAC,IAAI,CACT,0BAA0B,EAC1B,wCAAwC,EACxC,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;YACtD,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,6BAA6B;IAC7B,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,2CAA2C,EAC3C;QACE,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,gCAAgC,CAAC;KAC/D,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YACrE,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,6BAA6B;IAC7B,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,sCAAsC,EACtC,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YAC3C,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,2BAA2B;IAC3B,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,yCAAyC,EACzC;QACE,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,8BAA8B,CAAC;KAC7D,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1D,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,2BAA2B;IAC3B,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,oCAAoC,EACpC,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YAClD,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,yBAAyB;IACzB,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,uCAAuC,EACvC;QACE,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,4BAA4B,CAAC;KAC3D,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,oBAAoB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YACjE,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,mBAAmB;IACnB,MAAM,CAAC,IAAI,CACT,cAAc,EACd,mCAAmC,EACnC,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YAC3C,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,sEAAsE;IAEtE,+BAA+B;IAC/B,MAAM,CAAC,IAAI,CACT,0BAA0B,EAC1B,qDAAqD,EACrD;QACE,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,MAAM;KACd,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,qBAAqB,EAAE;gBACnD,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,KAAK,EAAE,MAAM,CAAC,KAAK;aACpB,CAAC,CAAC;YACH,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,oCAAoC;IACpC,MAAM,CAAC,IAAI,CACT,+BAA+B,EAC/B,6DAA6D,EAC7D,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;YACnE,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ForgejoClient } from "../client.js";
|
|
2
|
+
export type ToolHandler<TInput, TOutput> = (client: ForgejoClient, input: TInput) => Promise<TOutput>;
|
|
3
|
+
export declare function formatResponse(data: unknown): {
|
|
4
|
+
content: Array<{
|
|
5
|
+
type: "text";
|
|
6
|
+
text: string;
|
|
7
|
+
}>;
|
|
8
|
+
};
|
|
9
|
+
export declare function formatError(error: unknown): {
|
|
10
|
+
content: Array<{
|
|
11
|
+
type: "text";
|
|
12
|
+
text: string;
|
|
13
|
+
}>;
|
|
14
|
+
isError: true;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/tools/helpers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,MAAM,WAAW,CAAC,MAAM,EAAE,OAAO,IAAI,CACzC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,KACV,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAShG;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,CAiB7G"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ForgejoApiError } from "../client.js";
|
|
2
|
+
export function formatResponse(data) {
|
|
3
|
+
return {
|
|
4
|
+
content: [
|
|
5
|
+
{
|
|
6
|
+
type: "text",
|
|
7
|
+
text: typeof data === "string" ? data : JSON.stringify(data, null, 2),
|
|
8
|
+
},
|
|
9
|
+
],
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function formatError(error) {
|
|
13
|
+
let message;
|
|
14
|
+
if (error instanceof ForgejoApiError) {
|
|
15
|
+
// API errors are safe to expose (status + server message, URL is already sanitized)
|
|
16
|
+
message = error.message;
|
|
17
|
+
}
|
|
18
|
+
else if (error instanceof Error) {
|
|
19
|
+
// For unexpected errors, don't leak internals
|
|
20
|
+
message = error.message;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
message = "An unexpected error occurred";
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
27
|
+
isError: true,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/tools/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAQ/C,MAAM,UAAU,cAAc,CAAC,IAAa;IAC1C,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;aACtE;SACF;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,IAAI,OAAe,CAAC;IAEpB,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;QACrC,oFAAoF;QACpF,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC1B,CAAC;SAAM,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAClC,8CAA8C;QAC9C,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC1B,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,8BAA8B,CAAC;IAC3C,CAAC;IAED,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;QAC/D,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issues.d.ts","sourceRoot":"","sources":["../../src/tools/issues.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI7C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CA+ajF"}
|