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-search';
|
|
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 Search 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 Search');
|
|
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-search-mcp --client cursor');
|
|
51
|
+
}
|
|
52
|
+
return { Authorization: 'Bearer ' + token };
|
|
53
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "adoptai-github-search-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "GitHub's v3 REST API — search across code, repos, issues, commits, users, and related endpoints (OpenAPI-derived).",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"adoptai-github-search-mcp": "./setup.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node index.js",
|
|
12
|
+
"setup": "node setup.js"
|
|
13
|
+
},
|
|
14
|
+
"keywords": ["mcp", "github", "github-search", "search", "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-search",
|
|
22
|
+
"toolCount": 7,
|
|
23
|
+
"sourceFormat": "openapi_3.1",
|
|
24
|
+
"authType": "bearer",
|
|
25
|
+
"generatedAt": "2026-03-26T12:00:00.000Z"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -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-search-adoptai' });
|
|
23
|
+
console.log(`✅ GitHub Search MCP removed from ${clientFlag}`);
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (isStatus) {
|
|
28
|
+
const creds = getCredentials('github-search');
|
|
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-search');
|
|
47
|
+
|
|
48
|
+
if (existing && !isTokenExpired('github-search')) {
|
|
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-search-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-search-adoptai',
|
|
82
|
+
command: 'node',
|
|
83
|
+
args: [indexPath],
|
|
84
|
+
env: {},
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
console.log(`
|
|
88
|
+
✅ GitHub Search MCP is ready!
|
|
89
|
+
────────────────────────────────────────
|
|
90
|
+
Your AI (${clientFlag}) can now use 7 tools.
|
|
91
|
+
|
|
92
|
+
Try asking:
|
|
93
|
+
"Search repositories"
|
|
94
|
+
"Search code"
|
|
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,370 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { buildAuthHeaders } from './auth.js';
|
|
3
|
+
|
|
4
|
+
const BASE_URL = 'https://api.github.com';
|
|
5
|
+
const APP_ID = 'github-search';
|
|
6
|
+
|
|
7
|
+
function handleError(err) {
|
|
8
|
+
const status = err.response?.status;
|
|
9
|
+
const msg = err.response?.data?.message || err.response?.data?.error || err.message;
|
|
10
|
+
if (status === 401) throw new Error(`Token invalid.\nRun: npx adoptai-${APP_ID}-mcp --client cursor`);
|
|
11
|
+
if (status === 403) throw new Error('Insufficient permissions. Check your API key scopes.');
|
|
12
|
+
if (status === 404) throw new Error('Resource not found. Check your parameters.');
|
|
13
|
+
if (status === 429) throw new Error('Rate limit exceeded. Please wait and try again.');
|
|
14
|
+
throw new Error(msg || 'API request failed');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function apiRequest(method, pathTemplate, params = {}, opts = {}) {
|
|
18
|
+
const { deleteSendsJsonBody = false } = opts;
|
|
19
|
+
const headers = buildAuthHeaders();
|
|
20
|
+
let url = BASE_URL + pathTemplate;
|
|
21
|
+
const pathKeys = [...pathTemplate.matchAll(/\{([^}]+)\}/g)].map((m) => m[1]);
|
|
22
|
+
for (const key of pathKeys) {
|
|
23
|
+
const value = params[key];
|
|
24
|
+
if (value !== undefined && value !== null) url = url.replace(`{${key}}`, encodeURIComponent(String(value)));
|
|
25
|
+
}
|
|
26
|
+
const rest = { ...params };
|
|
27
|
+
for (const key of pathKeys) delete rest[key];
|
|
28
|
+
const m = method.toUpperCase();
|
|
29
|
+
const useQuery = m === 'GET' || (m === 'DELETE' && !deleteSendsJsonBody);
|
|
30
|
+
const queryParams = {};
|
|
31
|
+
const bodyParams = {};
|
|
32
|
+
for (const [key, value] of Object.entries(rest)) {
|
|
33
|
+
if (value === undefined) continue;
|
|
34
|
+
if (useQuery) queryParams[key] = value; else bodyParams[key] = value;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const res = await axios({
|
|
38
|
+
method: m,
|
|
39
|
+
url,
|
|
40
|
+
headers: { 'Content-Type': 'application/json', ...headers },
|
|
41
|
+
params: Object.keys(queryParams).length ? queryParams : undefined,
|
|
42
|
+
data: Object.keys(bodyParams).length ? bodyParams : undefined,
|
|
43
|
+
timeout: 30000,
|
|
44
|
+
});
|
|
45
|
+
if (res.status === 204 || res.data === '' || res.data === undefined) return { ok: true, status: res.status };
|
|
46
|
+
return res.data;
|
|
47
|
+
} catch (err) {
|
|
48
|
+
handleError(err);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const ENDPOINTS = [
|
|
53
|
+
{
|
|
54
|
+
"name": "search_code",
|
|
55
|
+
"description": "Search code",
|
|
56
|
+
"method": "GET",
|
|
57
|
+
"path": "/search/code",
|
|
58
|
+
"deleteSendsJsonBody": false,
|
|
59
|
+
"inputSchema": {
|
|
60
|
+
"type": "object",
|
|
61
|
+
"properties": {
|
|
62
|
+
"q": {
|
|
63
|
+
"type": "string",
|
|
64
|
+
"description": "The query contains one or more search keywords and qualifiers. Qualifiers allow you to limit your search to specific areas of GitHub. The REST API supports the same qualifiers as the web interface for GitHub. To learn more about the format of the query, see [Constructing a search query](https://docs.github.com/rest/search/search#constructing-a-search-query). See \"[Searching code](https://docs.github.com/search-github/searching-on-github/searching-code)\" for a detailed list of qualifiers."
|
|
65
|
+
},
|
|
66
|
+
"sort": {
|
|
67
|
+
"type": "string",
|
|
68
|
+
"description": "**This field is closing down.** Sorts the results of your query. Can only be `indexed`, which indicates how recently a file has been indexed by the GitHub search infrastructure. Default: [best match](https://docs.github.com/rest/search/search#ranking-search-results)",
|
|
69
|
+
"enum": [
|
|
70
|
+
"indexed"
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
"order": {
|
|
74
|
+
"type": "string",
|
|
75
|
+
"description": "**This field is closing down.** Determines whether the first search result returned is the highest number of matches (`desc`) or lowest number of matches (`asc`). This parameter is ignored unless you provide `sort`. ",
|
|
76
|
+
"enum": [
|
|
77
|
+
"desc",
|
|
78
|
+
"asc"
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
"per_page": {
|
|
82
|
+
"type": "number",
|
|
83
|
+
"description": "The number of results per page (max 100). For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\""
|
|
84
|
+
},
|
|
85
|
+
"page": {
|
|
86
|
+
"type": "number",
|
|
87
|
+
"description": "The page number of the results to fetch. For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\""
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"required": [
|
|
91
|
+
"q"
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"name": "search_commits",
|
|
97
|
+
"description": "Search commits",
|
|
98
|
+
"method": "GET",
|
|
99
|
+
"path": "/search/commits",
|
|
100
|
+
"deleteSendsJsonBody": false,
|
|
101
|
+
"inputSchema": {
|
|
102
|
+
"type": "object",
|
|
103
|
+
"properties": {
|
|
104
|
+
"q": {
|
|
105
|
+
"type": "string",
|
|
106
|
+
"description": "The query contains one or more search keywords and qualifiers. Qualifiers allow you to limit your search to specific areas of GitHub. The REST API supports the same qualifiers as the web interface for GitHub. To learn more about the format of the query, see [Constructing a search query](https://docs.github.com/rest/search/search#constructing-a-search-query). See \"[Searching commits](https://docs.github.com/search-github/searching-on-github/searching-commits)\" for a detailed list of qualifiers."
|
|
107
|
+
},
|
|
108
|
+
"sort": {
|
|
109
|
+
"type": "string",
|
|
110
|
+
"description": "Sorts the results of your query by `author-date` or `committer-date`. Default: [best match](https://docs.github.com/rest/search/search#ranking-search-results)",
|
|
111
|
+
"enum": [
|
|
112
|
+
"author-date",
|
|
113
|
+
"committer-date"
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
"order": {
|
|
117
|
+
"type": "string",
|
|
118
|
+
"description": "Determines whether the first search result returned is the highest number of matches (`desc`) or lowest number of matches (`asc`). This parameter is ignored unless you provide `sort`.",
|
|
119
|
+
"enum": [
|
|
120
|
+
"desc",
|
|
121
|
+
"asc"
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
"per_page": {
|
|
125
|
+
"type": "number",
|
|
126
|
+
"description": "The number of results per page (max 100). For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\""
|
|
127
|
+
},
|
|
128
|
+
"page": {
|
|
129
|
+
"type": "number",
|
|
130
|
+
"description": "The page number of the results to fetch. For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\""
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
"required": [
|
|
134
|
+
"q"
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"name": "search_issues_and_pull_requests",
|
|
140
|
+
"description": "Search issues and pull requests",
|
|
141
|
+
"method": "GET",
|
|
142
|
+
"path": "/search/issues",
|
|
143
|
+
"deleteSendsJsonBody": false,
|
|
144
|
+
"inputSchema": {
|
|
145
|
+
"type": "object",
|
|
146
|
+
"properties": {
|
|
147
|
+
"q": {
|
|
148
|
+
"type": "string",
|
|
149
|
+
"description": "The query contains one or more search keywords and qualifiers. Qualifiers allow you to limit your search to specific areas of GitHub. The REST API supports the same qualifiers as the web interface for GitHub. To learn more about the format of the query, see [Constructing a search query](https://docs.github.com/rest/search/search#constructing-a-search-query). See \"[Searching issues and pull requests](https://docs.github.com/search-github/searching-on-github/searching-issues-and-pull-requests)\" for a detailed list of qualifiers."
|
|
150
|
+
},
|
|
151
|
+
"sort": {
|
|
152
|
+
"type": "string",
|
|
153
|
+
"description": "Sorts the results of your query by the number of `comments`, `reactions`, `reactions-+1`, `reactions--1`, `reactions-smile`, `reactions-thinking_face`, `reactions-heart`, `reactions-tada`, or `interactions`. You can also sort results by how recently the items were `created` or `updated`, Default: [best match](https://docs.github.com/rest/search/search#ranking-search-results)",
|
|
154
|
+
"enum": [
|
|
155
|
+
"comments",
|
|
156
|
+
"reactions",
|
|
157
|
+
"reactions-+1",
|
|
158
|
+
"reactions--1",
|
|
159
|
+
"reactions-smile",
|
|
160
|
+
"reactions-thinking_face",
|
|
161
|
+
"reactions-heart",
|
|
162
|
+
"reactions-tada",
|
|
163
|
+
"interactions",
|
|
164
|
+
"created",
|
|
165
|
+
"updated"
|
|
166
|
+
]
|
|
167
|
+
},
|
|
168
|
+
"order": {
|
|
169
|
+
"type": "string",
|
|
170
|
+
"description": "Determines whether the first search result returned is the highest number of matches (`desc`) or lowest number of matches (`asc`). This parameter is ignored unless you provide `sort`.",
|
|
171
|
+
"enum": [
|
|
172
|
+
"desc",
|
|
173
|
+
"asc"
|
|
174
|
+
]
|
|
175
|
+
},
|
|
176
|
+
"per_page": {
|
|
177
|
+
"type": "number",
|
|
178
|
+
"description": "The number of results per page (max 100). For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\""
|
|
179
|
+
},
|
|
180
|
+
"page": {
|
|
181
|
+
"type": "number",
|
|
182
|
+
"description": "The page number of the results to fetch. For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\""
|
|
183
|
+
},
|
|
184
|
+
"advanced_search": {
|
|
185
|
+
"type": "string",
|
|
186
|
+
"description": "Set to `true` to use advanced search.\nExample: `http://api.github.com/search/issues?q={query}&advanced_search=true`"
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
"required": [
|
|
190
|
+
"q"
|
|
191
|
+
]
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"name": "search_labels",
|
|
196
|
+
"description": "Search labels",
|
|
197
|
+
"method": "GET",
|
|
198
|
+
"path": "/search/labels",
|
|
199
|
+
"deleteSendsJsonBody": false,
|
|
200
|
+
"inputSchema": {
|
|
201
|
+
"type": "object",
|
|
202
|
+
"properties": {
|
|
203
|
+
"repository_id": {
|
|
204
|
+
"type": "number",
|
|
205
|
+
"description": "The id of the repository."
|
|
206
|
+
},
|
|
207
|
+
"q": {
|
|
208
|
+
"type": "string",
|
|
209
|
+
"description": "The search keywords. This endpoint does not accept qualifiers in the query. To learn more about the format of the query, see [Constructing a search query](https://docs.github.com/rest/search/search#constructing-a-search-query)."
|
|
210
|
+
},
|
|
211
|
+
"sort": {
|
|
212
|
+
"type": "string",
|
|
213
|
+
"description": "Sorts the results of your query by when the label was `created` or `updated`. Default: [best match](https://docs.github.com/rest/search/search#ranking-search-results)",
|
|
214
|
+
"enum": [
|
|
215
|
+
"created",
|
|
216
|
+
"updated"
|
|
217
|
+
]
|
|
218
|
+
},
|
|
219
|
+
"order": {
|
|
220
|
+
"type": "string",
|
|
221
|
+
"description": "Determines whether the first search result returned is the highest number of matches (`desc`) or lowest number of matches (`asc`). This parameter is ignored unless you provide `sort`.",
|
|
222
|
+
"enum": [
|
|
223
|
+
"desc",
|
|
224
|
+
"asc"
|
|
225
|
+
]
|
|
226
|
+
},
|
|
227
|
+
"per_page": {
|
|
228
|
+
"type": "number",
|
|
229
|
+
"description": "The number of results per page (max 100). For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\""
|
|
230
|
+
},
|
|
231
|
+
"page": {
|
|
232
|
+
"type": "number",
|
|
233
|
+
"description": "The page number of the results to fetch. For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\""
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
"required": [
|
|
237
|
+
"repository_id",
|
|
238
|
+
"q"
|
|
239
|
+
]
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"name": "search_repos",
|
|
244
|
+
"description": "Search repositories",
|
|
245
|
+
"method": "GET",
|
|
246
|
+
"path": "/search/repositories",
|
|
247
|
+
"deleteSendsJsonBody": false,
|
|
248
|
+
"inputSchema": {
|
|
249
|
+
"type": "object",
|
|
250
|
+
"properties": {
|
|
251
|
+
"q": {
|
|
252
|
+
"type": "string",
|
|
253
|
+
"description": "The query contains one or more search keywords and qualifiers. Qualifiers allow you to limit your search to specific areas of GitHub. The REST API supports the same qualifiers as the web interface for GitHub. To learn more about the format of the query, see [Constructing a search query](https://docs.github.com/rest/search/search#constructing-a-search-query). See \"[Searching for repositories](https://docs.github.com/articles/searching-for-repositories/)\" for a detailed list of qualifiers."
|
|
254
|
+
},
|
|
255
|
+
"sort": {
|
|
256
|
+
"type": "string",
|
|
257
|
+
"description": "Sorts the results of your query by number of `stars`, `forks`, or `help-wanted-issues` or how recently the items were `updated`. Default: [best match](https://docs.github.com/rest/search/search#ranking-search-results)",
|
|
258
|
+
"enum": [
|
|
259
|
+
"stars",
|
|
260
|
+
"forks",
|
|
261
|
+
"help-wanted-issues",
|
|
262
|
+
"updated"
|
|
263
|
+
]
|
|
264
|
+
},
|
|
265
|
+
"order": {
|
|
266
|
+
"type": "string",
|
|
267
|
+
"description": "Determines whether the first search result returned is the highest number of matches (`desc`) or lowest number of matches (`asc`). This parameter is ignored unless you provide `sort`.",
|
|
268
|
+
"enum": [
|
|
269
|
+
"desc",
|
|
270
|
+
"asc"
|
|
271
|
+
]
|
|
272
|
+
},
|
|
273
|
+
"per_page": {
|
|
274
|
+
"type": "number",
|
|
275
|
+
"description": "The number of results per page (max 100). For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\""
|
|
276
|
+
},
|
|
277
|
+
"page": {
|
|
278
|
+
"type": "number",
|
|
279
|
+
"description": "The page number of the results to fetch. For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\""
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
"required": [
|
|
283
|
+
"q"
|
|
284
|
+
]
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
"name": "search_topics",
|
|
289
|
+
"description": "Search topics",
|
|
290
|
+
"method": "GET",
|
|
291
|
+
"path": "/search/topics",
|
|
292
|
+
"deleteSendsJsonBody": false,
|
|
293
|
+
"inputSchema": {
|
|
294
|
+
"type": "object",
|
|
295
|
+
"properties": {
|
|
296
|
+
"q": {
|
|
297
|
+
"type": "string",
|
|
298
|
+
"description": "The query contains one or more search keywords and qualifiers. Qualifiers allow you to limit your search to specific areas of GitHub. The REST API supports the same qualifiers as the web interface for GitHub. To learn more about the format of the query, see [Constructing a search query](https://docs.github.com/rest/search/search#constructing-a-search-query)."
|
|
299
|
+
},
|
|
300
|
+
"per_page": {
|
|
301
|
+
"type": "number",
|
|
302
|
+
"description": "The number of results per page (max 100). For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\""
|
|
303
|
+
},
|
|
304
|
+
"page": {
|
|
305
|
+
"type": "number",
|
|
306
|
+
"description": "The page number of the results to fetch. For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\""
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
"required": [
|
|
310
|
+
"q"
|
|
311
|
+
]
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
"name": "search_users",
|
|
316
|
+
"description": "Search users",
|
|
317
|
+
"method": "GET",
|
|
318
|
+
"path": "/search/users",
|
|
319
|
+
"deleteSendsJsonBody": false,
|
|
320
|
+
"inputSchema": {
|
|
321
|
+
"type": "object",
|
|
322
|
+
"properties": {
|
|
323
|
+
"q": {
|
|
324
|
+
"type": "string",
|
|
325
|
+
"description": "The query contains one or more search keywords and qualifiers. Qualifiers allow you to limit your search to specific areas of GitHub. The REST API supports the same qualifiers as the web interface for GitHub. To learn more about the format of the query, see [Constructing a search query](https://docs.github.com/rest/search/search#constructing-a-search-query). See \"[Searching users](https://docs.github.com/search-github/searching-on-github/searching-users)\" for a detailed list of qualifiers."
|
|
326
|
+
},
|
|
327
|
+
"sort": {
|
|
328
|
+
"type": "string",
|
|
329
|
+
"description": "Sorts the results of your query by number of `followers` or `repositories`, or when the person `joined` GitHub. Default: [best match](https://docs.github.com/rest/search/search#ranking-search-results)",
|
|
330
|
+
"enum": [
|
|
331
|
+
"followers",
|
|
332
|
+
"repositories",
|
|
333
|
+
"joined"
|
|
334
|
+
]
|
|
335
|
+
},
|
|
336
|
+
"order": {
|
|
337
|
+
"type": "string",
|
|
338
|
+
"description": "Determines whether the first search result returned is the highest number of matches (`desc`) or lowest number of matches (`asc`). This parameter is ignored unless you provide `sort`.",
|
|
339
|
+
"enum": [
|
|
340
|
+
"desc",
|
|
341
|
+
"asc"
|
|
342
|
+
]
|
|
343
|
+
},
|
|
344
|
+
"per_page": {
|
|
345
|
+
"type": "number",
|
|
346
|
+
"description": "The number of results per page (max 100). For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\""
|
|
347
|
+
},
|
|
348
|
+
"page": {
|
|
349
|
+
"type": "number",
|
|
350
|
+
"description": "The page number of the results to fetch. For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\""
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
"required": [
|
|
354
|
+
"q"
|
|
355
|
+
]
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
];
|
|
359
|
+
|
|
360
|
+
export const tools = ENDPOINTS.map((e) => ({
|
|
361
|
+
name: e.name,
|
|
362
|
+
description: e.description,
|
|
363
|
+
method: e.method,
|
|
364
|
+
path: e.path,
|
|
365
|
+
deleteSendsJsonBody: Boolean(e.deleteSendsJsonBody),
|
|
366
|
+
inputSchema: e.inputSchema,
|
|
367
|
+
handler: async (params) => ({
|
|
368
|
+
content: [{ type: 'text', text: JSON.stringify(await apiRequest(e.method, e.path, params, { deleteSendsJsonBody: e.deleteSendsJsonBody }), null, 2) }],
|
|
369
|
+
}),
|
|
370
|
+
}));
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { saveCredentials, getCredentials } from '../../core/auth-manager.js';
|
|
2
|
+
import readline from 'readline';
|
|
3
|
+
|
|
4
|
+
const APP_ID = 'github-teams';
|
|
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 Teams 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 Teams');
|
|
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-teams-mcp --client cursor');
|
|
51
|
+
}
|
|
52
|
+
return { Authorization: 'Bearer ' + token };
|
|
53
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "adoptai-github-teams-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "GitHub's v3 REST API — teams, memberships, repos, discussions, and related endpoints (OpenAPI-derived).",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"adoptai-github-teams-mcp": "./setup.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node index.js",
|
|
12
|
+
"setup": "node setup.js"
|
|
13
|
+
},
|
|
14
|
+
"keywords": ["mcp", "github", "github-teams", "teams", "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-teams",
|
|
22
|
+
"toolCount": 16,
|
|
23
|
+
"sourceFormat": "openapi_3.1",
|
|
24
|
+
"authType": "bearer",
|
|
25
|
+
"generatedAt": "2026-03-26T12:00:00.000Z"
|
|
26
|
+
}
|
|
27
|
+
}
|