@ldraney/github-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/README.md +131 -0
- package/dist/auth/local-server.d.ts +16 -0
- package/dist/auth/local-server.js +146 -0
- package/dist/auth/oauth-device-flow.d.ts +20 -0
- package/dist/auth/oauth-device-flow.d.ts.map +1 -0
- package/dist/auth/oauth-device-flow.js +141 -0
- package/dist/auth/oauth-device-flow.js.map +1 -0
- package/dist/auth/oauth-flow.d.ts +20 -0
- package/dist/auth/oauth-flow.js +95 -0
- package/dist/auth/token-storage.d.ts +16 -0
- package/dist/auth/token-storage.d.ts.map +1 -0
- package/dist/auth/token-storage.js +33 -0
- package/dist/auth/token-storage.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +85 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/webhooks.d.ts +15 -0
- package/dist/resources/webhooks.d.ts.map +1 -0
- package/dist/resources/webhooks.js +194 -0
- package/dist/resources/webhooks.js.map +1 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +247 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/categories/actions.d.ts +5 -0
- package/dist/tools/categories/actions.d.ts.map +1 -0
- package/dist/tools/categories/actions.js +395 -0
- package/dist/tools/categories/actions.js.map +1 -0
- package/dist/tools/categories/gists.d.ts +5 -0
- package/dist/tools/categories/gists.d.ts.map +1 -0
- package/dist/tools/categories/gists.js +315 -0
- package/dist/tools/categories/gists.js.map +1 -0
- package/dist/tools/categories/issues.d.ts +5 -0
- package/dist/tools/categories/issues.d.ts.map +1 -0
- package/dist/tools/categories/issues.js +425 -0
- package/dist/tools/categories/issues.js.map +1 -0
- package/dist/tools/categories/orgs.d.ts +5 -0
- package/dist/tools/categories/orgs.d.ts.map +1 -0
- package/dist/tools/categories/orgs.js +452 -0
- package/dist/tools/categories/orgs.js.map +1 -0
- package/dist/tools/categories/pulls.d.ts +5 -0
- package/dist/tools/categories/pulls.d.ts.map +1 -0
- package/dist/tools/categories/pulls.js +370 -0
- package/dist/tools/categories/pulls.js.map +1 -0
- package/dist/tools/categories/repos.d.ts +5 -0
- package/dist/tools/categories/repos.d.ts.map +1 -0
- package/dist/tools/categories/repos.js +392 -0
- package/dist/tools/categories/repos.js.map +1 -0
- package/dist/tools/categories/search.d.ts +5 -0
- package/dist/tools/categories/search.d.ts.map +1 -0
- package/dist/tools/categories/search.js +217 -0
- package/dist/tools/categories/search.js.map +1 -0
- package/dist/tools/categories/users.d.ts +5 -0
- package/dist/tools/categories/users.d.ts.map +1 -0
- package/dist/tools/categories/users.js +247 -0
- package/dist/tools/categories/users.js.map +1 -0
- package/dist/tools/generator.d.ts +19 -0
- package/dist/tools/generator.d.ts.map +1 -0
- package/dist/tools/generator.js +69 -0
- package/dist/tools/generator.js.map +1 -0
- package/dist/webhooks/event-queue.d.ts +54 -0
- package/dist/webhooks/event-queue.d.ts.map +1 -0
- package/dist/webhooks/event-queue.js +117 -0
- package/dist/webhooks/event-queue.js.map +1 -0
- package/dist/webhooks/smee-client.d.ts +27 -0
- package/dist/webhooks/smee-client.d.ts.map +1 -0
- package/dist/webhooks/smee-client.js +153 -0
- package/dist/webhooks/smee-client.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import SmeeClient from 'smee-client';
|
|
2
|
+
import { eventQueue } from './event-queue.js';
|
|
3
|
+
let smeeClient = null;
|
|
4
|
+
let smeeUrl = null;
|
|
5
|
+
/**
|
|
6
|
+
* Start the smee.io webhook client
|
|
7
|
+
*/
|
|
8
|
+
export function startWebhookClient(url) {
|
|
9
|
+
if (smeeClient) {
|
|
10
|
+
console.error('Webhook client already running');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
smeeUrl = url;
|
|
14
|
+
smeeClient = new SmeeClient({
|
|
15
|
+
source: url,
|
|
16
|
+
target: 'http://localhost:0/webhook', // Dummy target, we intercept events
|
|
17
|
+
logger: {
|
|
18
|
+
info: (msg) => console.error(`[smee] ${msg}`),
|
|
19
|
+
error: (msg) => console.error(`[smee:error] ${msg}`),
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
const events = smeeClient.start();
|
|
23
|
+
events.addEventListener('message', (event) => {
|
|
24
|
+
try {
|
|
25
|
+
const data = JSON.parse(event.data);
|
|
26
|
+
handleWebhookEvent(data);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Ignore parsing errors
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
events.addEventListener('error', () => {
|
|
33
|
+
console.error('[smee:error] Connection error');
|
|
34
|
+
});
|
|
35
|
+
console.error(`Webhook client started: ${url}`);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Stop the webhook client
|
|
39
|
+
*/
|
|
40
|
+
export function stopWebhookClient() {
|
|
41
|
+
if (smeeClient) {
|
|
42
|
+
// SmeeClient doesn't have a stop method, but we can clear the reference
|
|
43
|
+
smeeClient = null;
|
|
44
|
+
smeeUrl = null;
|
|
45
|
+
console.error('Webhook client stopped');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get the current smee URL
|
|
50
|
+
*/
|
|
51
|
+
export function getSmeeUrl() {
|
|
52
|
+
return smeeUrl;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Handle incoming webhook event
|
|
56
|
+
*/
|
|
57
|
+
function handleWebhookEvent(rawEvent) {
|
|
58
|
+
try {
|
|
59
|
+
const eventType = rawEvent['x-github-event'] || 'unknown';
|
|
60
|
+
const deliveryId = rawEvent['x-github-delivery'] || crypto.randomUUID();
|
|
61
|
+
const body = rawEvent.body || rawEvent;
|
|
62
|
+
const event = {
|
|
63
|
+
id: deliveryId,
|
|
64
|
+
type: eventType,
|
|
65
|
+
action: body.action,
|
|
66
|
+
payload: body,
|
|
67
|
+
receivedAt: new Date(),
|
|
68
|
+
repository: body.repository ? {
|
|
69
|
+
owner: body.repository.owner
|
|
70
|
+
? body.repository.owner.login
|
|
71
|
+
: '',
|
|
72
|
+
name: body.repository.name || '',
|
|
73
|
+
full_name: body.repository.full_name || '',
|
|
74
|
+
} : undefined,
|
|
75
|
+
sender: body.sender ? {
|
|
76
|
+
login: body.sender.login || '',
|
|
77
|
+
id: body.sender.id || 0,
|
|
78
|
+
} : undefined,
|
|
79
|
+
};
|
|
80
|
+
eventQueue.push(event);
|
|
81
|
+
const action = event.action ? ` (${event.action})` : '';
|
|
82
|
+
const repo = event.repository?.full_name ? ` in ${event.repository.full_name}` : '';
|
|
83
|
+
console.error(`[webhook] ${eventType}${action}${repo}`);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.error('[webhook:error] Failed to process event:', error);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get webhook resources for MCP
|
|
91
|
+
*/
|
|
92
|
+
export function getWebhookResources() {
|
|
93
|
+
const resources = [
|
|
94
|
+
{
|
|
95
|
+
uri: 'github://webhooks/all',
|
|
96
|
+
name: 'All Webhook Events',
|
|
97
|
+
description: 'All recent webhook events from GitHub',
|
|
98
|
+
mimeType: 'application/json',
|
|
99
|
+
},
|
|
100
|
+
];
|
|
101
|
+
// Add resources for each event type that has events
|
|
102
|
+
const eventTypes = eventQueue.getEventTypes();
|
|
103
|
+
for (const type of eventTypes) {
|
|
104
|
+
resources.push({
|
|
105
|
+
uri: `github://webhooks/${type}`,
|
|
106
|
+
name: `${type} Events`,
|
|
107
|
+
description: `Recent ${type} webhook events`,
|
|
108
|
+
mimeType: 'application/json',
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// Add common event types even if empty
|
|
112
|
+
const commonTypes = ['push', 'pull_request', 'issues', 'issue_comment', 'release', 'workflow_run'];
|
|
113
|
+
for (const type of commonTypes) {
|
|
114
|
+
if (!eventTypes.includes(type)) {
|
|
115
|
+
resources.push({
|
|
116
|
+
uri: `github://webhooks/${type}`,
|
|
117
|
+
name: `${type} Events`,
|
|
118
|
+
description: `Recent ${type} webhook events (none received yet)`,
|
|
119
|
+
mimeType: 'application/json',
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return resources;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get webhook events for a resource URI
|
|
127
|
+
*/
|
|
128
|
+
export function getWebhookEvents(uri) {
|
|
129
|
+
const match = uri.match(/^github:\/\/webhooks\/(.+)$/);
|
|
130
|
+
if (!match) {
|
|
131
|
+
return { error: 'Invalid webhook resource URI' };
|
|
132
|
+
}
|
|
133
|
+
const type = match[1];
|
|
134
|
+
if (type === 'all') {
|
|
135
|
+
return eventQueue.getAll();
|
|
136
|
+
}
|
|
137
|
+
return eventQueue.getByType(type);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Generate a new smee.io channel URL
|
|
141
|
+
*/
|
|
142
|
+
export async function createSmeeChannel() {
|
|
143
|
+
const response = await fetch('https://smee.io/new', {
|
|
144
|
+
method: 'HEAD',
|
|
145
|
+
redirect: 'manual',
|
|
146
|
+
});
|
|
147
|
+
const location = response.headers.get('location');
|
|
148
|
+
if (!location) {
|
|
149
|
+
throw new Error('Failed to create smee.io channel');
|
|
150
|
+
}
|
|
151
|
+
return location;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=smee-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smee-client.js","sourceRoot":"","sources":["../../src/webhooks/smee-client.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ldraney/github-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "GitHub MCP server with OAuth and 800+ API endpoints",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"github-mcp": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"start": "node dist/index.js",
|
|
16
|
+
"dev": "tsx watch src/index.ts",
|
|
17
|
+
"lint": "eslint src/",
|
|
18
|
+
"typecheck": "tsc --noEmit",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"github",
|
|
23
|
+
"mcp",
|
|
24
|
+
"model-context-protocol",
|
|
25
|
+
"oauth",
|
|
26
|
+
"api",
|
|
27
|
+
"claude-desktop"
|
|
28
|
+
],
|
|
29
|
+
"author": "ldraney",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/ldraney/github-mcp.git"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
40
|
+
"@octokit/rest": "^21.0.0",
|
|
41
|
+
"commander": "^12.1.0",
|
|
42
|
+
"keytar": "^7.9.0",
|
|
43
|
+
"open": "^10.1.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "^22.10.0",
|
|
47
|
+
"tsx": "^4.19.0",
|
|
48
|
+
"typescript": "^5.6.0"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=20"
|
|
52
|
+
}
|
|
53
|
+
}
|