@portkey/eoa-agent-skills 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/LICENSE +21 -0
- package/README.md +191 -0
- package/README.zh-CN.md +191 -0
- package/bin/platforms/claude.ts +54 -0
- package/bin/platforms/cursor.ts +63 -0
- package/bin/platforms/openclaw.ts +57 -0
- package/bin/platforms/utils.ts +145 -0
- package/bin/setup.ts +182 -0
- package/cli-helpers.ts +12 -0
- package/index.ts +92 -0
- package/lib/aelf.ts +320 -0
- package/lib/api.ts +286 -0
- package/lib/config.ts +95 -0
- package/lib/crypto.ts +25 -0
- package/lib/storage.ts +82 -0
- package/lib/types.ts +352 -0
- package/mcp-config.example.json +13 -0
- package/openclaw.json +48 -0
- package/package.json +51 -0
- package/portkey_eoa_skill.ts +424 -0
- package/src/core/bridge.ts +173 -0
- package/src/core/contract.ts +179 -0
- package/src/core/query.ts +139 -0
- package/src/core/transfer.ts +126 -0
- package/src/core/wallet.ts +200 -0
- package/src/mcp/server.ts +844 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Portkey
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# @portkey/eoa-agent-skills
|
|
2
|
+
|
|
3
|
+
AI Agent Skills for Portkey EOA Wallet on [aelf blockchain](https://aelf.com). Provides MCP, CLI, and SDK interfaces for wallet management, token transfers, asset queries, and smart contract interactions.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Wallet Management**: Create, import, list, and backup EOA wallets with AES-encrypted local storage
|
|
8
|
+
- **Token Queries**: Check balances, prices, and token lists across aelf chains
|
|
9
|
+
- **NFT Queries**: Browse NFT collections and items
|
|
10
|
+
- **Transaction History**: Query and inspect past transactions
|
|
11
|
+
- **Token Transfers**: Same-chain and cross-chain transfers within aelf
|
|
12
|
+
- **Contract Interactions**: Generic view/send calls, approve, fee estimation
|
|
13
|
+
- **eBridge**: Cross-chain transfers between aelf and EVM chains
|
|
14
|
+
|
|
15
|
+
## Consumption Modes
|
|
16
|
+
|
|
17
|
+
| Mode | Entry | Use Case |
|
|
18
|
+
|------|-------|----------|
|
|
19
|
+
| **MCP** | `src/mcp/server.ts` | Claude Desktop, Cursor, GPT, and other AI tools |
|
|
20
|
+
| **CLI** | `portkey_eoa_skill.ts` | Terminal scripts, OpenClaw |
|
|
21
|
+
| **SDK** | `index.ts` | LangChain, LlamaIndex, custom agents |
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bun install
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### One-Click Setup
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Claude Desktop
|
|
35
|
+
bun run bin/setup.ts claude
|
|
36
|
+
|
|
37
|
+
# Cursor (project-level)
|
|
38
|
+
bun run bin/setup.ts cursor
|
|
39
|
+
|
|
40
|
+
# Cursor (global)
|
|
41
|
+
bun run bin/setup.ts cursor --global
|
|
42
|
+
|
|
43
|
+
# OpenClaw (output config)
|
|
44
|
+
bun run bin/setup.ts openclaw
|
|
45
|
+
|
|
46
|
+
# OpenClaw (merge into existing config)
|
|
47
|
+
bun run bin/setup.ts openclaw --config-path /path/to/openclaw-config.json
|
|
48
|
+
|
|
49
|
+
# Check status
|
|
50
|
+
bun run bin/setup.ts list
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Environment Variables
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
cp .env.example .env
|
|
57
|
+
# Edit .env with your values
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
| Variable | Description | Default |
|
|
61
|
+
|----------|-------------|---------|
|
|
62
|
+
| `PORTKEY_NETWORK` | `mainnet` | `mainnet` |
|
|
63
|
+
| `PORTKEY_API_URL` | Override API base URL | Auto from network |
|
|
64
|
+
| `PORTKEY_PRIVATE_KEY` | Plaintext private key (optional) | — |
|
|
65
|
+
| `PORTKEY_WALLET_DIR` | Custom wallet storage directory | `~/.portkey-agent/wallets/` |
|
|
66
|
+
| `PORTKEY_WALLET_PASSWORD` | Password for local wallet encryption | — |
|
|
67
|
+
|
|
68
|
+
### MCP Server
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
bun run src/mcp/server.ts
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Or add to your MCP client config (see `mcp-config.example.json`):
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"mcpServers": {
|
|
79
|
+
"portkey-eoa-agent-skills": {
|
|
80
|
+
"command": "bun",
|
|
81
|
+
"args": ["run", "/path/to/src/mcp/server.ts"],
|
|
82
|
+
"env": {
|
|
83
|
+
"PORTKEY_NETWORK": "mainnet",
|
|
84
|
+
"PORTKEY_WALLET_PASSWORD": "your_password"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### CLI Usage
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Wallet
|
|
95
|
+
bun run portkey_eoa_skill.ts wallet create --password mypass
|
|
96
|
+
bun run portkey_eoa_skill.ts wallet list
|
|
97
|
+
bun run portkey_eoa_skill.ts wallet import --mnemonic "word1 word2 ..." --password mypass
|
|
98
|
+
|
|
99
|
+
# Queries
|
|
100
|
+
bun run portkey_eoa_skill.ts query tokens --address YOUR_ADDRESS
|
|
101
|
+
bun run portkey_eoa_skill.ts query balance --address YOUR_ADDRESS --symbol ELF --chain-id AELF
|
|
102
|
+
bun run portkey_eoa_skill.ts query price --symbols ELF,USDT
|
|
103
|
+
bun run portkey_eoa_skill.ts query history --address YOUR_ADDRESS
|
|
104
|
+
bun run portkey_eoa_skill.ts query chains
|
|
105
|
+
|
|
106
|
+
# Transfer
|
|
107
|
+
bun run portkey_eoa_skill.ts transfer --to RECIPIENT --symbol ELF --amount 100000000 --chain-id AELF
|
|
108
|
+
|
|
109
|
+
# Contract
|
|
110
|
+
bun run portkey_eoa_skill.ts contract view --contract-address ADDR --method GetBalance --params '{"symbol":"ELF","owner":"..."}' --chain-id AELF
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### SDK Usage
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { getConfig, createWallet, getTokenList, transfer } from '@portkey/eoa-agent-skills';
|
|
117
|
+
|
|
118
|
+
const config = getConfig('mainnet');
|
|
119
|
+
|
|
120
|
+
// Create wallet
|
|
121
|
+
const wallet = await createWallet(config, { password: 'mypass' });
|
|
122
|
+
console.log('Address:', wallet.address);
|
|
123
|
+
|
|
124
|
+
// Query tokens
|
|
125
|
+
const tokens = await getTokenList(config, { address: wallet.address });
|
|
126
|
+
console.log('Tokens:', tokens.data);
|
|
127
|
+
|
|
128
|
+
// Transfer
|
|
129
|
+
const result = await transfer(config, {
|
|
130
|
+
privateKey: 'YOUR_PRIVATE_KEY',
|
|
131
|
+
to: 'RECIPIENT_ADDRESS',
|
|
132
|
+
symbol: 'ELF',
|
|
133
|
+
amount: '100000000',
|
|
134
|
+
chainId: 'AELF',
|
|
135
|
+
});
|
|
136
|
+
console.log('TX:', result.transactionId);
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## MCP Tools (20 total)
|
|
140
|
+
|
|
141
|
+
### Wallet Management (5)
|
|
142
|
+
- `portkey_create_wallet` — Create new wallet with encrypted local storage
|
|
143
|
+
- `portkey_import_wallet` — Import from mnemonic or private key
|
|
144
|
+
- `portkey_get_wallet_info` — View wallet public info
|
|
145
|
+
- `portkey_list_wallets` — List all local wallets
|
|
146
|
+
- `portkey_backup_wallet` — Export wallet credentials
|
|
147
|
+
|
|
148
|
+
### Asset Queries (7)
|
|
149
|
+
- `portkey_get_token_list` — Token portfolio with balances
|
|
150
|
+
- `portkey_get_token_balance` — Single token balance
|
|
151
|
+
- `portkey_get_token_prices` — Token USD prices
|
|
152
|
+
- `portkey_get_nft_collections` — NFT collection list
|
|
153
|
+
- `portkey_get_nft_items` — NFT items in collection
|
|
154
|
+
- `portkey_get_transaction_history` — Transaction history
|
|
155
|
+
- `portkey_get_transaction_detail` — Single transaction detail
|
|
156
|
+
|
|
157
|
+
### Transfers (2)
|
|
158
|
+
- `portkey_transfer` — Same-chain token transfer
|
|
159
|
+
- `portkey_cross_chain_transfer` — Cross-chain aelf transfer
|
|
160
|
+
|
|
161
|
+
### Contract (4)
|
|
162
|
+
- `portkey_approve` — Token spending approval
|
|
163
|
+
- `portkey_call_view_method` — Generic contract read
|
|
164
|
+
- `portkey_call_send_method` — Generic contract write
|
|
165
|
+
- `portkey_estimate_fee` — Transaction fee estimation
|
|
166
|
+
|
|
167
|
+
### eBridge (2)
|
|
168
|
+
- `portkey_ebridge_transfer` — eBridge cross-chain transfer
|
|
169
|
+
- `portkey_ebridge_info` — eBridge limits and fees
|
|
170
|
+
|
|
171
|
+
## Architecture
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
index.ts (SDK) ─┐
|
|
175
|
+
server.ts (MCP) ─┼─> src/core/ ──> lib/
|
|
176
|
+
skill.ts (CLI) ─┘ (pure logic) (infra)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Three adapters call the same core functions — zero duplicated logic.
|
|
180
|
+
|
|
181
|
+
## Testing
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
bun test # All tests
|
|
185
|
+
bun test tests/unit/ # Unit tests
|
|
186
|
+
bun run tests/e2e/mcp-verify.ts # MCP verification
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## License
|
|
190
|
+
|
|
191
|
+
MIT
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# @portkey/eoa-agent-skills
|
|
2
|
+
|
|
3
|
+
[aelf 区块链](https://aelf.com) 上 Portkey EOA 钱包的 AI Agent Skills。提供 MCP、CLI 和 SDK 三种接口,覆盖钱包管理、Token 转账、资产查询和智能合约交互。
|
|
4
|
+
|
|
5
|
+
## 功能
|
|
6
|
+
|
|
7
|
+
- **钱包管理**:创建、导入、列表、备份 EOA 钱包,本地 AES 加密存储
|
|
8
|
+
- **Token 查询**:查询余额、价格、Token 列表(跨链)
|
|
9
|
+
- **NFT 查询**:浏览 NFT Collection 和具体 Item
|
|
10
|
+
- **交易历史**:查询和检索历史交易
|
|
11
|
+
- **Token 转账**:aelf 同链和跨链转账
|
|
12
|
+
- **合约交互**:通用 view/send 调用、Approve、手续费预估
|
|
13
|
+
- **eBridge**:aelf 与 EVM 链之间的跨链转账
|
|
14
|
+
|
|
15
|
+
## 消费方式
|
|
16
|
+
|
|
17
|
+
| 模式 | 入口 | 适用场景 |
|
|
18
|
+
|------|------|---------|
|
|
19
|
+
| **MCP** | `src/mcp/server.ts` | Claude Desktop、Cursor、GPT 等 AI 工具 |
|
|
20
|
+
| **CLI** | `portkey_eoa_skill.ts` | 终端脚本、OpenClaw |
|
|
21
|
+
| **SDK** | `index.ts` | LangChain、LlamaIndex、自定义 Agent |
|
|
22
|
+
|
|
23
|
+
## 快速开始
|
|
24
|
+
|
|
25
|
+
### 安装
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bun install
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 一键配置
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Claude Desktop
|
|
35
|
+
bun run bin/setup.ts claude
|
|
36
|
+
|
|
37
|
+
# Cursor(项目级)
|
|
38
|
+
bun run bin/setup.ts cursor
|
|
39
|
+
|
|
40
|
+
# Cursor(全局)
|
|
41
|
+
bun run bin/setup.ts cursor --global
|
|
42
|
+
|
|
43
|
+
# OpenClaw(输出配置)
|
|
44
|
+
bun run bin/setup.ts openclaw
|
|
45
|
+
|
|
46
|
+
# OpenClaw(合并到已有配置文件)
|
|
47
|
+
bun run bin/setup.ts openclaw --config-path /path/to/openclaw-config.json
|
|
48
|
+
|
|
49
|
+
# 查看配置状态
|
|
50
|
+
bun run bin/setup.ts list
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 环境变量
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
cp .env.example .env
|
|
57
|
+
# 编辑 .env 填入你的配置
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
| 变量 | 说明 | 默认值 |
|
|
61
|
+
|------|------|--------|
|
|
62
|
+
| `PORTKEY_NETWORK` | `mainnet` | `mainnet` |
|
|
63
|
+
| `PORTKEY_API_URL` | 覆盖 API 基础 URL | 根据网络自动选择 |
|
|
64
|
+
| `PORTKEY_PRIVATE_KEY` | 明文私钥(可选) | — |
|
|
65
|
+
| `PORTKEY_WALLET_DIR` | 自定义钱包存储目录 | `~/.portkey-agent/wallets/` |
|
|
66
|
+
| `PORTKEY_WALLET_PASSWORD` | 本地钱包加密密码 | — |
|
|
67
|
+
|
|
68
|
+
### MCP Server
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
bun run src/mcp/server.ts
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
或添加到你的 MCP 客户端配置(参见 `mcp-config.example.json`):
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"mcpServers": {
|
|
79
|
+
"portkey-eoa-agent-skills": {
|
|
80
|
+
"command": "bun",
|
|
81
|
+
"args": ["run", "/path/to/src/mcp/server.ts"],
|
|
82
|
+
"env": {
|
|
83
|
+
"PORTKEY_NETWORK": "mainnet",
|
|
84
|
+
"PORTKEY_WALLET_PASSWORD": "your_password"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### CLI 使用
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# 钱包
|
|
95
|
+
bun run portkey_eoa_skill.ts wallet create --password mypass
|
|
96
|
+
bun run portkey_eoa_skill.ts wallet list
|
|
97
|
+
bun run portkey_eoa_skill.ts wallet import --mnemonic "word1 word2 ..." --password mypass
|
|
98
|
+
|
|
99
|
+
# 查询
|
|
100
|
+
bun run portkey_eoa_skill.ts query tokens --address 你的地址
|
|
101
|
+
bun run portkey_eoa_skill.ts query balance --address 你的地址 --symbol ELF --chain-id AELF
|
|
102
|
+
bun run portkey_eoa_skill.ts query price --symbols ELF,USDT
|
|
103
|
+
bun run portkey_eoa_skill.ts query history --address 你的地址
|
|
104
|
+
bun run portkey_eoa_skill.ts query chains
|
|
105
|
+
|
|
106
|
+
# 转账
|
|
107
|
+
bun run portkey_eoa_skill.ts transfer --to 收款地址 --symbol ELF --amount 100000000 --chain-id AELF
|
|
108
|
+
|
|
109
|
+
# 合约调用
|
|
110
|
+
bun run portkey_eoa_skill.ts contract view --contract-address 合约地址 --method GetBalance --params '{"symbol":"ELF","owner":"..."}' --chain-id AELF
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### SDK 使用
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { getConfig, createWallet, getTokenList, transfer } from '@portkey/eoa-agent-skills';
|
|
117
|
+
|
|
118
|
+
const config = getConfig('mainnet');
|
|
119
|
+
|
|
120
|
+
// 创建钱包
|
|
121
|
+
const wallet = await createWallet(config, { password: 'mypass' });
|
|
122
|
+
console.log('地址:', wallet.address);
|
|
123
|
+
|
|
124
|
+
// 查询 Token
|
|
125
|
+
const tokens = await getTokenList(config, { address: wallet.address });
|
|
126
|
+
console.log('Tokens:', tokens.data);
|
|
127
|
+
|
|
128
|
+
// 转账
|
|
129
|
+
const result = await transfer(config, {
|
|
130
|
+
privateKey: '你的私钥',
|
|
131
|
+
to: '收款地址',
|
|
132
|
+
symbol: 'ELF',
|
|
133
|
+
amount: '100000000',
|
|
134
|
+
chainId: 'AELF',
|
|
135
|
+
});
|
|
136
|
+
console.log('交易ID:', result.transactionId);
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## MCP Tools(共 20 个)
|
|
140
|
+
|
|
141
|
+
### 钱包管理(5)
|
|
142
|
+
- `portkey_create_wallet` — 创建新钱包并加密存储
|
|
143
|
+
- `portkey_import_wallet` — 导入钱包(助记词/私钥)
|
|
144
|
+
- `portkey_get_wallet_info` — 查看钱包公开信息
|
|
145
|
+
- `portkey_list_wallets` — 列出所有本地钱包
|
|
146
|
+
- `portkey_backup_wallet` — 导出钱包凭证
|
|
147
|
+
|
|
148
|
+
### 资产查询(7)
|
|
149
|
+
- `portkey_get_token_list` — Token 列表和余额
|
|
150
|
+
- `portkey_get_token_balance` — 单个 Token 余额
|
|
151
|
+
- `portkey_get_token_prices` — Token USD 价格
|
|
152
|
+
- `portkey_get_nft_collections` — NFT Collection 列表
|
|
153
|
+
- `portkey_get_nft_items` — Collection 内的 NFT
|
|
154
|
+
- `portkey_get_transaction_history` — 交易历史
|
|
155
|
+
- `portkey_get_transaction_detail` — 单笔交易详情
|
|
156
|
+
|
|
157
|
+
### 转账(2)
|
|
158
|
+
- `portkey_transfer` — 同链 Token 转账
|
|
159
|
+
- `portkey_cross_chain_transfer` — aelf 跨链转账
|
|
160
|
+
|
|
161
|
+
### 合约(4)
|
|
162
|
+
- `portkey_approve` — Token 授权
|
|
163
|
+
- `portkey_call_view_method` — 通用合约只读调用
|
|
164
|
+
- `portkey_call_send_method` — 通用合约写调用
|
|
165
|
+
- `portkey_estimate_fee` — 交易手续费预估
|
|
166
|
+
|
|
167
|
+
### eBridge(2)
|
|
168
|
+
- `portkey_ebridge_transfer` — eBridge 跨链转账
|
|
169
|
+
- `portkey_ebridge_info` — eBridge 限额和手续费
|
|
170
|
+
|
|
171
|
+
## 架构
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
index.ts (SDK) ─┐
|
|
175
|
+
server.ts (MCP) ─┼─> src/core/ ──> lib/
|
|
176
|
+
skill.ts (CLI) ─┘ (纯逻辑) (基础设施)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
三个适配器调用同一套 Core 函数——零重复逻辑。
|
|
180
|
+
|
|
181
|
+
## 测试
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
bun test # 所有测试
|
|
185
|
+
bun test tests/unit/ # 单元测试
|
|
186
|
+
bun run tests/e2e/mcp-verify.ts # MCP 验证
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## License
|
|
190
|
+
|
|
191
|
+
MIT
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getPlatformPaths,
|
|
3
|
+
readJsonFile,
|
|
4
|
+
writeJsonFile,
|
|
5
|
+
mergeMcpConfig,
|
|
6
|
+
removeMcpConfig,
|
|
7
|
+
generateMcpEntry,
|
|
8
|
+
SERVER_NAME,
|
|
9
|
+
} from './utils.js';
|
|
10
|
+
|
|
11
|
+
export function setupClaude(opts: {
|
|
12
|
+
configPath?: string;
|
|
13
|
+
serverPath?: string;
|
|
14
|
+
force?: boolean;
|
|
15
|
+
}) {
|
|
16
|
+
const paths = getPlatformPaths();
|
|
17
|
+
const configPath = opts.configPath || paths.claude;
|
|
18
|
+
const existing = readJsonFile(configPath);
|
|
19
|
+
const entry = generateMcpEntry(opts.serverPath);
|
|
20
|
+
const { config, action } = mergeMcpConfig(
|
|
21
|
+
existing,
|
|
22
|
+
SERVER_NAME,
|
|
23
|
+
entry,
|
|
24
|
+
opts.force,
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
if (action === 'skipped') {
|
|
28
|
+
console.log(
|
|
29
|
+
`[SKIP] "${SERVER_NAME}" already exists in ${configPath}. Use --force to overwrite.`,
|
|
30
|
+
);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
writeJsonFile(configPath, config);
|
|
35
|
+
console.log(`[${action.toUpperCase()}] Claude Desktop config → ${configPath}`);
|
|
36
|
+
console.log(
|
|
37
|
+
'\nRemember to replace <YOUR_PRIVATE_KEY> and <YOUR_WALLET_PASSWORD> in the config.',
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function uninstallClaude(opts: { configPath?: string }) {
|
|
42
|
+
const paths = getPlatformPaths();
|
|
43
|
+
const configPath = opts.configPath || paths.claude;
|
|
44
|
+
const existing = readJsonFile(configPath);
|
|
45
|
+
const { config, removed } = removeMcpConfig(existing, SERVER_NAME);
|
|
46
|
+
|
|
47
|
+
if (!removed) {
|
|
48
|
+
console.log(`[SKIP] "${SERVER_NAME}" not found in ${configPath}`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
writeJsonFile(configPath, config);
|
|
53
|
+
console.log(`[REMOVED] "${SERVER_NAME}" from ${configPath}`);
|
|
54
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getPlatformPaths,
|
|
3
|
+
readJsonFile,
|
|
4
|
+
writeJsonFile,
|
|
5
|
+
mergeMcpConfig,
|
|
6
|
+
removeMcpConfig,
|
|
7
|
+
generateMcpEntry,
|
|
8
|
+
SERVER_NAME,
|
|
9
|
+
} from './utils.js';
|
|
10
|
+
|
|
11
|
+
export function setupCursor(opts: {
|
|
12
|
+
global?: boolean;
|
|
13
|
+
configPath?: string;
|
|
14
|
+
serverPath?: string;
|
|
15
|
+
force?: boolean;
|
|
16
|
+
}) {
|
|
17
|
+
const paths = getPlatformPaths();
|
|
18
|
+
const configPath =
|
|
19
|
+
opts.configPath || (opts.global ? paths.cursorGlobal : paths.cursorProject);
|
|
20
|
+
const existing = readJsonFile(configPath);
|
|
21
|
+
const entry = generateMcpEntry(opts.serverPath);
|
|
22
|
+
const { config, action } = mergeMcpConfig(
|
|
23
|
+
existing,
|
|
24
|
+
SERVER_NAME,
|
|
25
|
+
entry,
|
|
26
|
+
opts.force,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
if (action === 'skipped') {
|
|
30
|
+
console.log(
|
|
31
|
+
`[SKIP] "${SERVER_NAME}" already exists in ${configPath}. Use --force to overwrite.`,
|
|
32
|
+
);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
writeJsonFile(configPath, config);
|
|
37
|
+
const scope = opts.global ? 'global' : 'project-level';
|
|
38
|
+
console.log(
|
|
39
|
+
`[${action.toUpperCase()}] Cursor ${scope} config → ${configPath}`,
|
|
40
|
+
);
|
|
41
|
+
console.log(
|
|
42
|
+
'\nRemember to replace <YOUR_PRIVATE_KEY> and <YOUR_WALLET_PASSWORD> in the config.',
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function uninstallCursor(opts: {
|
|
47
|
+
global?: boolean;
|
|
48
|
+
configPath?: string;
|
|
49
|
+
}) {
|
|
50
|
+
const paths = getPlatformPaths();
|
|
51
|
+
const configPath =
|
|
52
|
+
opts.configPath || (opts.global ? paths.cursorGlobal : paths.cursorProject);
|
|
53
|
+
const existing = readJsonFile(configPath);
|
|
54
|
+
const { config, removed } = removeMcpConfig(existing, SERVER_NAME);
|
|
55
|
+
|
|
56
|
+
if (!removed) {
|
|
57
|
+
console.log(`[SKIP] "${SERVER_NAME}" not found in ${configPath}`);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
writeJsonFile(configPath, config);
|
|
62
|
+
console.log(`[REMOVED] "${SERVER_NAME}" from ${configPath}`);
|
|
63
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import {
|
|
4
|
+
getPackageRoot,
|
|
5
|
+
readJsonFile,
|
|
6
|
+
writeJsonFile,
|
|
7
|
+
} from './utils.js';
|
|
8
|
+
|
|
9
|
+
export function setupOpenclaw(opts: {
|
|
10
|
+
configPath?: string;
|
|
11
|
+
cwd?: string;
|
|
12
|
+
force?: boolean;
|
|
13
|
+
}) {
|
|
14
|
+
const pkgRoot = getPackageRoot();
|
|
15
|
+
const openclawSrc = path.join(pkgRoot, 'openclaw.json');
|
|
16
|
+
|
|
17
|
+
if (!fs.existsSync(openclawSrc)) {
|
|
18
|
+
console.log('[ERROR] openclaw.json not found in package root');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const openclawConfig = readJsonFile(openclawSrc);
|
|
23
|
+
|
|
24
|
+
// Replace cwd placeholder if specified
|
|
25
|
+
if (opts.cwd) {
|
|
26
|
+
if (openclawConfig.tools) {
|
|
27
|
+
for (const tool of openclawConfig.tools) {
|
|
28
|
+
if (tool.cwd) tool.cwd = opts.cwd;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (opts.configPath) {
|
|
34
|
+
// Merge into existing config
|
|
35
|
+
const existing = readJsonFile(opts.configPath);
|
|
36
|
+
if (!existing.tools) existing.tools = [];
|
|
37
|
+
|
|
38
|
+
const existingNames = new Set(
|
|
39
|
+
existing.tools.map((t: any) => t.name),
|
|
40
|
+
);
|
|
41
|
+
let added = 0;
|
|
42
|
+
for (const tool of openclawConfig.tools || []) {
|
|
43
|
+
if (existingNames.has(tool.name) && !opts.force) continue;
|
|
44
|
+
existing.tools = existing.tools.filter(
|
|
45
|
+
(t: any) => t.name !== tool.name,
|
|
46
|
+
);
|
|
47
|
+
existing.tools.push(tool);
|
|
48
|
+
added++;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
writeJsonFile(opts.configPath, existing);
|
|
52
|
+
console.log(`[DONE] Merged ${added} tools into ${opts.configPath}`);
|
|
53
|
+
} else {
|
|
54
|
+
// Just output the config
|
|
55
|
+
console.log(JSON.stringify(openclawConfig, null, 2));
|
|
56
|
+
}
|
|
57
|
+
}
|