foliko 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/.claude/settings.local.json +30 -0
- package/22.txt +10 -0
- package/README.md +218 -0
- package/SPEC.md +452 -0
- package/cli/bin/foliko.js +12 -0
- package/cli/src/commands/chat.js +75 -0
- package/cli/src/index.js +64 -0
- package/cli/src/ui/chat-ui.js +272 -0
- package/cli/src/utils/ansi.js +40 -0
- package/cli/src/utils/markdown.js +296 -0
- package/docs/quick-reference.md +131 -0
- package/docs/user-manual.md +1205 -0
- package/examples/basic.js +110 -0
- package/examples/bootstrap.js +93 -0
- package/examples/mcp-example.js +53 -0
- package/examples/skill-example.js +49 -0
- package/examples/workflow.js +158 -0
- package/package.json +36 -0
- package/plugins/ai-plugin.js +89 -0
- package/plugins/audit-plugin.js +187 -0
- package/plugins/default-plugins.js +412 -0
- package/plugins/file-system-plugin.js +344 -0
- package/plugins/install-plugin.js +93 -0
- package/plugins/python-executor-plugin.js +331 -0
- package/plugins/rules-plugin.js +292 -0
- package/plugins/scheduler-plugin.js +426 -0
- package/plugins/session-plugin.js +343 -0
- package/plugins/shell-executor-plugin.js +196 -0
- package/plugins/storage-plugin.js +237 -0
- package/plugins/subagent-plugin.js +395 -0
- package/plugins/think-plugin.js +329 -0
- package/plugins/tools-plugin.js +114 -0
- package/skills/mcp-usage/SKILL.md +198 -0
- package/skills/vb-agent-dev/AGENTS.md +162 -0
- package/skills/vb-agent-dev/SKILL.md +370 -0
- package/src/capabilities/index.js +11 -0
- package/src/capabilities/skill-manager.js +319 -0
- package/src/capabilities/workflow-engine.js +401 -0
- package/src/core/agent-chat.js +311 -0
- package/src/core/agent.js +573 -0
- package/src/core/framework.js +255 -0
- package/src/core/index.js +19 -0
- package/src/core/plugin-base.js +205 -0
- package/src/core/plugin-manager.js +392 -0
- package/src/core/provider.js +108 -0
- package/src/core/tool-registry.js +134 -0
- package/src/core/tool-router.js +216 -0
- package/src/executors/executor-base.js +58 -0
- package/src/executors/mcp-executor.js +728 -0
- package/src/index.js +37 -0
- package/src/utils/event-emitter.js +97 -0
- package/test-chat.js +129 -0
- package/test-mcp.js +79 -0
- package/test-reload.js +61 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Think 主动思考插件
|
|
3
|
+
* 支持 LLM 自我唤醒、自动反思、持续思考
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { Plugin } = require('../src/core/plugin-base')
|
|
7
|
+
const { z } = require('zod')
|
|
8
|
+
|
|
9
|
+
class ThinkPlugin extends Plugin {
|
|
10
|
+
constructor(config = {}) {
|
|
11
|
+
super()
|
|
12
|
+
this.name = 'think'
|
|
13
|
+
this.version = '1.0.0'
|
|
14
|
+
this.description = '主动思考插件,支持 LLM 自我唤醒和持续思考'
|
|
15
|
+
this.priority = 5 // 高优先级,早期加载
|
|
16
|
+
|
|
17
|
+
this.config = {
|
|
18
|
+
autoReflect: config.autoReflect === true, // 默认关闭自动反思
|
|
19
|
+
reflectDelay: config.reflectDelay || 2000, // 反思延迟(ms)
|
|
20
|
+
maxReflectDepth: config.maxReflectDepth || 3, // 最大反思深度
|
|
21
|
+
enableContinuous: config.enableContinuous || false // 是否启用持续思考
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
this._framework = null
|
|
25
|
+
this._thoughts = [] // 思考记录
|
|
26
|
+
this._reflectionChain = [] // 反思链
|
|
27
|
+
this._continuousMode = false
|
|
28
|
+
this._continuousTimer = null
|
|
29
|
+
this._pendingReflection = null
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
install(framework) {
|
|
33
|
+
this._framework = framework
|
|
34
|
+
return this
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
start(framework) {
|
|
38
|
+
// 注册思考工具
|
|
39
|
+
framework.registerTool({
|
|
40
|
+
name: 'think_now',
|
|
41
|
+
description: '立即触发 LLM 主动思考(用于反思、自我检视、生成想法)',
|
|
42
|
+
inputSchema: z.object({
|
|
43
|
+
topic: z.string().optional().describe('思考主题,不提供则让 LLM 自己决定思考什么'),
|
|
44
|
+
mode: z.enum(['reflect', 'brainstorm', 'analyze', 'plan']).optional().describe('思考模式'),
|
|
45
|
+
depth: z.number().optional().describe('思考深度 1-5')
|
|
46
|
+
}),
|
|
47
|
+
execute: async (args) => {
|
|
48
|
+
return await this._triggerThinking(args)
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
framework.registerTool({
|
|
53
|
+
name: 'think_continue',
|
|
54
|
+
description: '让 LLM 持续思考模式(后台自动思考,定期输出结果)',
|
|
55
|
+
inputSchema: z.object({
|
|
56
|
+
interval: z.number().optional().describe('思考间隔毫秒,默认 30000 (30秒)'),
|
|
57
|
+
topic: z.string().optional().describe('思考主题')
|
|
58
|
+
}),
|
|
59
|
+
execute: async (args) => {
|
|
60
|
+
return await this._startContinuousThinking(args)
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
framework.registerTool({
|
|
65
|
+
name: 'think_stop',
|
|
66
|
+
description: '停止持续思考模式',
|
|
67
|
+
inputSchema: z.object({}),
|
|
68
|
+
execute: async () => {
|
|
69
|
+
return this._stopContinuousThinking()
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
framework.registerTool({
|
|
74
|
+
name: 'think_get_thoughts',
|
|
75
|
+
description: '获取思考历史记录',
|
|
76
|
+
inputSchema: z.object({
|
|
77
|
+
limit: z.number().optional().describe('返回条数,默认 10')
|
|
78
|
+
}),
|
|
79
|
+
execute: async (args) => {
|
|
80
|
+
const limit = args.limit || 10
|
|
81
|
+
return {
|
|
82
|
+
success: true,
|
|
83
|
+
thoughts: this._thoughts.slice(-limit).reverse(),
|
|
84
|
+
total: this._thoughts.length
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
return this
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* 触发主动思考
|
|
94
|
+
*/
|
|
95
|
+
async _triggerThinking(args) {
|
|
96
|
+
const mode = args.mode || 'reflect'
|
|
97
|
+
const depth = Math.min(args.depth || 2, 5)
|
|
98
|
+
const topic = args.topic || '刚才的对话还有什么可以改进或补充的地方?'
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
const agent = this._getActiveAgent()
|
|
102
|
+
if (!agent) {
|
|
103
|
+
return { success: false, error: 'No active agent found' }
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const reflectPrompt = this._buildReflectPrompt(mode, depth, topic)
|
|
107
|
+
const result = await agent.chat(reflectPrompt)
|
|
108
|
+
|
|
109
|
+
const thought = {
|
|
110
|
+
id: Date.now(),
|
|
111
|
+
mode,
|
|
112
|
+
depth,
|
|
113
|
+
topic,
|
|
114
|
+
prompt: reflectPrompt,
|
|
115
|
+
result: typeof result === 'string' ? result : JSON.stringify(result),
|
|
116
|
+
timestamp: new Date()
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
this._thoughts.push(thought)
|
|
120
|
+
if (this._thoughts.length > 100) {
|
|
121
|
+
this._thoughts = this._thoughts.slice(-100)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 触发思考完成事件
|
|
125
|
+
if (this._framework) {
|
|
126
|
+
this._framework.emit('think:thought_completed', thought)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
success: true,
|
|
131
|
+
thought,
|
|
132
|
+
message: `【主动思考完成】\n模式: ${mode}\n主题: ${topic}\n\n${typeof result === 'string' ? result : JSON.stringify(result, null, 2)}`
|
|
133
|
+
}
|
|
134
|
+
} catch (err) {
|
|
135
|
+
return { success: false, error: err.message }
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* 构建反思提示
|
|
141
|
+
*/
|
|
142
|
+
_buildReflectPrompt(mode, depth, topic) {
|
|
143
|
+
const depthDesc = {
|
|
144
|
+
1: '快速检视',
|
|
145
|
+
2: '简单反思',
|
|
146
|
+
3: '深入思考',
|
|
147
|
+
4: '批判性分析',
|
|
148
|
+
5: '全面审视'
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const modePrompts = {
|
|
152
|
+
reflect: `你刚刚完成了一次对话。请${depthDesc[depth]}:
|
|
153
|
+
|
|
154
|
+
1. 检查回答是否完整、准确
|
|
155
|
+
2. 是否有遗漏的重要信息
|
|
156
|
+
3. 是否有更好的表达方式
|
|
157
|
+
4. 是否需要补充示例或细节
|
|
158
|
+
|
|
159
|
+
${topic ? `额外关注: ${topic}` : ''}
|
|
160
|
+
|
|
161
|
+
请直接输出你的反思结果,不需要重复之前的对话内容。`,
|
|
162
|
+
|
|
163
|
+
brainstorm: `请进行头脑风暴,针对以下主题产生更多想法:
|
|
164
|
+
|
|
165
|
+
${topic || '刚才讨论的内容'}
|
|
166
|
+
|
|
167
|
+
产生至少 3-5 个新的观点或方向,不必拘泥于之前讨论的内容。`,
|
|
168
|
+
|
|
169
|
+
analyze: `请对以下主题进行深度分析:
|
|
170
|
+
|
|
171
|
+
${topic || '刚才讨论的内容'}
|
|
172
|
+
|
|
173
|
+
分析要点:
|
|
174
|
+
- 根本原因是什么?
|
|
175
|
+
- 有哪些支持/反对的证据?
|
|
176
|
+
- 可能的发展方向?`,
|
|
177
|
+
|
|
178
|
+
plan: `基于目前的讨论,请制定下一步计划:
|
|
179
|
+
|
|
180
|
+
${topic || '接下来的行动'}
|
|
181
|
+
|
|
182
|
+
计划要具体、可执行,包含时间线和预期结果。`
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return modePrompts[mode] || modePrompts.reflect
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* 自动反思(响应完成后)
|
|
190
|
+
*/
|
|
191
|
+
async _autoReflect(data) {
|
|
192
|
+
if (!this._framework) return
|
|
193
|
+
|
|
194
|
+
try {
|
|
195
|
+
// 检查是否需要反思(避免短时间重复反思)
|
|
196
|
+
const lastThought = this._thoughts[this._thoughts.length - 1]
|
|
197
|
+
if (lastThought && Date.now() - lastThought.timestamp.getTime() < 10000) {
|
|
198
|
+
return // 10秒内不重复反思
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const agent = this._getActiveAgent()
|
|
202
|
+
if (!agent) return
|
|
203
|
+
|
|
204
|
+
// 构建轻量级反思
|
|
205
|
+
const reflectPrompt = `作为助手,请快速检视刚才的回答是否:
|
|
206
|
+
1. 完整回答了用户的问题
|
|
207
|
+
2. 表达清晰易懂
|
|
208
|
+
3. 有没有遗漏关键信息
|
|
209
|
+
|
|
210
|
+
如果发现不足,请直接补充。如果没问题,请简短回复"检查完毕,无需补充"。`
|
|
211
|
+
|
|
212
|
+
// 静默思考,不打断用户
|
|
213
|
+
const result = await agent.chat(reflectPrompt)
|
|
214
|
+
|
|
215
|
+
const thought = {
|
|
216
|
+
id: Date.now(),
|
|
217
|
+
mode: 'auto-reflect',
|
|
218
|
+
topic: '自动检视',
|
|
219
|
+
result: typeof result === 'string' ? result : '反思完成',
|
|
220
|
+
timestamp: new Date(),
|
|
221
|
+
auto: true
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
this._thoughts.push(thought)
|
|
225
|
+
|
|
226
|
+
// 如果反思有重要补充,触发事件通知
|
|
227
|
+
if (typeof result === 'string' && result.includes('补充') && !result.includes('无需补充')) {
|
|
228
|
+
this._framework.emit('think:reflection_needs_attention', {
|
|
229
|
+
thought,
|
|
230
|
+
originalData: data
|
|
231
|
+
})
|
|
232
|
+
}
|
|
233
|
+
} catch (err) {
|
|
234
|
+
console.error('[Think] Auto-reflect error:', err.message)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* 启动持续思考模式
|
|
240
|
+
*/
|
|
241
|
+
async _startContinuousThinking(args) {
|
|
242
|
+
if (this._continuousMode) {
|
|
243
|
+
return { success: false, error: 'Continuous thinking already running' }
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const interval = args.interval || 30000
|
|
247
|
+
const topic = args.topic || '基于最近的对话,还有什么值得深入思考的方向?'
|
|
248
|
+
|
|
249
|
+
this._continuousMode = true
|
|
250
|
+
this._continuousTopic = topic
|
|
251
|
+
|
|
252
|
+
const runThink = async () => {
|
|
253
|
+
if (!this._continuousMode) return
|
|
254
|
+
|
|
255
|
+
try {
|
|
256
|
+
await this._triggerThinking({
|
|
257
|
+
topic: this._continuousTopic,
|
|
258
|
+
mode: 'reflect',
|
|
259
|
+
depth: 2
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
// 触发下一轮
|
|
263
|
+
if (this._continuousMode) {
|
|
264
|
+
this._continuousTimer = setTimeout(runThink, interval)
|
|
265
|
+
}
|
|
266
|
+
} catch (err) {
|
|
267
|
+
console.error('[Think] Continuous think error:', err.message)
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// 立即执行一次
|
|
272
|
+
await runThink()
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
success: true,
|
|
276
|
+
message: `【持续思考已启动】\n间隔: ${interval}ms\n主题: ${topic}\n\nLLM 将定期自动思考并在有新想法时通知你。`
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* 停止持续思考模式
|
|
282
|
+
*/
|
|
283
|
+
_stopContinuousThinking() {
|
|
284
|
+
this._continuousMode = false
|
|
285
|
+
if (this._continuousTimer) {
|
|
286
|
+
clearTimeout(this._continuousTimer)
|
|
287
|
+
this._continuousTimer = null
|
|
288
|
+
}
|
|
289
|
+
return {
|
|
290
|
+
success: true,
|
|
291
|
+
message: '持续思考已停止'
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* 获取当前活跃的 Agent
|
|
297
|
+
*/
|
|
298
|
+
_getActiveAgent() {
|
|
299
|
+
if (this._framework._agents && this._framework._agents.length > 0) {
|
|
300
|
+
for (let i = this._framework._agents.length - 1; i >= 0; i--) {
|
|
301
|
+
const agent = this._framework._agents[i]
|
|
302
|
+
if (agent.getStatus() === 'idle') {
|
|
303
|
+
return agent
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return null
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* 获取待处理的反思通知
|
|
312
|
+
*/
|
|
313
|
+
getPendingThoughts() {
|
|
314
|
+
return this._thoughts.slice(-10).reverse()
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
reload(framework) {
|
|
318
|
+
this._framework = framework
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
uninstall(framework) {
|
|
322
|
+
this._stopContinuousThinking()
|
|
323
|
+
this._thoughts = []
|
|
324
|
+
this._reflectionChain = []
|
|
325
|
+
this._framework = null
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
module.exports = { ThinkPlugin }
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 工具插件
|
|
3
|
+
* 提供内置工具和热重载功能
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { Plugin } = require('../src/core/plugin-base')
|
|
7
|
+
const { z } = require('zod')
|
|
8
|
+
|
|
9
|
+
class ToolsPlugin extends Plugin {
|
|
10
|
+
constructor(config = {}) {
|
|
11
|
+
super()
|
|
12
|
+
this.name = 'tools'
|
|
13
|
+
this.version = '1.0.0'
|
|
14
|
+
this.description = '内置工具插件,提供热重载和工具管理功能'
|
|
15
|
+
this.priority = 10
|
|
16
|
+
|
|
17
|
+
this._framework = null
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
install(framework) {
|
|
21
|
+
this._framework = framework
|
|
22
|
+
this._registerBuiltinTools()
|
|
23
|
+
return this
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
start(framework) {
|
|
27
|
+
// 工具已通过 install 注册
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
_registerBuiltinTools() {
|
|
31
|
+
const framework = this._framework
|
|
32
|
+
|
|
33
|
+
// 热重载插件工具
|
|
34
|
+
framework.registerTool({
|
|
35
|
+
name: 'reload_plugins',
|
|
36
|
+
description: '热重载插件。可以重载单个指定插件,或重载所有插件。',
|
|
37
|
+
inputSchema: z.object({
|
|
38
|
+
pluginName: z.string().optional().describe('可选:指定要重载的插件名称,不指定则重载所有插件')
|
|
39
|
+
}),
|
|
40
|
+
execute: async (args) => {
|
|
41
|
+
try {
|
|
42
|
+
if (args.pluginName) {
|
|
43
|
+
await framework.reloadPlugin(args.pluginName)
|
|
44
|
+
return {
|
|
45
|
+
success: true,
|
|
46
|
+
message: `Plugin '${args.pluginName}' reloaded successfully`
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
await framework.reloadAllPlugins()
|
|
50
|
+
return {
|
|
51
|
+
success: true,
|
|
52
|
+
message: 'All plugins reloaded successfully'
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
} catch (err) {
|
|
56
|
+
return {
|
|
57
|
+
success: false,
|
|
58
|
+
error: err.message
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
// 列出已加载插件工具
|
|
65
|
+
framework.registerTool({
|
|
66
|
+
name: 'list_plugins',
|
|
67
|
+
description: '列出所有已加载的插件',
|
|
68
|
+
inputSchema: z.object({}),
|
|
69
|
+
execute: async () => {
|
|
70
|
+
const plugins = framework.pluginManager.getAll()
|
|
71
|
+
return {
|
|
72
|
+
success: true,
|
|
73
|
+
plugins: plugins.map(p => ({
|
|
74
|
+
name: p.name,
|
|
75
|
+
version: p.instance?.version
|
|
76
|
+
}))
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
// 获取工具列表
|
|
82
|
+
framework.registerTool({
|
|
83
|
+
name: 'list_tools',
|
|
84
|
+
description: '列出所有已注册的工具',
|
|
85
|
+
inputSchema: z.object({}),
|
|
86
|
+
execute: async () => {
|
|
87
|
+
const tools = framework.getTools()
|
|
88
|
+
return {
|
|
89
|
+
success: true,
|
|
90
|
+
tools: tools.map(t => ({
|
|
91
|
+
name: t.name,
|
|
92
|
+
description: t.description
|
|
93
|
+
}))
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
reload(framework) {
|
|
100
|
+
console.log('[ToolsPlugin] Reloading...')
|
|
101
|
+
this._framework = framework
|
|
102
|
+
this._registerBuiltinTools()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
uninstall(framework) {
|
|
106
|
+
// 注销内置工具
|
|
107
|
+
framework.toolRegistry.unregister('reload_plugins')
|
|
108
|
+
framework.toolRegistry.unregister('list_plugins')
|
|
109
|
+
framework.toolRegistry.unregister('list_tools')
|
|
110
|
+
this._framework = null
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
module.exports = { ToolsPlugin }
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mcp-usage
|
|
3
|
+
description: How to use MCP (Model Context Protocol) tools. Available tools, calling patterns, and best practices.
|
|
4
|
+
allowed-tools: mcp_call, mcp_list_servers, mcp_tool_schema, mcp_reload, Read, Write, Edit, Glob, Grep, execute_command
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# MCP Usage Guide
|
|
8
|
+
|
|
9
|
+
> How to use MCP tools in this environment.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. Available Tools
|
|
14
|
+
|
|
15
|
+
### mcp_list_servers
|
|
16
|
+
|
|
17
|
+
列出所有已连接的 MCP 服务器及其工具。
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
mcp_list_servers()
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
返回示例:
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"success": true,
|
|
27
|
+
"servers": [
|
|
28
|
+
{ "name": "fetch", "tools": [{ "name": "fetch", "description": "..." }] }
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### mcp_tool_schema
|
|
34
|
+
|
|
35
|
+
查询工具的完整参数结构,直接返回可复制的调用示例。
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
mcp_tool_schema({ server: "服务器名", tool: "工具名" })
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
返回示例:
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"success": true,
|
|
45
|
+
"result": {
|
|
46
|
+
"name": "fetch",
|
|
47
|
+
"description": "Fetches a URL from the internet...",
|
|
48
|
+
"required": ["url"],
|
|
49
|
+
"example": "{\"url\": \"https://example.com\"}",
|
|
50
|
+
"fullExample": "mcp_call({ server: \"fetch\", tool: \"fetch\", args_json: '{\"url\": \"https://...\"}' })"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### mcp_call
|
|
56
|
+
|
|
57
|
+
调用 MCP 服务器的工具。
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
mcp_call({
|
|
61
|
+
server: "服务器名",
|
|
62
|
+
tool: "工具名",
|
|
63
|
+
args_json: '{"参数名": "参数值"}'
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**重要**:
|
|
68
|
+
- `args_json` 必须是有效的 JSON 字符串
|
|
69
|
+
- 必填参数不能为空
|
|
70
|
+
- 如果不知道参数结构,先用 `mcp_tool_schema` 查询
|
|
71
|
+
|
|
72
|
+
### mcp_reload
|
|
73
|
+
|
|
74
|
+
重新加载 MCP 配置。当 `.agent/mcp_config.json` 修改后使用。
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
mcp_reload()
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 2. Calling Patterns
|
|
83
|
+
|
|
84
|
+
### 简单参数调用
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
// 调用 fetch 工具获取网页
|
|
88
|
+
mcp_call({
|
|
89
|
+
server: "fetch",
|
|
90
|
+
tool: "fetch",
|
|
91
|
+
args_json: '{"url": "https://news.baidu.com"}'
|
|
92
|
+
})
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 多个参数调用
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
// 调用搜索工具
|
|
99
|
+
mcp_call({
|
|
100
|
+
server: "bing-cn-mcp-server",
|
|
101
|
+
tool: "bing_search",
|
|
102
|
+
args_json: '{"query": "关键词", "count": 10}'
|
|
103
|
+
})
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 复杂参数调用
|
|
107
|
+
|
|
108
|
+
对于复杂参数(嵌套对象、数组等):
|
|
109
|
+
|
|
110
|
+
1. 先查询参数结构:
|
|
111
|
+
```
|
|
112
|
+
mcp_tool_schema({ server: "服务器", tool: "工具" })
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
2. 根据返回的 `example` 或 `fullExample` 构造调用
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 3. Error Handling
|
|
120
|
+
|
|
121
|
+
### 参数为空
|
|
122
|
+
|
|
123
|
+
如果忘记传参数,会返回错误:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"success": false,
|
|
128
|
+
"error": "参数为空!必须提供: url",
|
|
129
|
+
"hint": "正确格式: {\"url\": \"具体值\"}"
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 参数格式错误
|
|
134
|
+
|
|
135
|
+
如果 JSON 格式不正确:
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"success": false,
|
|
140
|
+
"error": "args_json 格式错误,不是有效的 JSON"
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 服务器不存在
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
{
|
|
148
|
+
"success": false,
|
|
149
|
+
"error": "MCP server 'xxx' not found"
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## 4. Configuration
|
|
156
|
+
|
|
157
|
+
MCP 服务器配置在 `.agent/mcp_config.json`:
|
|
158
|
+
|
|
159
|
+
```json
|
|
160
|
+
{
|
|
161
|
+
"mcpServers": {
|
|
162
|
+
"服务器名": {
|
|
163
|
+
"type": "sse",
|
|
164
|
+
"url": "https://...",
|
|
165
|
+
"headers": {
|
|
166
|
+
"Authorization": "Bearer xxx"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
添加或修改配置后,调用 `mcp_reload()` 重载。
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## 5. Best Practices
|
|
178
|
+
|
|
179
|
+
- [ ] 不知道参数时,先用 `mcp_tool_schema` 查询
|
|
180
|
+
- [ ] `args_json` 必须是有效的 JSON 字符串(用单引号包裹整个 JSON)
|
|
181
|
+
- [ ] 必填参数必须提供
|
|
182
|
+
- [ ] 修改配置后用 `mcp_reload()` 重载
|
|
183
|
+
- [ ] 使用前先 `mcp_list_servers` 查看可用服务器
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 6. Quick Reference
|
|
188
|
+
|
|
189
|
+
| 场景 | 操作 |
|
|
190
|
+
|------|------|
|
|
191
|
+
| 查看可用服务器 | `mcp_list_servers()` |
|
|
192
|
+
| 查询参数结构 | `mcp_tool_schema({ server: "x", tool: "y" })` |
|
|
193
|
+
| 调用工具 | `mcp_call({ server: "x", tool: "y", args_json: '{}' })` |
|
|
194
|
+
| 重载配置 | `mcp_reload()` |
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
> **Tip:** 当工具调用失败时,仔细阅读错误信息,它会告诉你缺少什么参数或格式问题。
|