@flyidea/ai-go-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 +61 -0
- package/dist/auth.js +64 -0
- package/dist/bin/cli.js +87 -0
- package/dist/index.js +52 -0
- package/dist/transport.js +162 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# @flyidea/ai-go-mcp
|
|
2
|
+
|
|
3
|
+
AI GO 官方的 Model Context Protocol (MCP) 本機代理伺服器。此套件可在您的本地環境運行 MCP Proxy 功能,協助諸如 **Cursor**, **Claude Desktop** 等支援 MCP 的智能代理,無縫連接受保護的 AI-GO 雲端(或地端)伺服器。
|
|
4
|
+
|
|
5
|
+
## 🚀 快速安裝與使用
|
|
6
|
+
|
|
7
|
+
### 1. 登入並驗證身份
|
|
8
|
+
請在您的開發機(筆電或桌機)的終端機執行:
|
|
9
|
+
```bash
|
|
10
|
+
npx -y @flyidea/ai-go-mcp auth login
|
|
11
|
+
```
|
|
12
|
+
*這將開啟您的預設瀏覽器跳轉至 AI GO 的驗證頁面。登入成功後,您的存取憑證將被安全地存放在 `~/.ai-go/credentials.json` 之中。*
|
|
13
|
+
|
|
14
|
+
### 2. 給 IDE (Cursor / Claude Desktop) 的連線設定
|
|
15
|
+
登入成功後,您不需要自己跑程式,只需要將此 SDK 加入您愛用的 Desktop Agent (IDE) 的設定中。
|
|
16
|
+
|
|
17
|
+
#### ➤ 若使用 Cursor IDE:
|
|
18
|
+
前往 `Cursor Settings` -> `Features` -> `MCP`,點選「Add New MCP Server」:
|
|
19
|
+
- **Name**: `ai-go`
|
|
20
|
+
- **Type**: `command`
|
|
21
|
+
- **Command**: `npx`
|
|
22
|
+
- **Args**: `-y @flyidea/ai-go-mcp`
|
|
23
|
+
|
|
24
|
+
#### ➤ 若使用 Claude Desktop:
|
|
25
|
+
修改您的 `claude_desktop_config.json`,加入以下節點:
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"mcpServers": {
|
|
29
|
+
"ai-go": {
|
|
30
|
+
"command": "npx",
|
|
31
|
+
"args": [
|
|
32
|
+
"-y",
|
|
33
|
+
"@flyidea/ai-go-mcp"
|
|
34
|
+
],
|
|
35
|
+
"env": {
|
|
36
|
+
"AIGO_API_URL": "https://ai-go.app" // 預設指向主站,若為內網測試可改為 localhost:8000
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## ⚙️ 環境變數 (進階)
|
|
44
|
+
|
|
45
|
+
如果您是內部開發人員需要連接至其他測試伺服器,您可以在配置檔的 `env` (如上方針對 Claude Desktop 的示範) 或您的 CLI 環境中加入以下變數:
|
|
46
|
+
|
|
47
|
+
- `AIGO_API_URL`:預設為 `https://ai-go.app`。您可以將其指向 `http://127.0.0.1:8000` 來測試本機伺服器。
|
|
48
|
+
- `AIGO_APP_URL`:預設為 `https://ai-go.app`。這是 CLI 登入階段用來開起 Auth 授權彈窗的網址。
|
|
49
|
+
|
|
50
|
+
## 📖 支援的 MCP Tools
|
|
51
|
+
一旦正確配置,AI 代理將能直接探索並執行您的資料庫與 API 操作,例如:
|
|
52
|
+
* `list_tables`
|
|
53
|
+
* `describe_table`
|
|
54
|
+
* `query_records`
|
|
55
|
+
* `insert_record`
|
|
56
|
+
* `update_record`
|
|
57
|
+
* `delete_record`
|
|
58
|
+
*(請注意:可操作的範圍嚴格遵照當前登入使用者的所屬租戶與權限進行過濾管控)*
|
|
59
|
+
|
|
60
|
+
## License
|
|
61
|
+
MIT
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.saveCredentials = saveCredentials;
|
|
7
|
+
exports.loadCredentials = loadCredentials;
|
|
8
|
+
exports.clearCredentials = clearCredentials;
|
|
9
|
+
exports.getValidAccessToken = getValidAccessToken;
|
|
10
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const os_1 = __importDefault(require("os"));
|
|
13
|
+
const axios_1 = __importDefault(require("axios"));
|
|
14
|
+
const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.ai-go');
|
|
15
|
+
const CREDS_FILE = path_1.default.join(CONFIG_DIR, 'credentials.json');
|
|
16
|
+
async function saveCredentials(creds) {
|
|
17
|
+
await promises_1.default.mkdir(CONFIG_DIR, { recursive: true });
|
|
18
|
+
await promises_1.default.writeFile(CREDS_FILE, JSON.stringify(creds, null, 2), { mode: 0o600 });
|
|
19
|
+
}
|
|
20
|
+
async function loadCredentials() {
|
|
21
|
+
try {
|
|
22
|
+
const data = await promises_1.default.readFile(CREDS_FILE, 'utf8');
|
|
23
|
+
return JSON.parse(data);
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
return null; // file not found or invalid
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function clearCredentials() {
|
|
30
|
+
try {
|
|
31
|
+
await promises_1.default.unlink(CREDS_FILE);
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
// ignore
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function getValidAccessToken(apiUrl) {
|
|
38
|
+
const creds = await loadCredentials();
|
|
39
|
+
if (!creds)
|
|
40
|
+
return null;
|
|
41
|
+
const now = Math.floor(Date.now() / 1000);
|
|
42
|
+
// Refresh 5 minutes before expiration to be safe
|
|
43
|
+
if (now > creds.expires_at - 300) {
|
|
44
|
+
try {
|
|
45
|
+
const response = await axios_1.default.post(`${apiUrl}/api/v1/auth/refresh`, {
|
|
46
|
+
refresh_token: creds.refresh_token
|
|
47
|
+
});
|
|
48
|
+
const newCreds = {
|
|
49
|
+
access_token: response.data.access_token,
|
|
50
|
+
refresh_token: response.data.refresh_token,
|
|
51
|
+
expires_at: Math.floor(Date.now() / 1000) + response.data.expires_in
|
|
52
|
+
};
|
|
53
|
+
await saveCredentials(newCreds);
|
|
54
|
+
return newCreds.access_token;
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
console.error("\n[AI GO Auth] 無法刷新 Token,請重新登入 (npx @ai-go/mcp auth login)。");
|
|
58
|
+
if (error.response?.data)
|
|
59
|
+
console.error("詳細錯誤:", error.response.data);
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return creds.access_token;
|
|
64
|
+
}
|
package/dist/bin/cli.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const express_1 = __importDefault(require("express"));
|
|
9
|
+
const cors_1 = __importDefault(require("cors"));
|
|
10
|
+
const open_1 = __importDefault(require("open"));
|
|
11
|
+
const auth_js_1 = require("../auth.js");
|
|
12
|
+
// Get version from package.json or hardcode for now
|
|
13
|
+
const program = new commander_1.Command();
|
|
14
|
+
program
|
|
15
|
+
.name('ai-go-mcp')
|
|
16
|
+
.description('AI GO MCP CLI utility')
|
|
17
|
+
.version('1.0.0');
|
|
18
|
+
const auth = program.command('auth').description('Manage authorization for the MCP server');
|
|
19
|
+
auth
|
|
20
|
+
.command('login')
|
|
21
|
+
.description('Login and authorize local MCP server')
|
|
22
|
+
.action(async () => {
|
|
23
|
+
const app = (0, express_1.default)();
|
|
24
|
+
app.use((0, cors_1.default)());
|
|
25
|
+
app.use(express_1.default.json());
|
|
26
|
+
const server = app.listen(0, async () => {
|
|
27
|
+
const address = server.address();
|
|
28
|
+
const port = typeof address === 'string' ? 0 : address?.port;
|
|
29
|
+
if (!port) {
|
|
30
|
+
console.error("無法取得啟動的 port。");
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
// 根據預設環境開啟網頁
|
|
34
|
+
const targetUrl = process.env.AIGO_APP_URL || 'https://ai-go.app';
|
|
35
|
+
const authUrl = `${targetUrl}/auth/cli?port=${port}`;
|
|
36
|
+
console.log(`\n正在開啟瀏覽器授權頁面...`);
|
|
37
|
+
console.log(`如果沒有自動跳轉,請手動複製以下連結:\n\n ${authUrl}\n`);
|
|
38
|
+
try {
|
|
39
|
+
await (0, open_1.default)(authUrl);
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
console.log("無法自動開啟瀏覽器,請手動前往上述連結。");
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
// 接收 Token callback
|
|
46
|
+
app.post('/callback', async (req, res) => {
|
|
47
|
+
const { access_token, refresh_token, expires_at } = req.body;
|
|
48
|
+
if (!access_token || !refresh_token) {
|
|
49
|
+
res.status(400).send("Bad Request: Missing tokens");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
await (0, auth_js_1.saveCredentials)({ access_token, refresh_token, expires_at });
|
|
54
|
+
res.status(200).send("OK");
|
|
55
|
+
console.log("✅ 授權成功!");
|
|
56
|
+
console.log("您現在可以在 Claude Code 等 AI 工具中配置 AI GO MCP Server。");
|
|
57
|
+
console.log("\n範例 claude_desktop_config.json 格式:");
|
|
58
|
+
console.log(JSON.stringify({
|
|
59
|
+
mcpServers: {
|
|
60
|
+
"ai-go": {
|
|
61
|
+
"command": "npx",
|
|
62
|
+
"args": ["-y", "@ai-go/mcp"],
|
|
63
|
+
"env": {
|
|
64
|
+
"AIGO_API_URL": "https://api.ai-go.app"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}, null, 2));
|
|
69
|
+
// 關閉 server 結束 process
|
|
70
|
+
server.close(() => process.exit(0));
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
console.error("保存失敗", e);
|
|
74
|
+
res.status(500).send("Internal Server Error");
|
|
75
|
+
server.close(() => process.exit(1));
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
auth
|
|
80
|
+
.command('logout')
|
|
81
|
+
.description('Clear credentials')
|
|
82
|
+
.action(async () => {
|
|
83
|
+
await (0, auth_js_1.clearCredentials)();
|
|
84
|
+
console.log("✅ 已登出並清除本機授權。");
|
|
85
|
+
process.exit(0);
|
|
86
|
+
});
|
|
87
|
+
program.parse(process.argv);
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const readline_1 = __importDefault(require("readline"));
|
|
8
|
+
const transport_js_1 = require("./transport.js");
|
|
9
|
+
async function main() {
|
|
10
|
+
const apiUrl = process.env.AIGO_API_URL || 'https://ai-go.app';
|
|
11
|
+
const transport = new transport_js_1.McpTransport(apiUrl);
|
|
12
|
+
try {
|
|
13
|
+
await transport.connect();
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
console.error("Failed to connect to AI GO MCP Server:", e.message);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
// 當從伺服器收到 JSON-RPC 回應時,印到 stdout
|
|
20
|
+
transport.onMessage = (message) => {
|
|
21
|
+
console.log(JSON.stringify(message));
|
|
22
|
+
};
|
|
23
|
+
// 監聽 stdin (AI 工具發送的 JSON-RPC 請求)
|
|
24
|
+
const rl = readline_1.default.createInterface({
|
|
25
|
+
input: process.stdin,
|
|
26
|
+
output: process.stdout,
|
|
27
|
+
terminal: false
|
|
28
|
+
});
|
|
29
|
+
rl.on('line', async (line) => {
|
|
30
|
+
if (!line.trim())
|
|
31
|
+
return;
|
|
32
|
+
try {
|
|
33
|
+
const message = JSON.parse(line);
|
|
34
|
+
await transport.sendMessage(message);
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
console.error("Failed to parse or send message:", e);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
process.on('SIGINT', () => {
|
|
41
|
+
transport.close();
|
|
42
|
+
process.exit(0);
|
|
43
|
+
});
|
|
44
|
+
process.on('SIGTERM', () => {
|
|
45
|
+
transport.close();
|
|
46
|
+
process.exit(0);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
main().catch(err => {
|
|
50
|
+
console.error("Fatal error:", err);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
});
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.McpTransport = void 0;
|
|
40
|
+
const http = __importStar(require("http"));
|
|
41
|
+
const https = __importStar(require("https"));
|
|
42
|
+
const axios_1 = __importDefault(require("axios"));
|
|
43
|
+
const auth_1 = require("./auth");
|
|
44
|
+
class McpTransport {
|
|
45
|
+
apiUrl;
|
|
46
|
+
sessionId = null;
|
|
47
|
+
req = null;
|
|
48
|
+
res = null;
|
|
49
|
+
// Callback when a JSON-RPC message is received from the server
|
|
50
|
+
onMessage;
|
|
51
|
+
// Callback when connection closes
|
|
52
|
+
onClose;
|
|
53
|
+
constructor(apiUrl) {
|
|
54
|
+
this.apiUrl = apiUrl.replace(/\/+$/, '');
|
|
55
|
+
}
|
|
56
|
+
async connect() {
|
|
57
|
+
const token = await (0, auth_1.getValidAccessToken)(this.apiUrl);
|
|
58
|
+
if (!token) {
|
|
59
|
+
throw new Error("Token 缺失或已過期,請執行 npx @ai-go/mcp auth login");
|
|
60
|
+
}
|
|
61
|
+
const sseUrl = `${this.apiUrl}/api/v1/mcp/sse`;
|
|
62
|
+
const urlObj = new URL(sseUrl);
|
|
63
|
+
const requestModule = urlObj.protocol === 'https:' ? https : http;
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
this.req = requestModule.get(sseUrl, {
|
|
66
|
+
headers: {
|
|
67
|
+
'Authorization': `Bearer ${token}`,
|
|
68
|
+
'Accept': 'text/event-stream'
|
|
69
|
+
}
|
|
70
|
+
}, (res) => {
|
|
71
|
+
this.res = res;
|
|
72
|
+
if (res.statusCode !== 200) {
|
|
73
|
+
reject(new Error(`Failed to connect to SSE: HTTP ${res.statusCode}`));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
let buffer = '';
|
|
77
|
+
res.on('data', (chunk) => {
|
|
78
|
+
buffer += chunk.toString();
|
|
79
|
+
const lines = buffer.split('\n');
|
|
80
|
+
buffer = lines.pop() || ''; // keep the last incomplete line
|
|
81
|
+
let currentEvent = '';
|
|
82
|
+
let currentData = '';
|
|
83
|
+
for (const line of lines) {
|
|
84
|
+
if (line.trim() === '') {
|
|
85
|
+
// Empty line means dispatch event
|
|
86
|
+
if (currentEvent === 'endpoint' && currentData) {
|
|
87
|
+
try {
|
|
88
|
+
const url = new URL(`${this.apiUrl}${currentData}`);
|
|
89
|
+
this.sessionId = url.searchParams.get('session_id');
|
|
90
|
+
resolve();
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
reject(err);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else if (currentEvent === 'message' && currentData) {
|
|
97
|
+
try {
|
|
98
|
+
const parsed = JSON.parse(currentData);
|
|
99
|
+
if (this.onMessage)
|
|
100
|
+
this.onMessage(parsed);
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
console.error("Parse error on message:", e);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
currentEvent = '';
|
|
107
|
+
currentData = '';
|
|
108
|
+
}
|
|
109
|
+
else if (line.startsWith('event:')) {
|
|
110
|
+
currentEvent = line.slice(6).trim();
|
|
111
|
+
}
|
|
112
|
+
else if (line.startsWith('data:')) {
|
|
113
|
+
currentData += line.slice(5).trim();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
res.on('end', () => {
|
|
118
|
+
if (this.onClose)
|
|
119
|
+
this.onClose();
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
this.req.on('error', (err) => {
|
|
123
|
+
if (!this.sessionId)
|
|
124
|
+
reject(err);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
async sendMessage(message) {
|
|
129
|
+
if (!this.sessionId) {
|
|
130
|
+
throw new Error("Not connected");
|
|
131
|
+
}
|
|
132
|
+
const token = await (0, auth_1.getValidAccessToken)(this.apiUrl);
|
|
133
|
+
if (!token) {
|
|
134
|
+
throw new Error("Token 缺失或已過期");
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
await axios_1.default.post(`${this.apiUrl}/api/v1/mcp/message?session_id=${this.sessionId}`, message, {
|
|
138
|
+
headers: {
|
|
139
|
+
'Authorization': `Bearer ${token}`,
|
|
140
|
+
'Content-Type': 'application/json'
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
console.error("Failed to send message:", error.response?.data || error.message);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
close() {
|
|
149
|
+
if (this.res) {
|
|
150
|
+
this.res.destroy();
|
|
151
|
+
this.res = null;
|
|
152
|
+
}
|
|
153
|
+
if (this.req) {
|
|
154
|
+
this.req.destroy();
|
|
155
|
+
this.req = null;
|
|
156
|
+
}
|
|
157
|
+
if (this.onClose) {
|
|
158
|
+
this.onClose();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
exports.McpTransport = McpTransport;
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flyidea/ai-go-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "AI GO MCP (Model Context Protocol) CLI & Proxy Server",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": "dist/bin/cli.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"start": "node dist/index.js",
|
|
16
|
+
"dev": "tsc -w"
|
|
17
|
+
},
|
|
18
|
+
"author": "Urfit Tech",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@modelcontextprotocol/sdk": "^1.0.1",
|
|
22
|
+
"axios": "^1.6.8",
|
|
23
|
+
"commander": "^12.0.0",
|
|
24
|
+
"cors": "^2.8.5",
|
|
25
|
+
"dotenv": "^16.4.5",
|
|
26
|
+
"express": "^4.19.2",
|
|
27
|
+
"open": "^10.1.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/cors": "^2.8.17",
|
|
31
|
+
"@types/eventsource": "^1.1.15",
|
|
32
|
+
"@types/express": "^4.17.21",
|
|
33
|
+
"@types/node": "^20.12.7",
|
|
34
|
+
"typescript": "^5.4.5"
|
|
35
|
+
}
|
|
36
|
+
}
|