@codify-ai/mcp-client 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-CLIENT.md +267 -0
- package/README.md +267 -0
- package/mcp-client.js +364 -0
- package/package.json +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Codify MCP Server
|
|
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-CLIENT.md
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# @codify-ai/mcp-client
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
**Codify MCP 客户端 - 连接 Figma 和 Cursor 的桥梁**
|
|
10
|
+
|
|
11
|
+
通过 MCP 协议从远程 Codify 服务器获取代码
|
|
12
|
+
|
|
13
|
+
[快速开始](#快速开始) · [配置说明](#配置说明) · [功能特性](#功能特性)
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 功能特性
|
|
20
|
+
|
|
21
|
+
- 🔌 **一键安装**:使用 `npx` 无需手动下载
|
|
22
|
+
- 📡 **MCP 协议**:完美集成 Cursor 等支持 MCP 的 IDE
|
|
23
|
+
- 🔐 **安全认证**:支持 access_key 认证
|
|
24
|
+
- 🛠️ **工具集成**:提供 `getCode` 和 `listChannels` 工具
|
|
25
|
+
- 📦 **资源访问**:通过 URI `codify://{channelId}/current` 访问代码
|
|
26
|
+
|
|
27
|
+
## 架构说明
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
Figma Plugin (WebSocket)
|
|
31
|
+
↓
|
|
32
|
+
Codify MCP Server (远程)
|
|
33
|
+
↓
|
|
34
|
+
@codify-ai/mcp-client (本包)
|
|
35
|
+
↓
|
|
36
|
+
Cursor IDE (本地)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 快速开始
|
|
40
|
+
|
|
41
|
+
### 1. 配置 Cursor
|
|
42
|
+
|
|
43
|
+
编辑 `~/.cursor/mcp.json`(如果文件不存在则创建):
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"mcpServers": {
|
|
48
|
+
"codify": {
|
|
49
|
+
"command": "npx",
|
|
50
|
+
"args": [
|
|
51
|
+
"-y",
|
|
52
|
+
"@codify/mcp-client",
|
|
53
|
+
"--url=http://your-server:8080"
|
|
54
|
+
],
|
|
55
|
+
"env": {
|
|
56
|
+
"CODIFY_ACCESS_KEY": "sk-your-access-key"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 2. 重启 Cursor
|
|
64
|
+
|
|
65
|
+
重启 Cursor 或重新加载 MCP 服务器配置。
|
|
66
|
+
|
|
67
|
+
### 3. 开始使用
|
|
68
|
+
|
|
69
|
+
在 Cursor 中,您可以:
|
|
70
|
+
|
|
71
|
+
#### 方式 1:使用 AI 工具调用
|
|
72
|
+
|
|
73
|
+
对 AI 说:
|
|
74
|
+
```
|
|
75
|
+
请使用 listChannels 工具查看所有可用频道
|
|
76
|
+
请使用 getCode 工具获取 my-channel 频道的代码
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### 方式 2:通过资源 URI 访问
|
|
80
|
+
|
|
81
|
+
在代码或对话中引用:
|
|
82
|
+
```
|
|
83
|
+
codify://my-channel/current
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 配置说明
|
|
87
|
+
|
|
88
|
+
### 命令行参数
|
|
89
|
+
|
|
90
|
+
| 参数 | 说明 | 默认值 |
|
|
91
|
+
|------|------|--------|
|
|
92
|
+
| `--url=<URL>` | Codify 服务器地址 | `http://localhost:8080` |
|
|
93
|
+
| `--help`, `-h` | 显示帮助信息 | - |
|
|
94
|
+
| `--version`, `-v` | 显示版本号 | - |
|
|
95
|
+
|
|
96
|
+
### 环境变量
|
|
97
|
+
|
|
98
|
+
| 变量名 | 说明 | 必需 |
|
|
99
|
+
|--------|------|------|
|
|
100
|
+
| `CODIFY_SERVER_URL` | 服务器地址(可被 --url 覆盖) | 否 |
|
|
101
|
+
| `CODIFY_ACCESS_KEY` | 访问密钥 | 是* |
|
|
102
|
+
|
|
103
|
+
*如果服务器启用了认证则必需
|
|
104
|
+
|
|
105
|
+
## 使用示例
|
|
106
|
+
|
|
107
|
+
### 示例 1:连接本地服务器(无认证)
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"mcpServers": {
|
|
112
|
+
"codify": {
|
|
113
|
+
"command": "npx",
|
|
114
|
+
"args": ["-y", "@codify/mcp-client"]
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 示例 2:连接远程服务器(带认证)
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"mcpServers": {
|
|
125
|
+
"codify": {
|
|
126
|
+
"command": "npx",
|
|
127
|
+
"args": [
|
|
128
|
+
"-y",
|
|
129
|
+
"@codify/mcp-client",
|
|
130
|
+
"--url=https://codify.example.com"
|
|
131
|
+
],
|
|
132
|
+
"env": {
|
|
133
|
+
"CODIFY_ACCESS_KEY": "sk-abc123xyz789"
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 示例 3:使用环境变量
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"mcpServers": {
|
|
145
|
+
"codify": {
|
|
146
|
+
"command": "npx",
|
|
147
|
+
"args": ["-y", "@codify/mcp-client"],
|
|
148
|
+
"env": {
|
|
149
|
+
"CODIFY_SERVER_URL": "http://192.168.1.100:8080",
|
|
150
|
+
"CODIFY_ACCESS_KEY": "sk-abc123xyz789"
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## 可用工具
|
|
158
|
+
|
|
159
|
+
### getCode
|
|
160
|
+
|
|
161
|
+
获取指定频道的代码。
|
|
162
|
+
|
|
163
|
+
**参数:**
|
|
164
|
+
- `channelId` (string, 必需) - 频道 ID
|
|
165
|
+
|
|
166
|
+
**示例:**
|
|
167
|
+
```
|
|
168
|
+
AI,请使用 getCode 工具获取 demo-channel 的代码
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### listChannels
|
|
172
|
+
|
|
173
|
+
列出所有可用频道。
|
|
174
|
+
|
|
175
|
+
**参数:** 无
|
|
176
|
+
|
|
177
|
+
**示例:**
|
|
178
|
+
```
|
|
179
|
+
AI,请使用 listChannels 工具查看所有频道
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## 可用资源
|
|
183
|
+
|
|
184
|
+
通过资源 URI 直接访问代码:
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
codify://{channelId}/current
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**示例:**
|
|
191
|
+
```
|
|
192
|
+
codify://demo-channel/current
|
|
193
|
+
codify://my-project/current
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## 故障排查
|
|
197
|
+
|
|
198
|
+
### 问题 1:连接失败
|
|
199
|
+
|
|
200
|
+
**错误信息:** `❌ 获取通道列表失败`
|
|
201
|
+
|
|
202
|
+
**解决方案:**
|
|
203
|
+
1. 确保 Codify 服务器正在运行
|
|
204
|
+
2. 检查服务器 URL 是否正确
|
|
205
|
+
3. 检查网络连接是否正常
|
|
206
|
+
4. 查看服务器日志
|
|
207
|
+
|
|
208
|
+
### 问题 2:认证失败
|
|
209
|
+
|
|
210
|
+
**错误信息:** `❌ 认证失败 (401)`
|
|
211
|
+
|
|
212
|
+
**解决方案:**
|
|
213
|
+
1. 确认 `CODIFY_ACCESS_KEY` 已设置
|
|
214
|
+
2. 检查 access_key 是否正确
|
|
215
|
+
3. 确认服务器启用了认证
|
|
216
|
+
|
|
217
|
+
### 问题 3:频道不存在
|
|
218
|
+
|
|
219
|
+
**错误信息:** `❌ 频道 "xxx" 不存在`
|
|
220
|
+
|
|
221
|
+
**解决方案:**
|
|
222
|
+
1. 使用 `listChannels` 工具查看所有可用频道
|
|
223
|
+
2. 确认 Figma 插件已连接并发送过代码
|
|
224
|
+
3. 检查频道 ID 拼写是否正确
|
|
225
|
+
|
|
226
|
+
## 调试模式
|
|
227
|
+
|
|
228
|
+
启用调试模式查看详细日志:
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"mcpServers": {
|
|
233
|
+
"codify": {
|
|
234
|
+
"command": "npx",
|
|
235
|
+
"args": ["-y", "@codify/mcp-client", "--url=http://localhost:8080"],
|
|
236
|
+
"env": {
|
|
237
|
+
"DEBUG": "true",
|
|
238
|
+
"CODIFY_ACCESS_KEY": "sk-xxx"
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## 相关项目
|
|
246
|
+
|
|
247
|
+
- **Codify MCP Server** - 服务端实现
|
|
248
|
+
- **Codify Figma Plugin** - Figma 插件
|
|
249
|
+
|
|
250
|
+
## 许可证
|
|
251
|
+
|
|
252
|
+
MIT
|
|
253
|
+
|
|
254
|
+
## 贡献
|
|
255
|
+
|
|
256
|
+
欢迎提交 Issue 和 Pull Request!
|
|
257
|
+
|
|
258
|
+
## 支持
|
|
259
|
+
|
|
260
|
+
如有问题,请:
|
|
261
|
+
1. 查看[文档](https://github.com/your-username/codify-mcp-client)
|
|
262
|
+
2. 提交 [Issue](https://github.com/your-username/codify-mcp-client/issues)
|
|
263
|
+
3. 加入我们的社区讨论
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
Made with ❤️ by Codify Team
|
package/README.md
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# @codify-ai/mcp-client
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
**Codify MCP 客户端 - 连接 Figma 和 Cursor 的桥梁**
|
|
10
|
+
|
|
11
|
+
通过 MCP 协议从远程 Codify 服务器获取代码
|
|
12
|
+
|
|
13
|
+
[快速开始](#快速开始) · [配置说明](#配置说明) · [功能特性](#功能特性)
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 功能特性
|
|
20
|
+
|
|
21
|
+
- 🔌 **一键安装**:使用 `npx` 无需手动下载
|
|
22
|
+
- 📡 **MCP 协议**:完美集成 Cursor 等支持 MCP 的 IDE
|
|
23
|
+
- 🔐 **安全认证**:支持 access_key 认证
|
|
24
|
+
- 🛠️ **工具集成**:提供 `getCode` 和 `listChannels` 工具
|
|
25
|
+
- 📦 **资源访问**:通过 URI `codify://{channelId}/current` 访问代码
|
|
26
|
+
|
|
27
|
+
## 架构说明
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
Figma Plugin (WebSocket)
|
|
31
|
+
↓
|
|
32
|
+
Codify MCP Server (远程)
|
|
33
|
+
↓
|
|
34
|
+
@codify-ai/mcp-client (本包)
|
|
35
|
+
↓
|
|
36
|
+
Cursor IDE (本地)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 快速开始
|
|
40
|
+
|
|
41
|
+
### 1. 配置 Cursor
|
|
42
|
+
|
|
43
|
+
编辑 `~/.cursor/mcp.json`(如果文件不存在则创建):
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"mcpServers": {
|
|
48
|
+
"codify": {
|
|
49
|
+
"command": "npx",
|
|
50
|
+
"args": [
|
|
51
|
+
"-y",
|
|
52
|
+
"@codify/mcp-client",
|
|
53
|
+
"--url=http://your-server:8080"
|
|
54
|
+
],
|
|
55
|
+
"env": {
|
|
56
|
+
"CODIFY_ACCESS_KEY": "sk-your-access-key"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 2. 重启 Cursor
|
|
64
|
+
|
|
65
|
+
重启 Cursor 或重新加载 MCP 服务器配置。
|
|
66
|
+
|
|
67
|
+
### 3. 开始使用
|
|
68
|
+
|
|
69
|
+
在 Cursor 中,您可以:
|
|
70
|
+
|
|
71
|
+
#### 方式 1:使用 AI 工具调用
|
|
72
|
+
|
|
73
|
+
对 AI 说:
|
|
74
|
+
```
|
|
75
|
+
请使用 listChannels 工具查看所有可用频道
|
|
76
|
+
请使用 getCode 工具获取 my-channel 频道的代码
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### 方式 2:通过资源 URI 访问
|
|
80
|
+
|
|
81
|
+
在代码或对话中引用:
|
|
82
|
+
```
|
|
83
|
+
codify://my-channel/current
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 配置说明
|
|
87
|
+
|
|
88
|
+
### 命令行参数
|
|
89
|
+
|
|
90
|
+
| 参数 | 说明 | 默认值 |
|
|
91
|
+
|------|------|--------|
|
|
92
|
+
| `--url=<URL>` | Codify 服务器地址 | `http://localhost:8080` |
|
|
93
|
+
| `--help`, `-h` | 显示帮助信息 | - |
|
|
94
|
+
| `--version`, `-v` | 显示版本号 | - |
|
|
95
|
+
|
|
96
|
+
### 环境变量
|
|
97
|
+
|
|
98
|
+
| 变量名 | 说明 | 必需 |
|
|
99
|
+
|--------|------|------|
|
|
100
|
+
| `CODIFY_SERVER_URL` | 服务器地址(可被 --url 覆盖) | 否 |
|
|
101
|
+
| `CODIFY_ACCESS_KEY` | 访问密钥 | 是* |
|
|
102
|
+
|
|
103
|
+
*如果服务器启用了认证则必需
|
|
104
|
+
|
|
105
|
+
## 使用示例
|
|
106
|
+
|
|
107
|
+
### 示例 1:连接本地服务器(无认证)
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"mcpServers": {
|
|
112
|
+
"codify": {
|
|
113
|
+
"command": "npx",
|
|
114
|
+
"args": ["-y", "@codify/mcp-client"]
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 示例 2:连接远程服务器(带认证)
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"mcpServers": {
|
|
125
|
+
"codify": {
|
|
126
|
+
"command": "npx",
|
|
127
|
+
"args": [
|
|
128
|
+
"-y",
|
|
129
|
+
"@codify/mcp-client",
|
|
130
|
+
"--url=https://codify.example.com"
|
|
131
|
+
],
|
|
132
|
+
"env": {
|
|
133
|
+
"CODIFY_ACCESS_KEY": "sk-abc123xyz789"
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 示例 3:使用环境变量
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"mcpServers": {
|
|
145
|
+
"codify": {
|
|
146
|
+
"command": "npx",
|
|
147
|
+
"args": ["-y", "@codify/mcp-client"],
|
|
148
|
+
"env": {
|
|
149
|
+
"CODIFY_SERVER_URL": "http://192.168.1.100:8080",
|
|
150
|
+
"CODIFY_ACCESS_KEY": "sk-abc123xyz789"
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## 可用工具
|
|
158
|
+
|
|
159
|
+
### getCode
|
|
160
|
+
|
|
161
|
+
获取指定频道的代码。
|
|
162
|
+
|
|
163
|
+
**参数:**
|
|
164
|
+
- `channelId` (string, 必需) - 频道 ID
|
|
165
|
+
|
|
166
|
+
**示例:**
|
|
167
|
+
```
|
|
168
|
+
AI,请使用 getCode 工具获取 demo-channel 的代码
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### listChannels
|
|
172
|
+
|
|
173
|
+
列出所有可用频道。
|
|
174
|
+
|
|
175
|
+
**参数:** 无
|
|
176
|
+
|
|
177
|
+
**示例:**
|
|
178
|
+
```
|
|
179
|
+
AI,请使用 listChannels 工具查看所有频道
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## 可用资源
|
|
183
|
+
|
|
184
|
+
通过资源 URI 直接访问代码:
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
codify://{channelId}/current
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**示例:**
|
|
191
|
+
```
|
|
192
|
+
codify://demo-channel/current
|
|
193
|
+
codify://my-project/current
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## 故障排查
|
|
197
|
+
|
|
198
|
+
### 问题 1:连接失败
|
|
199
|
+
|
|
200
|
+
**错误信息:** `❌ 获取通道列表失败`
|
|
201
|
+
|
|
202
|
+
**解决方案:**
|
|
203
|
+
1. 确保 Codify 服务器正在运行
|
|
204
|
+
2. 检查服务器 URL 是否正确
|
|
205
|
+
3. 检查网络连接是否正常
|
|
206
|
+
4. 查看服务器日志
|
|
207
|
+
|
|
208
|
+
### 问题 2:认证失败
|
|
209
|
+
|
|
210
|
+
**错误信息:** `❌ 认证失败 (401)`
|
|
211
|
+
|
|
212
|
+
**解决方案:**
|
|
213
|
+
1. 确认 `CODIFY_ACCESS_KEY` 已设置
|
|
214
|
+
2. 检查 access_key 是否正确
|
|
215
|
+
3. 确认服务器启用了认证
|
|
216
|
+
|
|
217
|
+
### 问题 3:频道不存在
|
|
218
|
+
|
|
219
|
+
**错误信息:** `❌ 频道 "xxx" 不存在`
|
|
220
|
+
|
|
221
|
+
**解决方案:**
|
|
222
|
+
1. 使用 `listChannels` 工具查看所有可用频道
|
|
223
|
+
2. 确认 Figma 插件已连接并发送过代码
|
|
224
|
+
3. 检查频道 ID 拼写是否正确
|
|
225
|
+
|
|
226
|
+
## 调试模式
|
|
227
|
+
|
|
228
|
+
启用调试模式查看详细日志:
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"mcpServers": {
|
|
233
|
+
"codify": {
|
|
234
|
+
"command": "npx",
|
|
235
|
+
"args": ["-y", "@codify/mcp-client", "--url=http://localhost:8080"],
|
|
236
|
+
"env": {
|
|
237
|
+
"DEBUG": "true",
|
|
238
|
+
"CODIFY_ACCESS_KEY": "sk-xxx"
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## 相关项目
|
|
246
|
+
|
|
247
|
+
- **Codify MCP Server** - 服务端实现
|
|
248
|
+
- **Codify Figma Plugin** - Figma 插件
|
|
249
|
+
|
|
250
|
+
## 许可证
|
|
251
|
+
|
|
252
|
+
MIT
|
|
253
|
+
|
|
254
|
+
## 贡献
|
|
255
|
+
|
|
256
|
+
欢迎提交 Issue 和 Pull Request!
|
|
257
|
+
|
|
258
|
+
## 支持
|
|
259
|
+
|
|
260
|
+
如有问题,请:
|
|
261
|
+
1. 查看[文档](https://github.com/your-username/codify-mcp-client)
|
|
262
|
+
2. 提交 [Issue](https://github.com/your-username/codify-mcp-client/issues)
|
|
263
|
+
3. 加入我们的社区讨论
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
Made with ❤️ by Codify Team
|
package/mcp-client.js
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Codify MCP Client
|
|
5
|
+
* 连接到远程 Codify MCP Server 的客户端适配器
|
|
6
|
+
*
|
|
7
|
+
* 使用方法:
|
|
8
|
+
* 在 Cursor 配置 (~/.cursor/mcp.json) 中:
|
|
9
|
+
* {
|
|
10
|
+
* "mcpServers": {
|
|
11
|
+
* "codify": {
|
|
12
|
+
* "command": "npx",
|
|
13
|
+
* "args": ["-y", "@codify/mcp-client", "--url=http://your-server:8080"],
|
|
14
|
+
* "env": {
|
|
15
|
+
* "CODIFY_ACCESS_KEY": "sk-your-access-key"
|
|
16
|
+
* }
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
23
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
24
|
+
|
|
25
|
+
function parseArgs() {
|
|
26
|
+
const args = process.argv.slice(2);
|
|
27
|
+
let serverUrl = process.env.CODIFY_SERVER_URL || 'http://localhost:8080';
|
|
28
|
+
|
|
29
|
+
for (let i = 0; i < args.length; i++) {
|
|
30
|
+
const arg = args[i];
|
|
31
|
+
|
|
32
|
+
if (arg === '--help' || arg === '-h') {
|
|
33
|
+
console.log(`
|
|
34
|
+
Codify MCP Client - 连接到远程 Codify MCP 服务器
|
|
35
|
+
|
|
36
|
+
用法:
|
|
37
|
+
npx -y @codify/mcp-client [选项]
|
|
38
|
+
|
|
39
|
+
选项:
|
|
40
|
+
--url=<URL> 服务器 URL (默认: http://localhost:8080)
|
|
41
|
+
--help, -h 显示帮助信息
|
|
42
|
+
--version, -v 显示版本号
|
|
43
|
+
|
|
44
|
+
环境变量:
|
|
45
|
+
CODIFY_SERVER_URL 服务器 URL
|
|
46
|
+
CODIFY_ACCESS_KEY 访问密钥
|
|
47
|
+
|
|
48
|
+
示例:
|
|
49
|
+
npx -y @codify/mcp-client --url=http://localhost:8080
|
|
50
|
+
CODIFY_ACCESS_KEY=sk-xxx npx -y @codify/mcp-client
|
|
51
|
+
|
|
52
|
+
Cursor 配置示例 (~/.cursor/mcp.json):
|
|
53
|
+
{
|
|
54
|
+
"mcpServers": {
|
|
55
|
+
"codify": {
|
|
56
|
+
"command": "npx",
|
|
57
|
+
"args": ["-y", "@codify/mcp-client", "--url=http://your-server:8080"],
|
|
58
|
+
"env": {
|
|
59
|
+
"CODIFY_ACCESS_KEY": "sk-your-access-key"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
`);
|
|
65
|
+
process.exit(0);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (arg === '--version' || arg === '-v') {
|
|
69
|
+
console.log('1.0.0');
|
|
70
|
+
process.exit(0);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (arg.startsWith('--url=')) {
|
|
74
|
+
serverUrl = arg.substring(6);
|
|
75
|
+
} else if (arg === '--url' && i + 1 < args.length) {
|
|
76
|
+
serverUrl = args[++i];
|
|
77
|
+
} else if (!arg.startsWith('-')) {
|
|
78
|
+
serverUrl = arg;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return { serverUrl };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const { serverUrl: SERVER_URL } = parseArgs();
|
|
86
|
+
const ACCESS_KEY = process.env.CODIFY_ACCESS_KEY;
|
|
87
|
+
|
|
88
|
+
if (process.env.DEBUG) {
|
|
89
|
+
console.error(`[DEBUG] 环境变量:`, Object.keys(process.env).filter(k => k.includes('CODIFY')));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
console.error(`🔌 连接到远程服务器: ${SERVER_URL}`);
|
|
93
|
+
if (ACCESS_KEY) {
|
|
94
|
+
console.error(`🔑 使用认证密钥: ${ACCESS_KEY.substring(0, 10)}...`);
|
|
95
|
+
} else {
|
|
96
|
+
console.error(`⚠️ 未设置认证密钥 (CODIFY_ACCESS_KEY)`);
|
|
97
|
+
console.error(`💡 提示: 请在 ~/.cursor/mcp.json 的 "env" 字段中设置 CODIFY_ACCESS_KEY`);
|
|
98
|
+
console.error(`💡 或者通过环境变量: export CODIFY_ACCESS_KEY=sk-xxx`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// 初始化 MCP Server
|
|
102
|
+
const mcpServer = new McpServer({
|
|
103
|
+
name: "Codify-MCP-Client",
|
|
104
|
+
version: "1.0.0",
|
|
105
|
+
}, {
|
|
106
|
+
capabilities: {
|
|
107
|
+
resources: {},
|
|
108
|
+
tools: {} // 添加 tools 能力
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// 注册资源(使用 ResourceTemplate)
|
|
113
|
+
const resourceTemplate = new ResourceTemplate(
|
|
114
|
+
"codify://{channelId}/current",
|
|
115
|
+
{
|
|
116
|
+
list: async () => {
|
|
117
|
+
try {
|
|
118
|
+
// 从远程服务器获取所有通道列表
|
|
119
|
+
const headers = {};
|
|
120
|
+
if (ACCESS_KEY) {
|
|
121
|
+
headers['Authorization'] = `Bearer ${ACCESS_KEY}`;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const response = await fetch(`${SERVER_URL}/channels`, { headers });
|
|
125
|
+
if (!response.ok) {
|
|
126
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
127
|
+
}
|
|
128
|
+
const channels = await response.json();
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
resources: channels.map(ch => ({
|
|
132
|
+
uri: `codify://${ch.channelId}/current`,
|
|
133
|
+
name: `${ch.channelId}-code`,
|
|
134
|
+
mimeType: "text/plain"
|
|
135
|
+
}))
|
|
136
|
+
};
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.error(`❌ 获取通道列表失败:`, error);
|
|
139
|
+
return { resources: [] };
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
complete: {}
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
mcpServer.registerResource(
|
|
147
|
+
"current-code",
|
|
148
|
+
resourceTemplate,
|
|
149
|
+
{ mimeType: "text/plain" },
|
|
150
|
+
async (uri, variables) => {
|
|
151
|
+
try {
|
|
152
|
+
// 从 variables 中获取 channelId(由 SDK 解析)
|
|
153
|
+
const channelId = variables.channelId || uri.hostname;
|
|
154
|
+
|
|
155
|
+
// 添加认证头
|
|
156
|
+
const headers = {};
|
|
157
|
+
if (ACCESS_KEY) {
|
|
158
|
+
headers['Authorization'] = `Bearer ${ACCESS_KEY}`;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// 通过 HTTP API 从远程服务器获取数据
|
|
162
|
+
const response = await fetch(`${SERVER_URL}/api/channel/${channelId}`, { headers });
|
|
163
|
+
|
|
164
|
+
if (!response.ok) {
|
|
165
|
+
// 如果 API 返回错误,尝试从 channels 列表中查找
|
|
166
|
+
const channelsResponse = await fetch(`${SERVER_URL}/channels`, { headers });
|
|
167
|
+
|
|
168
|
+
if (!channelsResponse.ok) {
|
|
169
|
+
return {
|
|
170
|
+
contents: [{
|
|
171
|
+
uri: uri.href,
|
|
172
|
+
text: `// 认证失败或服务器错误 (${channelsResponse.status})`
|
|
173
|
+
}]
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const channels = await channelsResponse.json();
|
|
178
|
+
const channel = channels.find(ch => ch.channelId === channelId);
|
|
179
|
+
|
|
180
|
+
if (!channel) {
|
|
181
|
+
return {
|
|
182
|
+
contents: [{
|
|
183
|
+
uri: uri.href,
|
|
184
|
+
text: `// 通道 ${channelId} 不存在或为空`
|
|
185
|
+
}]
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// 需要从完整数据中获取代码
|
|
190
|
+
// 这里返回一个提示,因为我们没有直接的 API
|
|
191
|
+
return {
|
|
192
|
+
contents: [{
|
|
193
|
+
uri: uri.href,
|
|
194
|
+
text: `// 通道 ${channelId} 存在\n// 代码长度: ${channel.codeLength} 字符\n// 最后更新: ${channel.lastUpdate}`
|
|
195
|
+
}]
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const data = await response.json();
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
contents: [{
|
|
203
|
+
uri: uri.href,
|
|
204
|
+
text: data.code || "// 等待 Figma WebSocket..."
|
|
205
|
+
}]
|
|
206
|
+
};
|
|
207
|
+
} catch (error) {
|
|
208
|
+
console.error(`❌ 获取资源失败:`, error);
|
|
209
|
+
return {
|
|
210
|
+
contents: [{
|
|
211
|
+
uri: uri.href,
|
|
212
|
+
text: `// 错误: ${error.message}`
|
|
213
|
+
}]
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
// 注册工具:getCode - 从 SQLite 获取指定频道的代码
|
|
220
|
+
mcpServer.registerTool(
|
|
221
|
+
"getCode",
|
|
222
|
+
{
|
|
223
|
+
description: "从 Codify 服务器获取指定频道的代码",
|
|
224
|
+
inputSchema: {
|
|
225
|
+
type: "object",
|
|
226
|
+
properties: {
|
|
227
|
+
channelId: {
|
|
228
|
+
type: "string",
|
|
229
|
+
description: "频道 ID,例如: my-demo, test-channel"
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
required: ["channelId"]
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
async ({ channelId }) => {
|
|
236
|
+
try {
|
|
237
|
+
console.error(`[Tool] getCode 被调用: channelId=${channelId}`);
|
|
238
|
+
|
|
239
|
+
// 添加认证头
|
|
240
|
+
const headers = {};
|
|
241
|
+
if (ACCESS_KEY) {
|
|
242
|
+
headers['Authorization'] = `Bearer ${ACCESS_KEY}`;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// 从远程服务器获取代码
|
|
246
|
+
const response = await fetch(`${SERVER_URL}/api/channel/${channelId}`, { headers });
|
|
247
|
+
|
|
248
|
+
if (!response.ok) {
|
|
249
|
+
if (response.status === 404) {
|
|
250
|
+
return {
|
|
251
|
+
content: [
|
|
252
|
+
{
|
|
253
|
+
type: "text",
|
|
254
|
+
text: `❌ 频道 "${channelId}" 不存在\n\n💡 使用 listChannels 工具查看所有可用频道`
|
|
255
|
+
}
|
|
256
|
+
]
|
|
257
|
+
};
|
|
258
|
+
} else if (response.status === 401 || response.status === 403) {
|
|
259
|
+
return {
|
|
260
|
+
content: [
|
|
261
|
+
{
|
|
262
|
+
type: "text",
|
|
263
|
+
text: `❌ 认证失败 (${response.status})\n\n请检查 CODIFY_ACCESS_KEY 是否正确`
|
|
264
|
+
}
|
|
265
|
+
]
|
|
266
|
+
};
|
|
267
|
+
} else {
|
|
268
|
+
throw new Error(`HTTP ${response.status}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const data = await response.json();
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
content: [
|
|
276
|
+
{
|
|
277
|
+
type: "text",
|
|
278
|
+
text: `✅ 成功获取频道 "${channelId}" 的代码:\n\n\`\`\`\n${data.code}\n\`\`\`\n\n📊 元数据:\n- 代码长度: ${data.code.length} 字符\n- 最后更新: ${data.lastUpdate}`
|
|
279
|
+
}
|
|
280
|
+
]
|
|
281
|
+
};
|
|
282
|
+
} catch (error) {
|
|
283
|
+
console.error(`[Tool] getCode 错误:`, error);
|
|
284
|
+
return {
|
|
285
|
+
content: [
|
|
286
|
+
{
|
|
287
|
+
type: "text",
|
|
288
|
+
text: `❌ 获取代码失败: ${error.message}\n\n请确保:\n1. Codify 服务器正在运行\n2. 频道 ID 正确\n3. 网络连接正常`
|
|
289
|
+
}
|
|
290
|
+
],
|
|
291
|
+
isError: true
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
// 注册工具:listChannels - 列出所有可用频道
|
|
298
|
+
mcpServer.registerTool(
|
|
299
|
+
"listChannels",
|
|
300
|
+
{
|
|
301
|
+
description: "列出 Codify 服务器上所有可用的频道"
|
|
302
|
+
},
|
|
303
|
+
async () => {
|
|
304
|
+
try {
|
|
305
|
+
console.error(`[Tool] listChannels 被调用`);
|
|
306
|
+
|
|
307
|
+
// 添加认证头
|
|
308
|
+
const headers = {};
|
|
309
|
+
if (ACCESS_KEY) {
|
|
310
|
+
headers['Authorization'] = `Bearer ${ACCESS_KEY}`;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// 从远程服务器获取频道列表
|
|
314
|
+
const response = await fetch(`${SERVER_URL}/channels`, { headers });
|
|
315
|
+
|
|
316
|
+
if (!response.ok) {
|
|
317
|
+
throw new Error(`HTTP ${response.status}`);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const channels = await response.json();
|
|
321
|
+
|
|
322
|
+
if (channels.length === 0) {
|
|
323
|
+
return {
|
|
324
|
+
content: [
|
|
325
|
+
{
|
|
326
|
+
type: "text",
|
|
327
|
+
text: "📭 暂无可用频道\n\n💡 通过 WebSocket 发送代码到服务器来创建频道"
|
|
328
|
+
}
|
|
329
|
+
]
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const channelList = channels.map((ch, i) =>
|
|
334
|
+
`${i + 1}. **${ch.channelId}**\n - 代码长度: ${ch.codeLength} 字符\n - 最后更新: ${ch.lastUpdate}`
|
|
335
|
+
).join('\n\n');
|
|
336
|
+
|
|
337
|
+
return {
|
|
338
|
+
content: [
|
|
339
|
+
{
|
|
340
|
+
type: "text",
|
|
341
|
+
text: `📺 可用频道列表 (共 ${channels.length} 个):\n\n${channelList}\n\n💡 使用 getCode 工具获取具体频道的代码`
|
|
342
|
+
}
|
|
343
|
+
]
|
|
344
|
+
};
|
|
345
|
+
} catch (error) {
|
|
346
|
+
console.error(`[Tool] listChannels 错误:`, error);
|
|
347
|
+
return {
|
|
348
|
+
content: [
|
|
349
|
+
{
|
|
350
|
+
type: "text",
|
|
351
|
+
text: `❌ 获取频道列表失败: ${error.message}`
|
|
352
|
+
}
|
|
353
|
+
],
|
|
354
|
+
isError: true
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
// 连接 stdio 传输
|
|
361
|
+
const transport = new StdioServerTransport();
|
|
362
|
+
await mcpServer.connect(transport);
|
|
363
|
+
|
|
364
|
+
console.error('✅ MCP 客户端已启动');
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@codify-ai/mcp-client",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Codify MCP 客户端 - 连接到远程 Codify MCP 服务器,供 Cursor 等 IDE 使用",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"codify-mcp-client": "./mcp-client.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./mcp-client.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"mcp-client.js",
|
|
12
|
+
"README-CLIENT.md"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=18.0.0",
|
|
16
|
+
"npm": ">=8.0.0"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"mcp",
|
|
20
|
+
"model-context-protocol",
|
|
21
|
+
"figma",
|
|
22
|
+
"ide",
|
|
23
|
+
"cursor",
|
|
24
|
+
"code-generation",
|
|
25
|
+
"client",
|
|
26
|
+
"websocket",
|
|
27
|
+
"sqlite"
|
|
28
|
+
],
|
|
29
|
+
"author": "Your Name <your-email@example.com>",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/your-username/codify-mcp-client.git"
|
|
34
|
+
},
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/your-username/codify-mcp-client/issues"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://github.com/your-username/codify-mcp-client#readme",
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@modelcontextprotocol/sdk": "^1.0.4"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
}
|
|
45
|
+
}
|