adoptai-mcp 1.0.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 +70 -0
- package/bin/adoptai-mcp.js +2 -0
- package/dist/apps/canva.js +1 -0
- package/dist/apps/figma.js +1 -0
- package/dist/apps/github.js +2 -0
- package/dist/apps/notion.js +1 -0
- package/dist/apps/registry.js +20 -0
- package/dist/apps/salesforce.js +1 -0
- package/dist/cli/add.js +532 -0
- package/dist/cli/index.js +39 -0
- package/dist/cli/list.js +19 -0
- package/dist/cli/remove.js +37 -0
- package/dist/cli/serve.js +27 -0
- package/dist/cli/status.js +24 -0
- package/dist/config/clients.js +118 -0
- package/dist/config/credentials.js +34 -0
- package/dist/core/auth-manager.js +237 -0
- package/dist/core/config-writer.js +161 -0
- package/dist/core/doctor.js +199 -0
- package/dist/core/package.json +3 -0
- package/dist/core/server-base.js +81 -0
- package/dist/integrations/canva/.env +3 -0
- package/dist/integrations/canva/auth.js +287 -0
- package/dist/integrations/canva/env.js +9 -0
- package/dist/integrations/canva/index.js +12 -0
- package/dist/integrations/canva/package.json +31 -0
- package/dist/integrations/canva/publish-to-adoptai.js +365 -0
- package/dist/integrations/canva/setup.js +90 -0
- package/dist/integrations/canva/tools.js +1315 -0
- package/dist/integrations/canva/tools.original.js +1315 -0
- package/dist/integrations/figma/auth.js +48 -0
- package/dist/integrations/figma/index.js +11 -0
- package/dist/integrations/figma/package.json +27 -0
- package/dist/integrations/figma/publish-to-adoptai.js +384 -0
- package/dist/integrations/figma/setup.js +90 -0
- package/dist/integrations/figma/tools.js +1137 -0
- package/dist/integrations/github/auth.js +53 -0
- package/dist/integrations/github/index.js +11 -0
- package/dist/integrations/github/package.json +28 -0
- package/dist/integrations/github/publish-to-adoptai.js +240 -0
- package/dist/integrations/github/setup.js +103 -0
- package/dist/integrations/github/tools.js +78 -0
- package/dist/integrations/github-actions/auth.js +53 -0
- package/dist/integrations/github-actions/index.js +11 -0
- package/dist/integrations/github-actions/package.json +27 -0
- package/dist/integrations/github-actions/setup.js +103 -0
- package/dist/integrations/github-actions/tools.js +5642 -0
- package/dist/integrations/github-activity/auth.js +53 -0
- package/dist/integrations/github-activity/index.js +11 -0
- package/dist/integrations/github-activity/package.json +27 -0
- package/dist/integrations/github-activity/setup.js +103 -0
- package/dist/integrations/github-activity/tools.js +925 -0
- package/dist/integrations/github-apps/auth.js +53 -0
- package/dist/integrations/github-apps/index.js +11 -0
- package/dist/integrations/github-apps/package.json +27 -0
- package/dist/integrations/github-apps/setup.js +103 -0
- package/dist/integrations/github-apps/tools.js +791 -0
- package/dist/integrations/github-billing/auth.js +53 -0
- package/dist/integrations/github-billing/index.js +11 -0
- package/dist/integrations/github-billing/package.json +27 -0
- package/dist/integrations/github-billing/setup.js +103 -0
- package/dist/integrations/github-billing/tools.js +438 -0
- package/dist/integrations/github-checks/auth.js +53 -0
- package/dist/integrations/github-checks/index.js +11 -0
- package/dist/integrations/github-checks/package.json +27 -0
- package/dist/integrations/github-checks/setup.js +103 -0
- package/dist/integrations/github-checks/tools.js +607 -0
- package/dist/integrations/github-code-scanning/auth.js +53 -0
- package/dist/integrations/github-code-scanning/index.js +11 -0
- package/dist/integrations/github-code-scanning/package.json +27 -0
- package/dist/integrations/github-code-scanning/setup.js +103 -0
- package/dist/integrations/github-code-scanning/tools.js +987 -0
- package/dist/integrations/github-dependabot/auth.js +53 -0
- package/dist/integrations/github-dependabot/index.js +11 -0
- package/dist/integrations/github-dependabot/package.json +27 -0
- package/dist/integrations/github-dependabot/setup.js +103 -0
- package/dist/integrations/github-dependabot/tools.js +915 -0
- package/dist/integrations/github-gists/auth.js +53 -0
- package/dist/integrations/github-gists/index.js +11 -0
- package/dist/integrations/github-gists/package.json +27 -0
- package/dist/integrations/github-gists/setup.js +103 -0
- package/dist/integrations/github-gists/tools.js +545 -0
- package/dist/integrations/github-git/auth.js +53 -0
- package/dist/integrations/github-git/index.js +11 -0
- package/dist/integrations/github-git/package.json +27 -0
- package/dist/integrations/github-git/setup.js +103 -0
- package/dist/integrations/github-git/tools.js +513 -0
- package/dist/integrations/github-issues/auth.js +53 -0
- package/dist/integrations/github-issues/index.js +11 -0
- package/dist/integrations/github-issues/package.json +27 -0
- package/dist/integrations/github-issues/setup.js +103 -0
- package/dist/integrations/github-issues/tools.js +2232 -0
- package/dist/integrations/github-orgs/auth.js +53 -0
- package/dist/integrations/github-orgs/index.js +11 -0
- package/dist/integrations/github-orgs/package.json +27 -0
- package/dist/integrations/github-orgs/setup.js +103 -0
- package/dist/integrations/github-orgs/tools.js +3512 -0
- package/dist/integrations/github-packages/auth.js +53 -0
- package/dist/integrations/github-packages/index.js +11 -0
- package/dist/integrations/github-packages/package.json +27 -0
- package/dist/integrations/github-packages/setup.js +103 -0
- package/dist/integrations/github-packages/tools.js +1088 -0
- package/dist/integrations/github-pulls/auth.js +53 -0
- package/dist/integrations/github-pulls/index.js +11 -0
- package/dist/integrations/github-pulls/package.json +27 -0
- package/dist/integrations/github-pulls/setup.js +103 -0
- package/dist/integrations/github-pulls/tools.js +1252 -0
- package/dist/integrations/github-reactions/auth.js +53 -0
- package/dist/integrations/github-reactions/index.js +11 -0
- package/dist/integrations/github-reactions/package.json +27 -0
- package/dist/integrations/github-reactions/setup.js +103 -0
- package/dist/integrations/github-reactions/tools.js +706 -0
- package/dist/integrations/github-repos/auth.js +53 -0
- package/dist/integrations/github-repos/index.js +11 -0
- package/dist/integrations/github-repos/package.json +27 -0
- package/dist/integrations/github-repos/setup.js +103 -0
- package/dist/integrations/github-repos/tools.js +7286 -0
- package/dist/integrations/github-search/auth.js +53 -0
- package/dist/integrations/github-search/index.js +11 -0
- package/dist/integrations/github-search/package.json +27 -0
- package/dist/integrations/github-search/setup.js +103 -0
- package/dist/integrations/github-search/tools.js +370 -0
- package/dist/integrations/github-teams/auth.js +53 -0
- package/dist/integrations/github-teams/index.js +11 -0
- package/dist/integrations/github-teams/package.json +27 -0
- package/dist/integrations/github-teams/setup.js +103 -0
- package/dist/integrations/github-teams/tools.js +633 -0
- package/dist/integrations/github-users/auth.js +53 -0
- package/dist/integrations/github-users/index.js +11 -0
- package/dist/integrations/github-users/package.json +27 -0
- package/dist/integrations/github-users/setup.js +103 -0
- package/dist/integrations/github-users/tools.js +1118 -0
- package/dist/integrations/notion/api.js +108 -0
- package/dist/integrations/notion/auth.js +59 -0
- package/dist/integrations/notion/endpoints.json +630 -0
- package/dist/integrations/notion/index.js +11 -0
- package/dist/integrations/notion/package.json +33 -0
- package/dist/integrations/notion/publish-to-adoptai.js +271 -0
- package/dist/integrations/notion/scripts/generate-endpoints.mjs +306 -0
- package/dist/integrations/notion/setup.js +89 -0
- package/dist/integrations/notion/tools.js +586 -0
- package/dist/integrations/notion/tools.original.js +568 -0
- package/dist/integrations/salesforce/.env +8 -0
- package/dist/integrations/salesforce/.env.example +15 -0
- package/dist/integrations/salesforce/auth.js +311 -0
- package/dist/integrations/salesforce/endpoints.json +1359 -0
- package/dist/integrations/salesforce/env.js +9 -0
- package/dist/integrations/salesforce/index.js +12 -0
- package/dist/integrations/salesforce/package.json +42 -0
- package/dist/integrations/salesforce/publish-smart-specs.js +890 -0
- package/dist/integrations/salesforce/publish-to-adoptai.js +386 -0
- package/dist/integrations/salesforce/scripts/extract-postman.mjs +222 -0
- package/dist/integrations/salesforce/setup.js +112 -0
- package/dist/integrations/salesforce/tools.js +4544 -0
- package/dist/integrations/salesforce/tools.original.js +4487 -0
- package/dist/server/mcp-server.js +50 -0
- package/dist/server/tool-loader.js +47 -0
- package/dist/specs/figma-api.json +13621 -0
- package/dist/specs/split/salesforce-auth.json +3931 -0
- package/dist/specs/split/salesforce-bulk-v1.json +1489 -0
- package/dist/specs/split/salesforce-bulk-v2.json +1951 -0
- package/dist/specs/split/salesforce-composite.json +1246 -0
- package/dist/specs/split/salesforce-connect.json +11639 -0
- package/dist/specs/split/salesforce-einstein-prediction-service.json +576 -0
- package/dist/specs/split/salesforce-event-platform.json +2682 -0
- package/dist/specs/split/salesforce-graphql.json +1754 -0
- package/dist/specs/split/salesforce-industries.json +4115 -0
- package/dist/specs/split/salesforce-metadata.json +555 -0
- package/dist/specs/split/salesforce-rest.json +4798 -0
- package/dist/specs/split/salesforce-soap.json +210 -0
- package/dist/specs/split/salesforce-subscription-management.json +1299 -0
- package/dist/specs/split/salesforce-tooling.json +2026 -0
- package/dist/specs/split/salesforce-ui.json +7426 -0
- package/package.json +47 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { saveCredentials, getCredentials } from '../../core/auth-manager.js';
|
|
2
|
+
import readline from 'readline';
|
|
3
|
+
|
|
4
|
+
const APP_ID = 'github';
|
|
5
|
+
|
|
6
|
+
export async function runAuth() {
|
|
7
|
+
const rl = readline.createInterface({
|
|
8
|
+
input: process.stdin,
|
|
9
|
+
output: process.stdout,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
console.log(`
|
|
13
|
+
┌─────────────────────────────────────────────┐
|
|
14
|
+
│ GitHub Authentication │
|
|
15
|
+
│ │
|
|
16
|
+
│ Use a GitHub Personal Access Token (PAT). │
|
|
17
|
+
│ Create one in Settings -> Developer │
|
|
18
|
+
│ settings -> Personal access tokens. │
|
|
19
|
+
└─────────────────────────────────────────────┘
|
|
20
|
+
`);
|
|
21
|
+
|
|
22
|
+
const token = await new Promise((resolve) => {
|
|
23
|
+
rl.question('Paste your GitHub PAT: ', (answer) => {
|
|
24
|
+
rl.close();
|
|
25
|
+
resolve(answer.trim());
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
if (!token || token.length < 10) {
|
|
30
|
+
throw new Error('Invalid token');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
saveCredentials(APP_ID, {
|
|
34
|
+
token,
|
|
35
|
+
tokenType: 'bearer',
|
|
36
|
+
expiresAt: null,
|
|
37
|
+
savedAt: new Date().toISOString(),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
console.log('✅ Token saved for GitHub');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function getToken() {
|
|
44
|
+
return getCredentials(APP_ID)?.token || null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function buildAuthHeaders() {
|
|
48
|
+
const token = getToken();
|
|
49
|
+
if (!token) {
|
|
50
|
+
throw new Error('Not authenticated. Run: npx adoptai-github-mcp --client cursor');
|
|
51
|
+
}
|
|
52
|
+
return { Authorization: 'Bearer ' + token };
|
|
53
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "adoptai-github-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Unified GitHub MCP server aggregating all generated GitHub category tools.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"adoptai-github-mcp": "./setup.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node index.js",
|
|
12
|
+
"setup": "node setup.js",
|
|
13
|
+
"publish-adopt": "node publish-to-adoptai.js"
|
|
14
|
+
},
|
|
15
|
+
"keywords": ["mcp", "github", "ai", "cursor", "claude", "adopt.ai"],
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
19
|
+
"axios": "^1.6.0"
|
|
20
|
+
},
|
|
21
|
+
"adoptai": {
|
|
22
|
+
"appId": "github",
|
|
23
|
+
"toolCount": 845,
|
|
24
|
+
"sourceFormat": "openapi_3.1_aggregated",
|
|
25
|
+
"authType": "bearer",
|
|
26
|
+
"generatedAt": "2026-03-26T12:00:00.000Z"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Publish integrations/github/tools.js (aggregated GitHub REST tools) to adopt.ai.
|
|
4
|
+
* See Docs/publisher.md — env: ADOPTAI_BEARER_TOKEN, ADOPTAI_INTEGRATION_ID, ADOPTAI_API_BASE_URL (optional).
|
|
5
|
+
*
|
|
6
|
+
* node publish-to-adoptai.js
|
|
7
|
+
*/
|
|
8
|
+
import axios from 'axios';
|
|
9
|
+
import { existsSync, readFileSync } from 'fs';
|
|
10
|
+
import { dirname, resolve } from 'path';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
import { tools } from './tools.js';
|
|
13
|
+
|
|
14
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
|
|
16
|
+
function loadEnvFile(filePath) {
|
|
17
|
+
if (!existsSync(filePath)) return;
|
|
18
|
+
const text = readFileSync(filePath, 'utf8');
|
|
19
|
+
for (const line of text.split('\n')) {
|
|
20
|
+
const t = line.trim();
|
|
21
|
+
if (!t || t.startsWith('#')) continue;
|
|
22
|
+
const eq = t.indexOf('=');
|
|
23
|
+
if (eq <= 0) continue;
|
|
24
|
+
const key = t.slice(0, eq).trim();
|
|
25
|
+
let val = t.slice(eq + 1).trim();
|
|
26
|
+
if (
|
|
27
|
+
(val.startsWith('"') && val.endsWith('"')) ||
|
|
28
|
+
(val.startsWith("'") && val.endsWith("'"))
|
|
29
|
+
) {
|
|
30
|
+
val = val.slice(1, -1);
|
|
31
|
+
}
|
|
32
|
+
process.env[key] = val;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
loadEnvFile(resolve(__dirname, '../../.env'));
|
|
37
|
+
|
|
38
|
+
const ADOPTAI_API_BASE = (
|
|
39
|
+
process.env.ADOPTAI_API_BASE_URL || 'https://api.adopt.ai'
|
|
40
|
+
).replace(/\/$/, '');
|
|
41
|
+
const ADOPTAI_API = `${ADOPTAI_API_BASE}/v1/mcp-integrations/add-update-integration-tool`;
|
|
42
|
+
const PUBLISH_DELAY_MS = Number(process.env.ADOPTAI_PUBLISH_DELAY_MS) || 300;
|
|
43
|
+
|
|
44
|
+
const BEARER_TOKEN = process.env.ADOPTAI_BEARER_TOKEN;
|
|
45
|
+
const INTEGRATION_ID = process.env.ADOPTAI_INTEGRATION_ID;
|
|
46
|
+
|
|
47
|
+
const BASE_URL = 'https://api.github.com';
|
|
48
|
+
const APP_NAME = 'GITHUB';
|
|
49
|
+
|
|
50
|
+
if (!BEARER_TOKEN) throw new Error('ADOPTAI_BEARER_TOKEN not set in ../../.env');
|
|
51
|
+
if (!INTEGRATION_ID) throw new Error('ADOPTAI_INTEGRATION_ID not set in ../../.env');
|
|
52
|
+
|
|
53
|
+
function pathParamsFromTemplate(pathTemplate) {
|
|
54
|
+
return [...String(pathTemplate).matchAll(/\{([^}]+)\}/g)].map((m) => m[1]);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function mapArgType(prop) {
|
|
58
|
+
if (!prop || typeof prop !== 'object') return 'string';
|
|
59
|
+
const t = prop.type;
|
|
60
|
+
if (t === 'integer') return 'number';
|
|
61
|
+
if (t === 'number' || t === 'boolean' || t === 'object' || t === 'array') {
|
|
62
|
+
return t;
|
|
63
|
+
}
|
|
64
|
+
return 'string';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function placeholderMap(keys) {
|
|
68
|
+
if (!keys?.length) return null;
|
|
69
|
+
return Object.fromEntries(keys.map((k) => [k, `{${k}}`]));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function fetchExistingToolIdsByName() {
|
|
73
|
+
const map = new Map();
|
|
74
|
+
try {
|
|
75
|
+
const res = await axios.get(
|
|
76
|
+
`${ADOPTAI_API_BASE}/v1/mcp-integrations/get-integration-tools`,
|
|
77
|
+
{
|
|
78
|
+
params: { integration_id: INTEGRATION_ID },
|
|
79
|
+
headers: {
|
|
80
|
+
Authorization: `Bearer ${BEARER_TOKEN}`,
|
|
81
|
+
Accept: 'application/json',
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
if (Array.isArray(res.data)) {
|
|
86
|
+
for (const t of res.data) {
|
|
87
|
+
if (t?.name && t?.id) map.set(t.name, t.id);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} catch (err) {
|
|
91
|
+
console.warn(
|
|
92
|
+
'⚠️ Could not load existing tools; updates may 409:',
|
|
93
|
+
err.response?.data?.detail || err.message
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
return map;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Mirrors submodule apiRequest routing (see integrations/github-* /tools.js).
|
|
101
|
+
* @param {{ name: string, description?: string, method: string, path: string, deleteSendsJsonBody?: boolean, inputSchema?: object }} tool
|
|
102
|
+
*/
|
|
103
|
+
function buildPayload(tool) {
|
|
104
|
+
if (!tool.method || !tool.path) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
`Tool "${tool.name}" is missing method/path — ensure submodule tools export them.`
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const method = String(tool.method).toUpperCase();
|
|
111
|
+
const pathTemplate = tool.path;
|
|
112
|
+
const pathParams = pathParamsFromTemplate(pathTemplate);
|
|
113
|
+
const pathSet = new Set(pathParams);
|
|
114
|
+
const properties = tool.inputSchema?.properties || {};
|
|
115
|
+
|
|
116
|
+
const nonPathKeys = Object.keys(properties).filter((k) => !pathSet.has(k));
|
|
117
|
+
|
|
118
|
+
const useQuery =
|
|
119
|
+
method === 'GET' || (method === 'DELETE' && !tool.deleteSendsJsonBody);
|
|
120
|
+
|
|
121
|
+
const paramPlaceholders = placeholderMap(nonPathKeys);
|
|
122
|
+
|
|
123
|
+
let body = null;
|
|
124
|
+
let query_params = null;
|
|
125
|
+
if (useQuery) {
|
|
126
|
+
query_params = paramPlaceholders;
|
|
127
|
+
} else {
|
|
128
|
+
body = paramPlaceholders;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const args = Object.fromEntries(
|
|
132
|
+
Object.entries(properties).map(([k, v]) => [k, mapArgType(v)])
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
integration_id: INTEGRATION_ID,
|
|
137
|
+
name: `${APP_NAME}_${String(tool.name).toUpperCase()}`,
|
|
138
|
+
description: tool.description || '',
|
|
139
|
+
tool_spec: {
|
|
140
|
+
url: BASE_URL + pathTemplate,
|
|
141
|
+
method,
|
|
142
|
+
headers: {
|
|
143
|
+
authorization: '{secrets.bearer_token}',
|
|
144
|
+
'content-type': 'application/json',
|
|
145
|
+
},
|
|
146
|
+
body,
|
|
147
|
+
query_params,
|
|
148
|
+
},
|
|
149
|
+
input_schema: {
|
|
150
|
+
args,
|
|
151
|
+
required: tool.inputSchema?.required || [],
|
|
152
|
+
},
|
|
153
|
+
is_custom_integration: false,
|
|
154
|
+
is_published: false,
|
|
155
|
+
is_browser_call: false,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async function publishAll() {
|
|
160
|
+
console.log(
|
|
161
|
+
`Publishing ${tools.length} GitHub tools (adopt API: ${ADOPTAI_API_BASE})...\n`
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
const existingIds = await fetchExistingToolIdsByName();
|
|
165
|
+
if (existingIds.size) {
|
|
166
|
+
console.log(`Loaded ${existingIds.size} existing tool id(s) for upsert.\n`);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
let published = 0;
|
|
170
|
+
let updated = 0;
|
|
171
|
+
let skipped = 0;
|
|
172
|
+
let failed = 0;
|
|
173
|
+
|
|
174
|
+
for (const tool of tools) {
|
|
175
|
+
let payload;
|
|
176
|
+
try {
|
|
177
|
+
payload = buildPayload(tool);
|
|
178
|
+
} catch (e) {
|
|
179
|
+
console.error(`❌ Skip: ${tool.name} — ${e.message}`);
|
|
180
|
+
failed++;
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const existingId = existingIds.get(payload.name);
|
|
185
|
+
if (existingId) {
|
|
186
|
+
payload.id = existingId;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
await axios.post(ADOPTAI_API, payload, {
|
|
191
|
+
headers: {
|
|
192
|
+
Authorization: `Bearer ${BEARER_TOKEN}`,
|
|
193
|
+
'Content-Type': 'application/json',
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
if (existingId) {
|
|
198
|
+
console.log(`✅ Updated: ${payload.name}`);
|
|
199
|
+
updated++;
|
|
200
|
+
} else {
|
|
201
|
+
console.log(`✅ Published: ${payload.name}`);
|
|
202
|
+
published++;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
await new Promise((r) => setTimeout(r, PUBLISH_DELAY_MS));
|
|
206
|
+
} catch (err) {
|
|
207
|
+
const status = err.response?.status;
|
|
208
|
+
const data = err.response?.data;
|
|
209
|
+
const message =
|
|
210
|
+
(typeof data?.detail === 'string' && data.detail) ||
|
|
211
|
+
data?.message ||
|
|
212
|
+
err.message;
|
|
213
|
+
|
|
214
|
+
const isDuplicate =
|
|
215
|
+
status === 409 &&
|
|
216
|
+
typeof message === 'string' &&
|
|
217
|
+
message.toLowerCase().includes('already exists');
|
|
218
|
+
|
|
219
|
+
if (isDuplicate) {
|
|
220
|
+
console.log(`⏭️ Skipped (already exists, no id): ${payload.name}`);
|
|
221
|
+
skipped++;
|
|
222
|
+
} else {
|
|
223
|
+
console.error(`❌ Failed: ${payload.name} — ${status}: ${message}`);
|
|
224
|
+
failed++;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
await new Promise((r) => setTimeout(r, PUBLISH_DELAY_MS));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
console.log(`\n─────────────────────────────────`);
|
|
232
|
+
console.log(`✅ Published (new): ${published}`);
|
|
233
|
+
console.log(`✅ Updated: ${updated}`);
|
|
234
|
+
console.log(`⏭️ Skipped: ${skipped}`);
|
|
235
|
+
console.log(`❌ Failed: ${failed}`);
|
|
236
|
+
console.log(`─────────────────────────────────`);
|
|
237
|
+
console.log(`Total: ${tools.length} tools`);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
publishAll();
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { writeConfig, removeConfig } from '../../core/config-writer.js';
|
|
3
|
+
import { getCredentials, isTokenExpired } from '../../core/auth-manager.js';
|
|
4
|
+
import { runAuth } from './auth.js';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { dirname, resolve } from 'path';
|
|
7
|
+
import readline from 'readline';
|
|
8
|
+
|
|
9
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const args = process.argv.slice(2);
|
|
11
|
+
|
|
12
|
+
const clientFlag = args.includes('--client')
|
|
13
|
+
? args[args.indexOf('--client') + 1]
|
|
14
|
+
: 'cursor';
|
|
15
|
+
|
|
16
|
+
const isRemove = args.includes('--remove');
|
|
17
|
+
const isStatus = args.includes('--status');
|
|
18
|
+
|
|
19
|
+
const SUPPORTED_CLIENTS = ['cursor', 'claude', 'windsurf', 'vscode'];
|
|
20
|
+
|
|
21
|
+
if (isRemove) {
|
|
22
|
+
removeConfig({ client: clientFlag, serverName: 'github-adoptai' });
|
|
23
|
+
console.log(`✅ GitHub MCP removed from ${clientFlag}`);
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (isStatus) {
|
|
28
|
+
const creds = getCredentials('github');
|
|
29
|
+
if (!creds) {
|
|
30
|
+
console.log('❌ Not authenticated');
|
|
31
|
+
} else {
|
|
32
|
+
console.log('✅ Authenticated');
|
|
33
|
+
console.log(` Token: ${creds.token?.substring(0, 12)}...`);
|
|
34
|
+
console.log(` Saved: ${creds.savedAt}`);
|
|
35
|
+
}
|
|
36
|
+
process.exit(0);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!SUPPORTED_CLIENTS.includes(clientFlag)) {
|
|
40
|
+
console.error(`Invalid client: ${clientFlag}`);
|
|
41
|
+
console.error(`Supported: ${SUPPORTED_CLIENTS.join(', ')}`);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function main() {
|
|
46
|
+
const existing = getCredentials('github');
|
|
47
|
+
|
|
48
|
+
if (existing && !isTokenExpired('github')) {
|
|
49
|
+
console.log('✅ Already authenticated');
|
|
50
|
+
|
|
51
|
+
const rl = readline.createInterface({
|
|
52
|
+
input: process.stdin,
|
|
53
|
+
output: process.stdout,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const answer = await new Promise((resolveAns) => {
|
|
57
|
+
rl.question('Re-authenticate? (y/n): ', (a) => {
|
|
58
|
+
rl.close();
|
|
59
|
+
resolveAns(a.trim().toLowerCase());
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
if (answer !== 'y') {
|
|
64
|
+
writeConfig({
|
|
65
|
+
client: clientFlag,
|
|
66
|
+
serverName: 'github-adoptai',
|
|
67
|
+
command: 'node',
|
|
68
|
+
args: [resolve(__dirname, 'index.js')],
|
|
69
|
+
env: {},
|
|
70
|
+
});
|
|
71
|
+
process.exit(0);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
await runAuth();
|
|
76
|
+
|
|
77
|
+
const indexPath = resolve(__dirname, 'index.js');
|
|
78
|
+
|
|
79
|
+
writeConfig({
|
|
80
|
+
client: clientFlag,
|
|
81
|
+
serverName: 'github-adoptai',
|
|
82
|
+
command: 'node',
|
|
83
|
+
args: [indexPath],
|
|
84
|
+
env: {},
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
console.log(`
|
|
88
|
+
✅ GitHub MCP is ready!
|
|
89
|
+
────────────────────────────────────────
|
|
90
|
+
Your AI (${clientFlag}) can now use 845 tools.
|
|
91
|
+
|
|
92
|
+
Try asking:
|
|
93
|
+
"List open pull requests for owner/repo"
|
|
94
|
+
"Search repositories matching mcp server"
|
|
95
|
+
|
|
96
|
+
Run health check: node core/doctor.js --client ${clientFlag}
|
|
97
|
+
`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
main().catch((err) => {
|
|
101
|
+
console.error('❌ Setup failed:', err.message);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { tools as actionsTools } from '../github-actions/tools.js';
|
|
2
|
+
import { tools as activityTools } from '../github-activity/tools.js';
|
|
3
|
+
import { tools as appsTools } from '../github-apps/tools.js';
|
|
4
|
+
import { tools as billingTools } from '../github-billing/tools.js';
|
|
5
|
+
import { tools as checksTools } from '../github-checks/tools.js';
|
|
6
|
+
import { tools as codeScanningTools } from '../github-code-scanning/tools.js';
|
|
7
|
+
import { tools as dependabotTools } from '../github-dependabot/tools.js';
|
|
8
|
+
import { tools as gistsTools } from '../github-gists/tools.js';
|
|
9
|
+
import { tools as gitTools } from '../github-git/tools.js';
|
|
10
|
+
import { tools as issuesTools } from '../github-issues/tools.js';
|
|
11
|
+
import { tools as orgsTools } from '../github-orgs/tools.js';
|
|
12
|
+
import { tools as packagesTools } from '../github-packages/tools.js';
|
|
13
|
+
import { tools as pullsTools } from '../github-pulls/tools.js';
|
|
14
|
+
import { tools as reactionsTools } from '../github-reactions/tools.js';
|
|
15
|
+
import { tools as reposTools } from '../github-repos/tools.js';
|
|
16
|
+
import { tools as searchTools } from '../github-search/tools.js';
|
|
17
|
+
import { tools as teamsTools } from '../github-teams/tools.js';
|
|
18
|
+
import { tools as usersTools } from '../github-users/tools.js';
|
|
19
|
+
|
|
20
|
+
const SERVER_NAME = 'github-adoptai';
|
|
21
|
+
const MAX_COMBINED_NAME_LEN = 60;
|
|
22
|
+
const MAX_TOOL_NAME_LEN = Math.max(12, MAX_COMBINED_NAME_LEN - (SERVER_NAME.length + 1));
|
|
23
|
+
|
|
24
|
+
function shortHash(input) {
|
|
25
|
+
let h = 2166136261;
|
|
26
|
+
for (let i = 0; i < input.length; i += 1) {
|
|
27
|
+
h ^= input.charCodeAt(i);
|
|
28
|
+
h = Math.imul(h, 16777619);
|
|
29
|
+
}
|
|
30
|
+
return (h >>> 0).toString(36).slice(0, 6);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function compactName(name) {
|
|
34
|
+
if (name.length <= MAX_TOOL_NAME_LEN) return name;
|
|
35
|
+
const hash = shortHash(name);
|
|
36
|
+
const headLen = Math.max(1, MAX_TOOL_NAME_LEN - (hash.length + 1));
|
|
37
|
+
return `${name.slice(0, headLen)}_${hash}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function normalizeToolNames(toolList) {
|
|
41
|
+
const used = new Set();
|
|
42
|
+
return toolList.map((tool) => {
|
|
43
|
+
const base = compactName(tool.name);
|
|
44
|
+
let candidate = base;
|
|
45
|
+
let i = 2;
|
|
46
|
+
while (used.has(candidate)) {
|
|
47
|
+
const suffix = `_${i}`;
|
|
48
|
+
const headLen = Math.max(1, MAX_TOOL_NAME_LEN - suffix.length);
|
|
49
|
+
candidate = `${base.slice(0, headLen)}${suffix}`;
|
|
50
|
+
i += 1;
|
|
51
|
+
}
|
|
52
|
+
used.add(candidate);
|
|
53
|
+
return { ...tool, name: candidate };
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const allTools = [
|
|
58
|
+
...actionsTools,
|
|
59
|
+
...activityTools,
|
|
60
|
+
...appsTools,
|
|
61
|
+
...billingTools,
|
|
62
|
+
...checksTools,
|
|
63
|
+
...codeScanningTools,
|
|
64
|
+
...dependabotTools,
|
|
65
|
+
...gistsTools,
|
|
66
|
+
...gitTools,
|
|
67
|
+
...issuesTools,
|
|
68
|
+
...orgsTools,
|
|
69
|
+
...packagesTools,
|
|
70
|
+
...pullsTools,
|
|
71
|
+
...reactionsTools,
|
|
72
|
+
...reposTools,
|
|
73
|
+
...searchTools,
|
|
74
|
+
...teamsTools,
|
|
75
|
+
...usersTools,
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
export const tools = normalizeToolNames(allTools);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { saveCredentials, getCredentials } from '../../core/auth-manager.js';
|
|
2
|
+
import readline from 'readline';
|
|
3
|
+
|
|
4
|
+
const APP_ID = 'github-actions';
|
|
5
|
+
|
|
6
|
+
export async function runAuth() {
|
|
7
|
+
const rl = readline.createInterface({
|
|
8
|
+
input: process.stdin,
|
|
9
|
+
output: process.stdout,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
console.log(`
|
|
13
|
+
┌─────────────────────────────────────────────┐
|
|
14
|
+
│ GitHub Actions Authentication │
|
|
15
|
+
│ │
|
|
16
|
+
│ Use a GitHub Personal Access Token (PAT). │
|
|
17
|
+
│ Create one in Settings → Developer │
|
|
18
|
+
│ settings → Personal access tokens. │
|
|
19
|
+
└─────────────────────────────────────────────┘
|
|
20
|
+
`);
|
|
21
|
+
|
|
22
|
+
const token = await new Promise((resolve) => {
|
|
23
|
+
rl.question('Paste your GitHub PAT: ', (answer) => {
|
|
24
|
+
rl.close();
|
|
25
|
+
resolve(answer.trim());
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
if (!token || token.length < 10) {
|
|
30
|
+
throw new Error('Invalid token');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
saveCredentials(APP_ID, {
|
|
34
|
+
token,
|
|
35
|
+
tokenType: 'bearer',
|
|
36
|
+
expiresAt: null,
|
|
37
|
+
savedAt: new Date().toISOString(),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
console.log('✅ Token saved for GitHub Actions');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function getToken() {
|
|
44
|
+
return getCredentials(APP_ID)?.token || null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function buildAuthHeaders() {
|
|
48
|
+
const token = getToken();
|
|
49
|
+
if (!token) {
|
|
50
|
+
throw new Error('Not authenticated. Run: npx adoptai-github-actions-mcp --client cursor');
|
|
51
|
+
}
|
|
52
|
+
return { Authorization: 'Bearer ' + token };
|
|
53
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "adoptai-github-actions-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "GitHub's v3 REST API — Actions workflows, runs, artifacts, caches, runners, and related endpoints (OpenAPI-derived).",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"adoptai-github-actions-mcp": "./setup.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node index.js",
|
|
12
|
+
"setup": "node setup.js"
|
|
13
|
+
},
|
|
14
|
+
"keywords": ["mcp", "github", "github-actions", "actions", "ci", "ai", "cursor", "claude", "adopt.ai"],
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
18
|
+
"axios": "^1.6.0"
|
|
19
|
+
},
|
|
20
|
+
"adoptai": {
|
|
21
|
+
"appId": "github-actions",
|
|
22
|
+
"toolCount": 184,
|
|
23
|
+
"sourceFormat": "openapi_3.1",
|
|
24
|
+
"authType": "bearer",
|
|
25
|
+
"generatedAt": "2026-03-26T12:00:00.000Z"
|
|
26
|
+
}
|
|
27
|
+
}
|