@gitgrant/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/.env.example ADDED
@@ -0,0 +1,13 @@
1
+ # GitGrant MCP Server Configuration
2
+
3
+ # API endpoint of the GitGrant bot (required)
4
+ GITGRANT_API_URL=https://api.gitgrant.app
5
+
6
+ # Chain RPC URL (default: Base Sepolia)
7
+ RPC_URL=https://sepolia.base.org
8
+
9
+ # Escrow contract address on the target chain
10
+ ESCROW_ADDRESS=0x0000000000000000000000000000000000000000
11
+
12
+ # Chain ID (default: 84532 = Base Sepolia)
13
+ CHAIN_ID=84532
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import "dotenv/config";
package/dist/cli.js ADDED
@@ -0,0 +1,192 @@
1
+ #!/usr/bin/env node
2
+ import "dotenv/config";
3
+ import { readFileSync, existsSync } from "fs";
4
+ import { join, dirname } from "path";
5
+ import { fileURLToPath } from "url";
6
+ import { GitGrantClient, computeBountyId, parseIssueUri, statusEmoji, formatWeiToEth } from "@gitgrant/sdk";
7
+ const API_URL = process.env.GITGRANT_API_URL || "https://api.gitgrant.app";
8
+ const RPC_URL = process.env.RPC_URL || "https://mainnet.base.org";
9
+ const ESCROW_ADDRESS = process.env.ESCROW_ADDRESS || "0xFa59AeA9A35880716bC17455d101871Ba2D274a7";
10
+ const CHAIN_ID = Number(process.env.CHAIN_ID || 8453);
11
+ const CHAIN_NAMES = { 8453: "Base Mainnet", 84532: "Base Sepolia", 31337: "Local" };
12
+ const client = new GitGrantClient({ baseUrl: API_URL });
13
+ // Resolve ASCII art from src/ (dev via tsx) or from a sibling file (compiled dist/)
14
+ const __dirname = dirname(fileURLToPath(import.meta.url));
15
+ const asciiPath = existsSync(join(__dirname, "ascii-text-art.txt"))
16
+ ? join(__dirname, "ascii-text-art.txt")
17
+ : join(__dirname, "..", "src", "ascii-text-art.txt");
18
+ const ASCII = readFileSync(asciiPath, "utf-8");
19
+ const G = "\x1b[38;2;139;92;246m";
20
+ const R = "\x1b[0m";
21
+ const B = "\x1b[1m";
22
+ const D = "\x1b[2m";
23
+ const WELCOME = `
24
+ ${G}${ASCII}${R}
25
+
26
+ ${B}GitGrant CLI${R} — onchain bounties for open source
27
+ ${D}API: ${API_URL} • Chain: ${CHAIN_NAMES[CHAIN_ID]} (${CHAIN_ID})${R}
28
+
29
+ ${B}Commands:${R}
30
+ list List all bounties
31
+ active List active bounties (Open + Claimed)
32
+ get Get bounty detail by ID or issue URI
33
+ stats Show platform statistics
34
+ id Compute bounty ID from an issue URI
35
+ parse Parse an issue URI into components
36
+ chain Show chain info
37
+
38
+ ${B}Options${R} (list/active):
39
+ --status Filter by status (comma-separated)
40
+ --repo Filter by repo (owner/repo)
41
+ --limit Max results (default 20)
42
+ --offset Pagination offset
43
+
44
+ ${B}Examples:${R}
45
+ gitgrant list
46
+ gitgrant list --status Open --repo owner/repo
47
+ gitgrant active
48
+ gitgrant get github:owner/repo#123
49
+ gitgrant stats
50
+ gitgrant id github:owner/repo#123
51
+ gitgrant chain
52
+ `;
53
+ function parseArgs(argv) {
54
+ const opts = {};
55
+ for (let i = 0; i < argv.length; i++) {
56
+ if (argv[i].startsWith("--")) {
57
+ const key = argv[i].slice(2);
58
+ const val = argv[i + 1] && !argv[i + 1].startsWith("--") ? argv[++i] : "true";
59
+ opts[key] = val;
60
+ }
61
+ }
62
+ return opts;
63
+ }
64
+ function daysAgo(iso) {
65
+ return Math.floor((Date.now() - new Date(iso).getTime()) / 86400000);
66
+ }
67
+ function shortAddr(addr) {
68
+ return addr.length < 10 ? addr : `${addr.slice(0, 6)}...${addr.slice(-4)}`;
69
+ }
70
+ async function cmdList(args) {
71
+ const opts = parseArgs(args);
72
+ const status = opts.status?.split(",").map((s) => s.trim());
73
+ const result = await client.listBounties({
74
+ status,
75
+ repo: opts.repo,
76
+ limit: Number(opts.limit) || 20,
77
+ offset: Number(opts.offset) || 0,
78
+ });
79
+ if (result.bounties.length === 0)
80
+ return console.log("No bounties found.");
81
+ for (const b of result.bounties) {
82
+ const age = daysAgo(b.createdAt);
83
+ console.log(`${statusEmoji(b.status)} [${b.status}] ${b.repo}#${b.issueNumber}`);
84
+ console.log(` ID: ${b.bountyId}`);
85
+ console.log(` Creator: ${b.creatorGithub ?? shortAddr(b.creatorWallet)} | ${age}d ago`);
86
+ console.log(` Amount: ${formatWeiToEth(b.amountWei)} ETH`);
87
+ console.log();
88
+ }
89
+ console.log(`${result.bounties.length} bounties | chain=${result.chain.chainId}`);
90
+ }
91
+ async function cmdActive(args) {
92
+ const opts = parseArgs(args);
93
+ const result = await client.listBounties({
94
+ status: ["Open", "Claimed"],
95
+ repo: opts.repo,
96
+ limit: Number(opts.limit) || 20,
97
+ });
98
+ if (result.bounties.length === 0)
99
+ return console.log("No active bounties.");
100
+ for (const b of result.bounties) {
101
+ const age = daysAgo(b.createdAt);
102
+ console.log(`${statusEmoji(b.status)} [${b.status}] ${b.repo}#${b.issueNumber}`);
103
+ console.log(` ID: ${b.bountyId}`);
104
+ console.log(` Creator: ${b.creatorGithub ?? shortAddr(b.creatorWallet)} | ${age}d ago`);
105
+ console.log(` Amount: ${formatWeiToEth(b.amountWei)} ETH`);
106
+ console.log();
107
+ }
108
+ console.log(`${result.bounties.length} active bounties`);
109
+ }
110
+ async function cmdGet(identifier) {
111
+ let bountyId = identifier;
112
+ if (identifier.startsWith("github:") || identifier.startsWith("gitlab:")) {
113
+ bountyId = computeBountyId(identifier);
114
+ }
115
+ const result = await client.getBounty(bountyId);
116
+ const b = result.bounty;
117
+ console.log(`${statusEmoji(b.status)} ${b.status} — ${b.repo}#${b.issueNumber}`);
118
+ console.log(`ID: ${b.bountyId}`);
119
+ console.log(`Issue: ${b.issueUri}`);
120
+ console.log(`Amount: ${formatWeiToEth(b.amountWei)} ETH (${b.amountWei} wei)`);
121
+ console.log(`Creator: ${b.creatorGithub ?? b.creatorWallet}`);
122
+ console.log(`Claimant: ${b.claimantGithub ?? b.claimantWallet ?? "(none)"}`);
123
+ console.log(`Created: ${b.createdAt}`);
124
+ console.log(`Deadline: ${b.deadline}`);
125
+ console.log(`Create tx: ${b.createTx ?? "—"}`);
126
+ console.log(`Claim tx: ${b.claimTx ?? "—"}`);
127
+ console.log(`Submit tx: ${b.submitTx ?? "—"}`);
128
+ console.log(`Release tx: ${b.releaseTx ?? "—"}`);
129
+ }
130
+ async function cmdStats() {
131
+ const result = await client.getStats();
132
+ const s = result.stats;
133
+ console.log(`Total: ${s.total}`);
134
+ console.log(`Open: ${s.open}`);
135
+ console.log(`Claimed: ${s.claimed}`);
136
+ console.log(`Submitted: ${s.submitted}`);
137
+ console.log(`Completed: ${s.completed}`);
138
+ console.log(`Escrowed: ${formatWeiToEth(s.totalEscrowedWei)} ETH`);
139
+ console.log(`Paid: ${formatWeiToEth(s.totalPaidWei)} ETH`);
140
+ }
141
+ async function cmdId(uri) {
142
+ const id = computeBountyId(uri);
143
+ const parsed = parseIssueUri(uri);
144
+ console.log(`URI: ${uri}`);
145
+ console.log(`ID: ${id}`);
146
+ if (parsed) {
147
+ console.log(`Repo: ${parsed.repo}`);
148
+ console.log(`Issue: #${parsed.issueNumber}`);
149
+ console.log(`URL: https://github.com/${parsed.repo}/issues/${parsed.issueNumber}`);
150
+ }
151
+ }
152
+ async function cmdParse(uri) {
153
+ const parsed = parseIssueUri(uri);
154
+ if (!parsed) {
155
+ console.log(`Invalid URI: ${uri}`);
156
+ console.log("Expected format: github:owner/repo#123");
157
+ process.exit(1);
158
+ }
159
+ console.log(`Platform: github`);
160
+ console.log(`Repo: ${parsed.repo}`);
161
+ console.log(`Issue: #${parsed.issueNumber}`);
162
+ console.log(`URL: https://github.com/${parsed.repo}/issues/${parsed.issueNumber}`);
163
+ }
164
+ function cmdChain() {
165
+ const name = CHAIN_NAMES[CHAIN_ID] ?? `Chain ${CHAIN_ID}`;
166
+ console.log(`Chain: ${name} (${CHAIN_ID})`);
167
+ console.log(`RPC: ${RPC_URL}`);
168
+ console.log(`Escrow: ${ESCROW_ADDRESS}`);
169
+ }
170
+ // ─── Main ──────────────────────────────────────────────────────────────
171
+ const [, , cmd, ...args] = process.argv;
172
+ async function main() {
173
+ switch (cmd) {
174
+ case "list": return cmdList(args);
175
+ case "active": return cmdActive(args);
176
+ case "get": return cmdGet(args[0] || "");
177
+ case "stats": return cmdStats();
178
+ case "id": return cmdId(args[0] || "");
179
+ case "parse": return cmdParse(args[0] || "");
180
+ case "chain": return cmdChain();
181
+ default:
182
+ console.log(WELCOME);
183
+ if (cmd)
184
+ console.log(`Unknown command: ${cmd}`);
185
+ process.exit(cmd ? 1 : 0);
186
+ }
187
+ }
188
+ main().catch((err) => {
189
+ console.error(`Error: ${err.message}`);
190
+ process.exit(1);
191
+ });
192
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import "dotenv/config";
package/dist/index.js ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ import "dotenv/config";
3
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
+ import { createToolDefinitions } from "./tools.js";
6
+ const GITGRANT_API_URL = process.env.GITGRANT_API_URL || "https://api.gitgrant.app";
7
+ const RPC_URL = process.env.RPC_URL || "https://sepolia.base.org";
8
+ const ESCROW_ADDRESS = process.env.ESCROW_ADDRESS || "0x0000000000000000000000000000000000000000";
9
+ const CHAIN_ID = Number(process.env.CHAIN_ID || 84532);
10
+ const server = new McpServer({
11
+ name: "gitgrant",
12
+ version: "0.1.0",
13
+ description: "GitGrant — onchain bounties for open source. Create, claim, submit, and release bounties directly from AI agents.",
14
+ });
15
+ const tools = createToolDefinitions({
16
+ apiUrl: GITGRANT_API_URL,
17
+ rpcUrl: RPC_URL,
18
+ escrowAddress: ESCROW_ADDRESS,
19
+ chainId: CHAIN_ID,
20
+ });
21
+ for (const tool of tools) {
22
+ server.registerTool(tool.name, tool.config, tool.handler);
23
+ }
24
+ async function main() {
25
+ const transport = new StdioServerTransport();
26
+ await server.connect(transport);
27
+ console.error(`GitGrant MCP server started (api=${GITGRANT_API_URL}, chain=${CHAIN_ID})`);
28
+ }
29
+ main().catch((err) => {
30
+ console.error("Fatal: failed to start GitGrant MCP server", err);
31
+ process.exit(1);
32
+ });
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,0BAA0B,CAAC;AACpF,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,0BAA0B,CAAC;AAClE,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,4CAA4C,CAAC;AAClG,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,KAAK,CAAC,CAAC;AAEvD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,OAAO;IAChB,WAAW,EACT,mHAAmH;CACtH,CAAC,CAAC;AAEH,MAAM,KAAK,GAAG,qBAAqB,CAAC;IAClC,MAAM,EAAE,gBAAgB;IACxB,MAAM,EAAE,OAAO;IACf,aAAa,EAAE,cAA+B;IAC9C,OAAO,EAAE,QAAQ;CAClB,CAAC,CAAC;AAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;IACzB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAc,CAAC,CAAC;AACnE,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,oCAAoC,gBAAgB,WAAW,QAAQ,GAAG,CAAC,CAAC;AAC5F,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,4CAA4C,EAAE,GAAG,CAAC,CAAC;IACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { z } from "zod";
2
+ export interface ToolContext {
3
+ apiUrl: string;
4
+ rpcUrl: string;
5
+ escrowAddress: `0x${string}`;
6
+ chainId: number;
7
+ }
8
+ type Handler = (args: Record<string, unknown>) => Promise<{
9
+ content: Array<{
10
+ type: "text";
11
+ text: string;
12
+ }>;
13
+ }>;
14
+ export interface ToolDef {
15
+ name: string;
16
+ config: {
17
+ description: string;
18
+ inputSchema: Record<string, z.ZodTypeAny>;
19
+ };
20
+ handler: Handler;
21
+ }
22
+ export declare function createToolDefinitions(ctx: ToolContext): ToolDef[];
23
+ export {};
package/dist/tools.js ADDED
@@ -0,0 +1,215 @@
1
+ import { z } from "zod";
2
+ import { GitGrantClient, computeBountyId, parseIssueUri } from "@gitgrant/sdk";
3
+ let _client = null;
4
+ function getClient(ctx) {
5
+ if (!_client)
6
+ _client = new GitGrantClient({ baseUrl: ctx.apiUrl });
7
+ return _client;
8
+ }
9
+ export function createToolDefinitions(ctx) {
10
+ const client = () => getClient(ctx);
11
+ return [
12
+ // ── list_bounties ───────────────────────────────────────────────
13
+ {
14
+ name: "list_bounties",
15
+ config: {
16
+ description: "List all bounties on GitGrant. Supports filtering by status (Open, Claimed, Submitted, Completed, Disputed, Expired, Cancelled), repo (e.g. 'owner/repo'), and pagination with limit/offset.",
17
+ inputSchema: {
18
+ status: z.string().optional().describe("Filter by status. Use comma for multiple, e.g. 'Open,Claimed'."),
19
+ repo: z.string().optional().describe("Filter by GitHub repo, e.g. 'owner/repo'."),
20
+ limit: z.number().optional().describe("Max results (1-200, default 50)."),
21
+ offset: z.number().optional().describe("Pagination offset (default 0)."),
22
+ },
23
+ },
24
+ handler: async (args) => {
25
+ const result = await client().listBounties({
26
+ status: args.status ? args.status.split(",").map((s) => s.trim()) : undefined,
27
+ repo: args.repo,
28
+ limit: args.limit,
29
+ offset: args.offset,
30
+ });
31
+ const lines = result.bounties.map((b) => {
32
+ const age = daysAgo(b.createdAt);
33
+ return `- [${b.status}] \`${b.bountyId.slice(0, 10)}...\` | ${b.repo}#${b.issueNumber} | ${b.creatorGithub ?? shortAddr(b.creatorWallet)} | ${age}d ago`;
34
+ });
35
+ return {
36
+ content: [{ type: "text", text: `Found ${result.bounties.length} bounties (chain=${result.chain.chainId}, escrow=${result.chain.escrowAddress}):\n\n${lines.join("\n") || "(none)"}` }],
37
+ };
38
+ },
39
+ },
40
+ // ── get_bounty ──────────────────────────────────────────────────
41
+ {
42
+ name: "get_bounty",
43
+ config: {
44
+ description: "Get full details for a single bounty by its ID (bytes32 hex) or by its issue URI (e.g. 'github:owner/repo#123').",
45
+ inputSchema: {
46
+ idOrUri: z.string().describe("Bounty ID (0x... bytes32) or issue URI (github:owner/repo#123)."),
47
+ },
48
+ },
49
+ handler: async (args) => {
50
+ let bountyId = args.idOrUri;
51
+ if (bountyId.startsWith("github:") || bountyId.startsWith("gitlab:")) {
52
+ bountyId = computeBountyId(bountyId);
53
+ }
54
+ const result = await client().getBounty(bountyId);
55
+ const b = result.bounty;
56
+ return {
57
+ content: [{
58
+ type: "text",
59
+ text: [
60
+ `**Bounty ${b.bountyId}**`,
61
+ `- Issue: ${b.issueUri} (${b.repo}#${b.issueNumber})`,
62
+ `- Status: ${b.status}`,
63
+ `- Amount: ${b.amountWei} wei`,
64
+ `- Creator: ${b.creatorGithub ?? b.creatorWallet}`,
65
+ `- Claimant: ${b.claimantGithub ?? b.claimantWallet ?? "(none)"}`,
66
+ `- Created: ${b.createdAt}`,
67
+ `- Deadline: ${b.deadline}`,
68
+ `- Tx: create=${b.createTx ?? "—"}, claim=${b.claimTx ?? "—"}, submit=${b.submitTx ?? "—"}, release=${b.releaseTx ?? "—"}`,
69
+ ].join("\n"),
70
+ }],
71
+ };
72
+ },
73
+ },
74
+ // ── get_stats ───────────────────────────────────────────────────
75
+ {
76
+ name: "get_stats",
77
+ config: {
78
+ description: "Get aggregate GitGrant platform statistics (total, per-status counts, total value escrowed and paid).",
79
+ inputSchema: {},
80
+ },
81
+ handler: async () => {
82
+ const result = await client().getStats();
83
+ const s = result.stats;
84
+ return {
85
+ content: [{
86
+ type: "text",
87
+ text: [
88
+ `**GitGrant Platform Stats**`,
89
+ `- Total bounties: ${s.total}`,
90
+ `- Open: ${s.open}`,
91
+ `- Claimed: ${s.claimed}`,
92
+ `- Submitted: ${s.submitted}`,
93
+ `- Completed: ${s.completed}`,
94
+ `- Total escrowed: ${s.totalEscrowedWei} wei`,
95
+ `- Total paid: ${s.totalPaidWei} wei`,
96
+ ].join("\n"),
97
+ }],
98
+ };
99
+ },
100
+ },
101
+ // ── compute_bounty_id ───────────────────────────────────────────
102
+ {
103
+ name: "compute_bounty_id",
104
+ config: {
105
+ description: "Compute the deterministic bytes32 bounty ID from an issue URI. Format: 'github:owner/repo#issueNumber'.",
106
+ inputSchema: {
107
+ issueUri: z.string().describe("Issue URI, e.g. 'github:owner/repo#123'."),
108
+ },
109
+ },
110
+ handler: async (args) => {
111
+ const uri = args.issueUri;
112
+ const id = computeBountyId(uri);
113
+ const parsed = parseIssueUri(uri);
114
+ return {
115
+ content: [{
116
+ type: "text",
117
+ text: parsed
118
+ ? `**Bounty ID:** \`${id}\`\n- Repo: ${parsed.repo}\n- Issue: #${parsed.issueNumber}\n- URL: https://github.com/${parsed.repo}/issues/${parsed.issueNumber}`
119
+ : `**Bounty ID:** \`${id}\`\n- URI: ${uri}`,
120
+ }],
121
+ };
122
+ },
123
+ },
124
+ // ── parse_issue_uri ─────────────────────────────────────────────
125
+ {
126
+ name: "parse_issue_uri",
127
+ config: {
128
+ description: "Parse a GitGrant issue URI into components (platform, repo, issue number). Supports github: and gitlab: prefixes.",
129
+ inputSchema: {
130
+ issueUri: z.string().describe("Issue URI, e.g. 'github:owner/repo#123'."),
131
+ },
132
+ },
133
+ handler: async (args) => {
134
+ const uri = args.issueUri;
135
+ const parsed = parseIssueUri(uri);
136
+ if (!parsed) {
137
+ return {
138
+ content: [{ type: "text", text: `Invalid issue URI: "${uri}". Expected format: github:owner/repo#123` }],
139
+ };
140
+ }
141
+ return {
142
+ content: [{
143
+ type: "text",
144
+ text: `- Platform: github\n- Repo: ${parsed.repo}\n- Issue: #${parsed.issueNumber}\n- URL: https://github.com/${parsed.repo}/issues/${parsed.issueNumber}`,
145
+ }],
146
+ };
147
+ },
148
+ },
149
+ // ── get_chain_info ──────────────────────────────────────────────
150
+ {
151
+ name: "get_chain_info",
152
+ config: {
153
+ description: "Get the current chain configuration (chain ID, RPC URL, escrow contract address).",
154
+ inputSchema: {},
155
+ },
156
+ handler: async () => {
157
+ const chainNames = {
158
+ 8453: "Base Mainnet",
159
+ 84532: "Base Sepolia (testnet)",
160
+ 31337: "Local / Foundry",
161
+ };
162
+ const name = chainNames[ctx.chainId] ?? `Chain ${ctx.chainId}`;
163
+ return {
164
+ content: [{
165
+ type: "text",
166
+ text: [
167
+ `**Chain:** ${name} (${ctx.chainId})`,
168
+ `- RPC: ${ctx.rpcUrl}`,
169
+ `- Escrow contract: ${ctx.escrowAddress}`,
170
+ ].join("\n"),
171
+ }],
172
+ };
173
+ },
174
+ },
175
+ // ── list_active_bounties ────────────────────────────────────────
176
+ {
177
+ name: "list_active_bounties",
178
+ config: {
179
+ description: "List only active (workable) bounties — those with status Open or Claimed. These are bounties contributors can still engage with.",
180
+ inputSchema: {
181
+ repo: z.string().optional().describe("Filter by GitHub repo, e.g. 'owner/repo'."),
182
+ limit: z.number().optional().describe("Max results (default 50)."),
183
+ },
184
+ },
185
+ handler: async (args) => {
186
+ const result = await client().listBounties({
187
+ status: ["Open", "Claimed"],
188
+ repo: args.repo,
189
+ limit: args.limit,
190
+ });
191
+ const lines = result.bounties.map((b) => {
192
+ const age = daysAgo(b.createdAt);
193
+ return `- [${b.status}] ${b.repo}#${b.issueNumber} | ${b.creatorGithub ?? shortAddr(b.creatorWallet)} | ${age}d ago | \`${b.bountyId.slice(0, 10)}...\``;
194
+ });
195
+ return {
196
+ content: [{
197
+ type: "text",
198
+ text: `${result.bounties.length} active bounties:\n\n${lines.join("\n") || "(none)"}`,
199
+ }],
200
+ };
201
+ },
202
+ },
203
+ ];
204
+ }
205
+ // ─── Helpers ───────────────────────────────────────────────────────────
206
+ function daysAgo(iso) {
207
+ const diff = Date.now() - new Date(iso).getTime();
208
+ return Math.floor(diff / (1000 * 60 * 60 * 24));
209
+ }
210
+ function shortAddr(addr) {
211
+ if (addr.length < 10)
212
+ return addr;
213
+ return `${addr.slice(0, 6)}...${addr.slice(-4)}`;
214
+ }
215
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@gitgrant/mcp",
3
+ "version": "0.1.0",
4
+ "description": "GitGrant CLI & MCP server — onchain bounties for open source",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "bin": {
8
+ "gitgrant": "./dist/cli.js",
9
+ "gitgrant-mcp": "./dist/index.js"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "dev": "tsx src/index.ts",
14
+ "start": "node dist/index.js",
15
+ "typecheck": "tsc --noEmit"
16
+ },
17
+ "dependencies": {
18
+ "@gitgrant/sdk": "^0.2.0",
19
+ "@modelcontextprotocol/sdk": "^1.12.0",
20
+ "dotenv": "^16.4.0",
21
+ "viem": "^2.23.0",
22
+ "zod": "^3.24.0"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "^22.10.0",
26
+ "tsx": "^4.19.0",
27
+ "typescript": "^5.7.0"
28
+ },
29
+ "keywords": ["gitgrant", "mcp", "ai-agent", "bounty", "web3"],
30
+ "license": "MIT"
31
+ }