1lev1-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 +67 -0
- package/bin/cli.js +20 -0
- package/package.json +25 -0
- package/src/app-config.js +13 -0
- package/src/auth-flow.js +73 -0
- package/src/config-writers.js +214 -0
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# 1lev1 MCP Setup ๐ (English)
|
|
2
|
+
|
|
3
|
+
A CLI tool to quickly connect the **1lev1** system to your favorite AI agents (Claude Desktop, Cursor, Windsurf, VS Code, etc.) using the MCP (Model Context Protocol).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
By connecting, your AI agent gains "superpowers" within the 1lev1 system:
|
|
8
|
+
|
|
9
|
+
- ๐ **Timer Control**: Start, stop, and manage timers in real-time.
|
|
10
|
+
- ๐ค **Partnerships**: Manage and connect different entities in the system.
|
|
11
|
+
- โ
**Task Management**: Automatically create and track tasks.
|
|
12
|
+
- ๐ **Voting & Sales Data**: Get real-time updates on audience voting and sales reports.
|
|
13
|
+
|
|
14
|
+
## Installation & Usage
|
|
15
|
+
|
|
16
|
+
Once the package is published to NPM, no prior installation is needed. Simply run:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx 1lev1-mcp
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Customization (for Developers)
|
|
23
|
+
|
|
24
|
+
To use this tool for your own MCP project, follow these two simple steps:
|
|
25
|
+
|
|
26
|
+
1. **Edit Config**: Change the values in `src/app-config.js` to match your service name and server URLs.
|
|
27
|
+
2. **Server-Side Implementation**: Ensure your website has the following routes:
|
|
28
|
+
- `authUrlBase`: A page for authentication that returns the user to the callback URL with the API Key.
|
|
29
|
+
- `mcpUrl`: The MCP server endpoint (supporting SSE or Stdio).
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
**1lev1 - we can together ๐**
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
# 1lev1 MCP Setup (Hebrew) ๐
|
|
38
|
+
|
|
39
|
+
ืืื CLI ืืืืืืจ ืืืืจ ืฉื ืืขืจืืช **1lev1** ืืกืืื ื ื-AI ืืืืืืื ืขืืื (Claude Desktop, Cursor, Windsurf, VS Code ืืขืื) ืืืืฆืขืืช ืคืจืืืืงืื MCP (Model Context Protocol).
|
|
40
|
+
|
|
41
|
+
## ืื ืื ืืืคืฉืจ?
|
|
42
|
+
|
|
43
|
+
ืืืืฆืขืืช ืืืืืืจ, ืกืืื ื-AI ืฉืื ืืงืื ืืืืืืช "ืขื" ืืชืื ืืืขืจืืช ืฉื 1lev1:
|
|
44
|
+
|
|
45
|
+
- ๐ **ืฉืืืื ืืืืืืจืื**: ืืคืขืื, ืขืฆืืจื ืื ืืืื ืืื ืืืื ืืืช.
|
|
46
|
+
- ๐ค **ืืฆืืจืช ืฉืืชืคืืืืช**: ื ืืืื ืืืืืืจ ืืืจืืื ืฉืื ื ืืืขืจืืช.
|
|
47
|
+
- โ
**ื ืืืื ืืฉืืืืช**: ืืฆืืจื ืืืขืงื ืืืจ ืืฉืืืืช ืืฆืืจื ืืืืืืืืช.
|
|
48
|
+
- ๐ **ื ืชืื ื ืืฆืืขืืช ืืืืืจืืช**: ืงืืืช ืืืืข ืืขืืืื ืขื ืืฆืืขืืช ืงืื ืืื"ืืืช ืืืืจื.
|
|
49
|
+
|
|
50
|
+
## ืืชืงื ื ืืฉืืืืฉ
|
|
51
|
+
|
|
52
|
+
ืืจืืข ืฉืืืืืื ืืคืืจืกืืช ื-NPM, ืืื ืฆืืจื ืืืชืงื ื ืืืงืืืช. ืคืฉืื ืืจืืฆื:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx 1lev1-mcp
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## ืืชืืื ืืืฉืืช (ืืืคืชืืื)
|
|
59
|
+
|
|
60
|
+
ืื ืืจืฆืื ื ืืืฉืชืืฉ ืืืื ืื ืขืืืจ ืคืจืืืงื MCP ืืฉืื, ืขืืื ืืืฆืข ืฉื ื ืคืขืืืืช ืคืฉืืืืช:
|
|
61
|
+
|
|
62
|
+
1. **ืขืจืืืช ืืงืื ืคืื**: ืฉื ื ืืช ืืขืจืืื ื-`src/app-config.js` ืืื ืฉืืชืืืื ืืฉื ืืฉืืจืืช ืืืืชืืืืช ื-URL ืฉื ืืฉืจืช ืฉืื.
|
|
63
|
+
2. **ืืืืืฉ ืืฆื ืืฉืจืช**: ืขืืื ืืืืื ืฉืืืชืจ ืฉืื ืงืืืืื ืืจืืืืื (Routes) ืืืืื:
|
|
64
|
+
- `authUrlBase`: ืืฃ ืฉืืืฆืข ืืืืืช ืืืืืืจ ืืช ืืืฉืชืืฉ ืืืชืืืช ื-callback ืขื ื-API Key.
|
|
65
|
+
- `mcpUrl`: ื ืงืืืช ืืงืฆื (Endpoint) ืฉื ืฉืจืช ื-MCP ืฉืชืืืืช ื-SSE ืื ื-Stdio.
|
|
66
|
+
|
|
67
|
+
---
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { runSetup } from '../src/auth-flow.js';
|
|
4
|
+
import { APP_CONFIG } from '../src/app-config.js';
|
|
5
|
+
|
|
6
|
+
const program = new Command();
|
|
7
|
+
|
|
8
|
+
program
|
|
9
|
+
.name(APP_CONFIG.serviceName)
|
|
10
|
+
.description('Connect your MCP server to AI coding agents')
|
|
11
|
+
.version('1.0.0');
|
|
12
|
+
|
|
13
|
+
program
|
|
14
|
+
.command('setup', { isDefault: true })
|
|
15
|
+
.description('Authenticate and configure all supported agents')
|
|
16
|
+
.option('--url <url>', 'MCP server URL', APP_CONFIG.mcpUrl)
|
|
17
|
+
.option('--port <port>', 'Local callback port', APP_CONFIG.defaultPort.toString())
|
|
18
|
+
.action(runSetup);
|
|
19
|
+
|
|
20
|
+
program.parse();
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "1lev1-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Connect 1lev1 to your AI coding agents",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"1lev1-mcp": "./bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"src/"
|
|
12
|
+
],
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
16
|
+
"keywords": ["mcp", "ai", "claude", "cursor"],
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"commander": "^12.0.0",
|
|
20
|
+
"open": "^10.0.0",
|
|
21
|
+
"chalk": "^5.0.0",
|
|
22
|
+
"ora": "^8.0.0"
|
|
23
|
+
},
|
|
24
|
+
"engines": { "node": ">=18" }
|
|
25
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const APP_CONFIG = {
|
|
2
|
+
// ืฉื ืืฉืืจืืช ืืคื ืฉืืืคืืข ืืงืื ืคืื ืฉื ืืกืืื ืื (Claude, Cursor ืืื')
|
|
3
|
+
serviceName: '1lev1-mcp',
|
|
4
|
+
|
|
5
|
+
// ืืชืืืช ื-URL ืฉื ื-MCP server
|
|
6
|
+
mcpUrl: 'https://1lev1.com/api/mcp',
|
|
7
|
+
|
|
8
|
+
// ืืชืืืช ืืฃ ืืืืืืจ ืืืชืจ (ืขืืืจ OAuth/Auth flow)
|
|
9
|
+
authUrlBase: 'https://1lev1.com/mcp-connect',
|
|
10
|
+
|
|
11
|
+
// ืคืืจื ืืจืืจืช ืืืื ืืฉืจืช ื-callback ืืืงืืื
|
|
12
|
+
defaultPort: 4242
|
|
13
|
+
};
|
package/src/auth-flow.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import http from 'node:http';
|
|
2
|
+
import open from 'open';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
import { writeAllConfigs } from './config-writers.js';
|
|
6
|
+
import { APP_CONFIG } from './app-config.js';
|
|
7
|
+
|
|
8
|
+
export async function runSetup({ url, port }) {
|
|
9
|
+
console.log(chalk.bold('\n MCP Setup ' + url + ' ' + port + '\n'));
|
|
10
|
+
|
|
11
|
+
// 1. ืืคืขืื ืฉืจืช โ ืืืืืจ promise ืืื ืืืืืช ืขืืื ืขืืืื
|
|
12
|
+
const { promise: apiKeyPromise } = startCallbackServer(Number(port));
|
|
13
|
+
|
|
14
|
+
// 2. ืจืง ืขืืฉืื ืคืืชื ืืคืืคื
|
|
15
|
+
const authUrl = new URL(APP_CONFIG.authUrlBase);
|
|
16
|
+
authUrl.searchParams.set('callback', `http://localhost:${port}/callback`);
|
|
17
|
+
|
|
18
|
+
const spinner = ora('Opening browser...').start();
|
|
19
|
+
await open(authUrl.toString());
|
|
20
|
+
spinner.text = 'Waiting for authentication in browser...';
|
|
21
|
+
|
|
22
|
+
// 3. ืขืืฉืื ืืืื
|
|
23
|
+
const key = await apiKeyPromise;
|
|
24
|
+
spinner.succeed(chalk.green('Authenticated!'));
|
|
25
|
+
|
|
26
|
+
const writeSpinner = ora('Writing agent configs...').start();
|
|
27
|
+
const results = await writeAllConfigs({ mcpUrl: url, apiKey: key });
|
|
28
|
+
writeSpinner.stop();
|
|
29
|
+
|
|
30
|
+
for (const [agent, status] of Object.entries(results)) {
|
|
31
|
+
const icon = status.success ? chalk.green('โ') : chalk.yellow('โ');
|
|
32
|
+
const msg = status.success ? chalk.dim(status.path) : chalk.dim(status.reason);
|
|
33
|
+
console.log(` ${icon} ${agent.padEnd(18)} ${msg}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
console.log('\n' + chalk.bold(' Done!') + ' Restart your agent to pick up the new config.\n');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ื ืคืจื ื-waitForCallback โ ืืืืืจ { promise } ืืื await
|
|
40
|
+
function startCallbackServer(port) {
|
|
41
|
+
const promise = new Promise((resolve, reject) => {
|
|
42
|
+
const server = http.createServer((req, res) => {
|
|
43
|
+
const url = new URL(req.url, `http://localhost:${port}`);
|
|
44
|
+
if (url.pathname !== '/callback') { res.writeHead(404); res.end(); return; }
|
|
45
|
+
|
|
46
|
+
const apiKey = url.searchParams.get('api_key');
|
|
47
|
+
if (!apiKey) { res.writeHead(400); res.end('Missing api_key'); return; }
|
|
48
|
+
|
|
49
|
+
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
50
|
+
res.end(`<!DOCTYPE html><html><head><meta charset="utf-8">
|
|
51
|
+
<style>body{font-family:system-ui;display:flex;align-items:center;
|
|
52
|
+
justify-content:center;height:100vh;margin:0;background:#f9f9f7}
|
|
53
|
+
.card{text-align:center;padding:2rem 3rem;border-radius:16px;
|
|
54
|
+
background:#fff;box-shadow:0 2px 16px #0001}</style>
|
|
55
|
+
</head><body><div class="card">
|
|
56
|
+
<h2>โ Connected!</h2>
|
|
57
|
+
<b>1๐1 - we can together</b>
|
|
58
|
+
<p>You can close this tab and return to your terminal.</p>
|
|
59
|
+
</div></body></html>`);
|
|
60
|
+
|
|
61
|
+
server.close();
|
|
62
|
+
resolve(apiKey);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
server.listen(port, '127.0.0.1', () => {
|
|
66
|
+
console.log(chalk.dim(` Listening on http://localhost:${port}/callback`));
|
|
67
|
+
});
|
|
68
|
+
server.on('error', reject);
|
|
69
|
+
setTimeout(() => { server.close(); reject(new Error('Timed out')); }, 5 * 60 * 1000);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return { promise };
|
|
73
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import { APP_CONFIG } from './app-config.js';
|
|
5
|
+
|
|
6
|
+
const HOME = os.homedir();
|
|
7
|
+
|
|
8
|
+
// ืื agent โ ืืืคื ืืงืื ืคืื ืฉืื ืืืื ื ืจืื ืืคืืจืื
|
|
9
|
+
const AGENTS = {
|
|
10
|
+
'Claude Desktop': {
|
|
11
|
+
paths: {
|
|
12
|
+
darwin: path.join(HOME, 'Library/Application Support/Claude/claude_desktop_config.json'),
|
|
13
|
+
win32: path.join(process.env.APPDATA ?? '', 'Claude', 'claude_desktop_config.json'),
|
|
14
|
+
linux: path.join(HOME, '.config/claude/claude_desktop_config.json'),
|
|
15
|
+
},
|
|
16
|
+
write: (config, { mcpUrl, apiKey, name }) => {
|
|
17
|
+
config.mcpServers ??= {};
|
|
18
|
+
config.mcpServers[name] = {
|
|
19
|
+
url: mcpUrl,
|
|
20
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
21
|
+
};
|
|
22
|
+
return config;
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
'Cursor': {
|
|
27
|
+
paths: {
|
|
28
|
+
darwin: path.join(HOME, '.cursor/mcp.json'),
|
|
29
|
+
win32: path.join(HOME, '.cursor/mcp.json'),
|
|
30
|
+
linux: path.join(HOME, '.cursor/mcp.json'),
|
|
31
|
+
},
|
|
32
|
+
write: (config, { mcpUrl, apiKey, name }) => {
|
|
33
|
+
config.mcpServers ??= {};
|
|
34
|
+
config.mcpServers[name] = {
|
|
35
|
+
url: mcpUrl,
|
|
36
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
37
|
+
};
|
|
38
|
+
return config;
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
'Windsurf': {
|
|
43
|
+
paths: {
|
|
44
|
+
darwin: path.join(HOME, '.codeium/windsurf/mcp_config.json'),
|
|
45
|
+
win32: path.join(HOME, '.codeium/windsurf/mcp_config.json'),
|
|
46
|
+
linux: path.join(HOME, '.codeium/windsurf/mcp_config.json'),
|
|
47
|
+
},
|
|
48
|
+
write: (config, { mcpUrl, apiKey, name }) => {
|
|
49
|
+
config.mcpServers ??= {};
|
|
50
|
+
config.mcpServers[name] = {
|
|
51
|
+
serverUrl: mcpUrl, // Windsurf ืืฉืชืืฉ ื-serverUrl
|
|
52
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
53
|
+
};
|
|
54
|
+
return config;
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
'Claude Code': {
|
|
59
|
+
// ืขื ืคื ืืืืงืืื ืืฆืื ืืจืฉืืืช, ืืืืืจืืช ื ืฉืืจืืช ืืงืืืฅ .claude.json ืืชืืงืืืช ืืืืช
|
|
60
|
+
paths: {
|
|
61
|
+
darwin: path.join(HOME, '.claude.json'),
|
|
62
|
+
win32: path.join(HOME, '.claude.json'),
|
|
63
|
+
linux: path.join(HOME, '.claude.json'),
|
|
64
|
+
},
|
|
65
|
+
write: (config, { mcpUrl, apiKey, name }) => {
|
|
66
|
+
// ืื ืื ื ืฉืืืจืื ืชืืช ืืืืืืงื mcpServers ืืจืืฉื (User Scope - ืืืืืื)
|
|
67
|
+
config.mcpServers ??= {};
|
|
68
|
+
config.mcpServers[name] = {
|
|
69
|
+
type: 'http', // ืืืื ื-Claude Code ืืืืืืจ ืกืื ืืืืืจ
|
|
70
|
+
url: mcpUrl,
|
|
71
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
72
|
+
};
|
|
73
|
+
return config;
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
'Antigravity': {
|
|
77
|
+
paths: {
|
|
78
|
+
darwin: path.join(HOME, '.gemini/antigravity/mcp_config.json'),
|
|
79
|
+
win32: path.join(HOME, '.gemini/antigravity/mcp_config.json'),
|
|
80
|
+
linux: path.join(HOME, '.gemini/antigravity/mcp_config.json'),
|
|
81
|
+
},
|
|
82
|
+
write: (config, { mcpUrl, apiKey, name }) => {
|
|
83
|
+
config.mcpServers ??= {};
|
|
84
|
+
config.mcpServers[name] = {
|
|
85
|
+
serverUrl: mcpUrl, // Antigravity ืืฉืชืืฉ ื-serverUrl ืืืืืืจ ืืจืืืง
|
|
86
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
87
|
+
};
|
|
88
|
+
return config;
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
'VS Code': {
|
|
92
|
+
// VS Code MCP ืืืชื ืworkspace โ ื ืืชืื ื-global settings
|
|
93
|
+
paths: {
|
|
94
|
+
darwin: path.join(HOME, 'Library/Application Support/Code/User/settings.json'),
|
|
95
|
+
win32: path.join(process.env.APPDATA ?? '', 'Code', 'User', 'settings.json'),
|
|
96
|
+
linux: path.join(HOME, '.config/Code/User/settings.json'),
|
|
97
|
+
},
|
|
98
|
+
write: (config, { mcpUrl, apiKey, name }) => {
|
|
99
|
+
config['mcp.servers'] ??= {};
|
|
100
|
+
config['mcp.servers'][name] = {
|
|
101
|
+
url: mcpUrl,
|
|
102
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
103
|
+
};
|
|
104
|
+
return config;
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
'OpenClaw': {
|
|
108
|
+
paths: {
|
|
109
|
+
darwin: path.join(HOME, '.openclaw/config.json'),
|
|
110
|
+
win32: path.join(HOME, '.openclaw/config.json'), // ืืืืื ืืช ืื ืืจืื ืื ืืชืืงืืืช ืืืืช
|
|
111
|
+
linux: path.join(HOME, '.openclaw/config.json'),
|
|
112
|
+
},
|
|
113
|
+
write: (config, { mcpUrl, apiKey, name }) => {
|
|
114
|
+
// ืืืืืืืงื ืฉื OpenClaw ืื ืื ืืฆืืจื ืืงืื ื ืช: config.mcp.servers
|
|
115
|
+
config.mcp ??= {};
|
|
116
|
+
config.mcp.servers ??= {};
|
|
117
|
+
|
|
118
|
+
config.mcp.servers[name] = {
|
|
119
|
+
url: mcpUrl,
|
|
120
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
121
|
+
};
|
|
122
|
+
return config;
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
'Cline': {
|
|
127
|
+
paths: {
|
|
128
|
+
darwin: path.join(HOME, 'Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json'),
|
|
129
|
+
win32: path.join(process.env.APPDATA ?? '', 'Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json'),
|
|
130
|
+
linux: path.join(HOME, '.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json'),
|
|
131
|
+
},
|
|
132
|
+
write: (config, { mcpUrl, apiKey, name }) => {
|
|
133
|
+
config.mcpServers ??= {};
|
|
134
|
+
config.mcpServers[name] = {
|
|
135
|
+
url: mcpUrl,
|
|
136
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
137
|
+
};
|
|
138
|
+
return config;
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
'Roo Code': {
|
|
143
|
+
paths: {
|
|
144
|
+
darwin: path.join(HOME, 'Library/Application Support/Code/User/globalStorage/rooveterinaryinc.roo-cline/settings/cline_mcp_settings.json'),
|
|
145
|
+
win32: path.join(process.env.APPDATA ?? '', 'Code/User/globalStorage/rooveterinaryinc.roo-cline/settings/cline_mcp_settings.json'),
|
|
146
|
+
linux: path.join(HOME, '.config/Code/User/globalStorage/rooveterinaryinc.roo-cline/settings/cline_mcp_settings.json'),
|
|
147
|
+
},
|
|
148
|
+
write: (config, { mcpUrl, apiKey, name }) => {
|
|
149
|
+
config.mcpServers ??= {};
|
|
150
|
+
config.mcpServers[name] = {
|
|
151
|
+
url: mcpUrl,
|
|
152
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
153
|
+
};
|
|
154
|
+
return config;
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
'Continue': {
|
|
159
|
+
paths: {
|
|
160
|
+
darwin: path.join(HOME, '.continue/config.json'),
|
|
161
|
+
win32: path.join(HOME, '.continue/config.json'),
|
|
162
|
+
linux: path.join(HOME, '.continue/config.json'),
|
|
163
|
+
},
|
|
164
|
+
write: (config, { mcpUrl, apiKey, name }) => {
|
|
165
|
+
config.mcpServers ??= {};
|
|
166
|
+
// Continue.dev ืืฉืชืืฉ ืืืื ื ืืขื ืฉืื ื ืืืืืืจ transport
|
|
167
|
+
config.mcpServers[name] = {
|
|
168
|
+
transport: {
|
|
169
|
+
type: "sse",
|
|
170
|
+
url: mcpUrl,
|
|
171
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
return config;
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export async function writeAllConfigs({ mcpUrl, apiKey, name = APP_CONFIG.serviceName }) {
|
|
181
|
+
const platform = process.platform;
|
|
182
|
+
const results = {};
|
|
183
|
+
|
|
184
|
+
for (const [agentName, agent] of Object.entries(AGENTS)) {
|
|
185
|
+
const filePath = agent.paths[platform] ?? agent.paths['linux'];
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
// ืงืืจื ืงืื ืคืื ืงืืื (ืื ืืฉ) ืื ืืชืืื ืจืืง
|
|
189
|
+
let config = {};
|
|
190
|
+
if (fs.existsSync(filePath)) {
|
|
191
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
192
|
+
try {
|
|
193
|
+
config = JSON.parse(raw);
|
|
194
|
+
} catch (parseError) {
|
|
195
|
+
// ืืืคืื ืืืงืจื ืฉืืฉ ืืขืจืืช ืืงืืืฅ JSON (ืงืืจื ืืจืื ื-VS Code)
|
|
196
|
+
console.warn(`[Warning] Could not parse JSON for ${agentName}. Creating new config. Error: ${parseError.message}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// ืืขืืื
|
|
201
|
+
config = agent.write(config, { mcpUrl, apiKey, name });
|
|
202
|
+
|
|
203
|
+
// ืืืชื ืืืืจื
|
|
204
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
205
|
+
fs.writeFileSync(filePath, JSON.stringify(config, null, 2), 'utf-8');
|
|
206
|
+
|
|
207
|
+
results[agentName] = { success: true, path: filePath };
|
|
208
|
+
} catch (err) {
|
|
209
|
+
results[agentName] = { success: false, reason: err.message };
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return results;
|
|
214
|
+
}
|