flowmind 1.5.3 → 1.5.4

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/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.5.4] - 2026-07-01
6
+
7
+ ### Added
8
+ - FlowMind now resolves deferred MCP invocations from skill outputs and executes them through the registered adapter when available
9
+ - Auto-flow, YApi, Yuque, and log audit skills now return concise execution summaries instead of raw MCP payload shapes
10
+
11
+ ### Fixed
12
+ - Repeated TUI submissions are now serialized to avoid multi-input crashes during fast follow-up commands
13
+ - CLI startup now falls back to ASCII-friendly banners in managed terminal environments that can crash on full graphics rendering
14
+
15
+ ### Changed
16
+ - `resource-bind` and related learned bindings now surface clearer resource summaries for follow-up skill reuse
17
+ - Result formatting now unwraps nested execution payloads so the TUI shows the actual output instead of intermediate envelopes
18
+
5
19
  ## [1.5.2] - 2026-07-01
6
20
 
7
21
  ### Added
package/bin/flowmind.js CHANGED
@@ -75,7 +75,19 @@ async function initFlowMind(options = {}) {
75
75
  /**
76
76
  * Display banner
77
77
  */
78
- function showBanner() {
78
+ function showBanner(asciiMode = false) {
79
+ if (asciiMode) {
80
+ console.log(chalk.cyan(`
81
+ +--------------------------------------------------+
82
+ | |
83
+ | FlowMind |
84
+ | The AI Agent That Learns How You Work |
85
+ | |
86
+ +--------------------------------------------------+
87
+ `));
88
+ return;
89
+ }
90
+
79
91
  console.log(chalk.cyan(`
80
92
  ╔══════════════════════════════════════════════════╗
81
93
  ║ ║
@@ -89,7 +101,71 @@ function showBanner() {
89
101
  /**
90
102
  * Dragon Totem ASCII Art by level - Chinese Dragon (中国龙)
91
103
  */
92
- function getDragonArt(level) {
104
+ function getDragonArt(level, asciiMode = false) {
105
+ if (asciiMode) {
106
+ const asciiArts = {
107
+ 0: [
108
+ ' /-----\\ ',
109
+ ' / /-\\ \\ ',
110
+ ' | | o | | ',
111
+ ' | | | | ',
112
+ ' | \\_/ | ',
113
+ ' \\ / ',
114
+ ' \\-----/ ',
115
+ ' Dragon Egg '
116
+ ],
117
+ 1: [
118
+ ' /--\\ ',
119
+ ' /----/ \\---\\ ',
120
+ ' / o \\/ \\ ',
121
+ ' \\ /\\ /\\ / ',
122
+ ' \\/\\/ \\/\\/ \\/ ',
123
+ ' Hatchling Dragon '
124
+ ],
125
+ 2: [
126
+ ' /-\\ /-\\ ',
127
+ ' /----/ \\/ \\---\\ ',
128
+ ' / o __ \\ ',
129
+ ' \\ /--------\\ / ',
130
+ ' \\---/ ////// \\/ ',
131
+ ' \\_/ \\_/ ',
132
+ ' Juvenile Dragon '
133
+ ],
134
+ 3: [
135
+ ' /---\\ /---\\ ',
136
+ ' /---/ \\/ \\---\\ ',
137
+ '/ o __ \\ ',
138
+ '| /----------\\ | ',
139
+ ' \\--/ //////// \\-/ ',
140
+ ' \\/ ////////// \\/ ',
141
+ ' \\_/ \\_/ ',
142
+ ' Adult Dragon '
143
+ ],
144
+ 4: [
145
+ ' /---\\ /---\\ ',
146
+ '/---/ \\____/ \\---\\ ',
147
+ '| o __ | ',
148
+ '| /------------\\ | ',
149
+ ' \\-/ //////////// \\-/ ',
150
+ ' / //////////// \\ ',
151
+ ' /_/ \\_\\ ',
152
+ ' Elder Dragon '
153
+ ],
154
+ 5: [
155
+ ' * /---\\ /---\\ * ',
156
+ '/-/ \\______/ \\-\\ ',
157
+ '| o __ | ',
158
+ '| /--------------\\ | ',
159
+ ' \\-/ /////**///// \\-/ ',
160
+ ' / ///// ///// \\ ',
161
+ ' /_/ ** ** \\_\\ ',
162
+ ' * \\______________/ * ',
163
+ ' Ascended Dragon '
164
+ ]
165
+ };
166
+ return asciiArts[level] || asciiArts[0];
167
+ }
168
+
93
169
  const arts = {
94
170
  0: [
95
171
  ' ╭─────╮ ',
@@ -192,11 +268,11 @@ function getHighlightColor(level) {
192
268
  /**
193
269
  * Render dragon totem with honor data
194
270
  */
195
- function renderDragonTotem(honorData) {
271
+ function renderDragonTotem(honorData, asciiMode = false) {
196
272
  const info = getLevelInfo(honorData.points);
197
273
  const dragonColor = getDragonColor(info.level);
198
274
  const highlightColor = getHighlightColor(info.level);
199
- const art = getDragonArt(info.level);
275
+ const art = getDragonArt(info.level, asciiMode);
200
276
 
201
277
  // Calculate max art line width for proper padding
202
278
  const maxArtWidth = Math.max(...art.map(l => l.length));
@@ -210,7 +286,8 @@ function renderDragonTotem(honorData) {
210
286
 
211
287
  console.log('');
212
288
  console.log(chalk.cyan(' ┌' + border + '┐'));
213
- console.log(chalk.cyan(' │') + ' 🐉 Dragon Totem of Honor ' + padRight(' 🐉 Dragon Totem of Honor ', boxWidth - 2) + chalk.cyan('│'));
289
+ const title = asciiMode ? ' Dragon Totem of Honor ' : ' 🐉 Dragon Totem of Honor ';
290
+ console.log(chalk.cyan(' │') + title + padRight(title, boxWidth - 2) + chalk.cyan('│'));
214
291
  console.log(chalk.cyan(' ├' + border + '┤'));
215
292
 
216
293
  for (const line of art) {
@@ -366,7 +443,7 @@ program
366
443
  .description('Initialize FlowMind in current directory')
367
444
  .option('--ai <provider>', 'Initialize with AI provider (openai/anthropic/glm/mimo/qwen/ernie/deepseek/ollama)')
368
445
  .action(async (options) => {
369
- showBanner();
446
+ showBanner(options.ascii || shouldUseAsciiUi());
370
447
 
371
448
  const spinner = ora('Initializing FlowMind...').start();
372
449
 
@@ -836,7 +913,7 @@ program
836
913
  } else if (options.publish) {
837
914
  await publishHonor({ output: options.output, gist: options.gist });
838
915
  } else {
839
- renderDragonTotem(honorData);
916
+ renderDragonTotem(honorData, shouldUseAsciiUi());
840
917
  console.log(chalk.gray(` ${getNextLevelHint(honorData.points)}`));
841
918
  }
842
919
  } catch (error) {
@@ -959,7 +1036,7 @@ program
959
1036
 
960
1037
  // Interactive mode
961
1038
  async function runInteractiveMode(fm) {
962
- showBanner();
1039
+ showBanner(shouldUseAsciiUi());
963
1040
  console.log(chalk.cyan('Interactive mode started. Type "exit" to quit.\n'));
964
1041
 
965
1042
  try {
@@ -66,15 +66,10 @@ class McpAdapter extends BaseAdapter {
66
66
  return this.config.transport || this.config.mcpServerConfig || this.config.mcpTransport || {};
67
67
  }
68
68
 
69
- async callMcpTool(localName, args = {}) {
70
- const tool = this.resolveTool(localName);
71
- if (!tool) {
72
- throw new Error(`Unknown MCP tool mapping: ${localName}`);
73
- }
74
-
69
+ async callTool(tool, args = {}) {
75
70
  const transport = this.getTransportConfig();
76
71
  const serverName = this.mcpServer || this.providerName;
77
- const response = await callMcpTool({
72
+ return callMcpTool({
78
73
  url: transport.url || transport.endpoint || transport.baseUrl,
79
74
  headers: transport.headers || {},
80
75
  tool,
@@ -82,8 +77,14 @@ class McpAdapter extends BaseAdapter {
82
77
  timeoutMs: transport.timeoutMs || 60000,
83
78
  serverName
84
79
  });
80
+ }
85
81
 
86
- return response;
82
+ async callMcpTool(localName, args = {}) {
83
+ const tool = this.resolveTool(localName);
84
+ if (!tool) {
85
+ throw new Error(`Unknown MCP tool mapping: ${localName}`);
86
+ }
87
+ return this.callTool(tool, args);
87
88
  }
88
89
  }
89
90
 
@@ -82,7 +82,7 @@ class MiMoProvider extends BaseModel {
82
82
  ...super.getInfo(),
83
83
  model: this.model,
84
84
  baseUrl: this.baseUrl,
85
- provider: 'Xiaomi'
85
+ provider: 'MiMo'
86
86
  };
87
87
  }
88
88
  }
package/core/index.js CHANGED
@@ -217,6 +217,7 @@ class FlowMind {
217
217
 
218
218
  // Execute skill
219
219
  const result = await skill.execute(input, enhancedContext);
220
+ const resolvedResult = await this.resolveDeferredMcpResult(result, skill, enhancedContext);
220
221
 
221
222
  if (resourceBinding?.id) {
222
223
  await this.learning.markResourceBindingUsed(resourceBinding.id, {
@@ -239,7 +240,144 @@ class FlowMind {
239
240
  // Award honor point for skill use
240
241
  await this.honor.award('skill_use', `Used skill: ${skill.name}`);
241
242
 
242
- return result;
243
+ return resolvedResult;
244
+ }
245
+
246
+ async resolveDeferredMcpResult(result, skill, context = {}) {
247
+ const invocation = this.extractMcpInvocation(result);
248
+ if (!invocation) {
249
+ return result;
250
+ }
251
+
252
+ const adapter = this.resolveDeferredAdapter(invocation, skill, context);
253
+ if (!adapter) {
254
+ return result;
255
+ }
256
+
257
+ const executor = typeof adapter.callTool === 'function'
258
+ ? adapter.callTool.bind(adapter)
259
+ : typeof adapter.callMcpTool === 'function'
260
+ ? adapter.callMcpTool.bind(adapter)
261
+ : null;
262
+
263
+ if (!executor) {
264
+ return result;
265
+ }
266
+
267
+ try {
268
+ const execution = await executor(invocation.tool, invocation.args || {});
269
+ const resultData = result && typeof result === 'object' && !Array.isArray(result) && result.data && typeof result.data === 'object'
270
+ ? result.data
271
+ : {};
272
+
273
+ return {
274
+ ...result,
275
+ data: {
276
+ ...resultData,
277
+ execution,
278
+ mcpTool: invocation.tool,
279
+ mcpExecuted: true,
280
+ mcpServer: invocation.mcpServer || adapter.mcpServer || adapter.providerName
281
+ }
282
+ };
283
+ } catch (error) {
284
+ return {
285
+ ...result,
286
+ type: result?.type || 'error',
287
+ success: false,
288
+ message: result?.message || error.message,
289
+ data: {
290
+ ...(result && typeof result === 'object' && result.data && typeof result.data === 'object' ? result.data : {}),
291
+ mcpTool: invocation.tool,
292
+ mcpExecuted: false,
293
+ mcpError: error.message
294
+ }
295
+ };
296
+ }
297
+ }
298
+
299
+ extractMcpInvocation(result) {
300
+ if (!result || typeof result !== 'object') {
301
+ return null;
302
+ }
303
+
304
+ const candidates = [
305
+ result.data,
306
+ result
307
+ ];
308
+
309
+ for (const candidate of candidates) {
310
+ if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) {
311
+ continue;
312
+ }
313
+
314
+ const tool = candidate.mcpTool || candidate.tool;
315
+ if (!tool || typeof tool !== 'string') {
316
+ continue;
317
+ }
318
+
319
+ const args = candidate.args || candidate.params || {};
320
+ if (args && typeof args !== 'object') {
321
+ continue;
322
+ }
323
+
324
+ return {
325
+ tool,
326
+ args,
327
+ mcpServer: candidate.mcpServer || null
328
+ };
329
+ }
330
+
331
+ return null;
332
+ }
333
+
334
+ resolveDeferredAdapter(invocation, skill, context = {}) {
335
+ const registry = context.componentRegistry || this.components;
336
+ if (!registry) {
337
+ return null;
338
+ }
339
+
340
+ const bindingComponentType = context.resourceBinding?.componentType || context.resolvedBinding?.componentType || null;
341
+ const skillComponentType = this.inferSkillComponentType(skill, context);
342
+ const componentTypes = [
343
+ bindingComponentType,
344
+ skillComponentType,
345
+ invocation.componentType
346
+ ].filter(Boolean);
347
+
348
+ for (const componentType of componentTypes) {
349
+ const adapter = registry.getAdapter(componentType);
350
+ if (adapter) {
351
+ return adapter;
352
+ }
353
+ }
354
+
355
+ if (typeof registry.getAll === 'function') {
356
+ const allAdapters = registry.getAll();
357
+ for (const entry of allAdapters) {
358
+ const adapter = registry.getAdapterByProvider?.(entry.type, entry.provider) || null;
359
+ if (adapter && (adapter.mcpServer === invocation.mcpServer || adapter.providerName === invocation.provider)) {
360
+ return adapter;
361
+ }
362
+ }
363
+ }
364
+
365
+ return null;
366
+ }
367
+
368
+ inferSkillComponentType(skill, context = {}) {
369
+ const name = skill?.name || context.currentSkill || '';
370
+ const mapping = {
371
+ 'log-audit': 'logService',
372
+ 'sls-log-audit': 'logService',
373
+ 'yapi-sync-interface': 'apiDoc',
374
+ 'yuque-sync-design': 'knowledgeBase',
375
+ 'data-logic-validation': 'databaseQuery',
376
+ 'resource-bind': null,
377
+ 'auto-flow': 'workflow'
378
+ };
379
+
380
+ return mapping[name] || null;
243
381
  }
244
382
 
245
383
  /**
@@ -27,43 +27,23 @@ class AliyunDmsAdapter extends DatabaseManagerAdapter {
27
27
  }
28
28
 
29
29
  async listInstances(params) {
30
- return {
31
- mcpServer: this.mcpServer,
32
- tool: this.resolveTool('listInstances'),
33
- params: params || {}
34
- };
30
+ return this.callMcpTool('listInstances', params || {});
35
31
  }
36
32
 
37
33
  async executeScript(params) {
38
- return {
39
- mcpServer: this.mcpServer,
40
- tool: this.resolveTool('executeScript'),
41
- params
42
- };
34
+ return this.callMcpTool('executeScript', params);
43
35
  }
44
36
 
45
37
  async searchDatabase(searchKey) {
46
- return {
47
- mcpServer: this.mcpServer,
48
- tool: this.resolveTool('searchDatabase'),
49
- params: { search_key: searchKey }
50
- };
38
+ return this.callMcpTool('searchDatabase', { search_key: searchKey });
51
39
  }
52
40
 
53
41
  async listTables(databaseId) {
54
- return {
55
- mcpServer: this.mcpServer,
56
- tool: this.resolveTool('listTables'),
57
- params: { database_id: databaseId }
58
- };
42
+ return this.callMcpTool('listTables', { database_id: databaseId });
59
43
  }
60
44
 
61
45
  async getTableDetail(tableGuid) {
62
- return {
63
- mcpServer: this.mcpServer,
64
- tool: this.resolveTool('getTableDetailInfo'),
65
- params: { table_guid: tableGuid }
66
- };
46
+ return this.callMcpTool('getTableDetailInfo', { table_guid: tableGuid });
67
47
  }
68
48
 
69
49
  /**
@@ -73,11 +53,7 @@ class AliyunDmsAdapter extends DatabaseManagerAdapter {
73
53
  * @returns {Promise<object>}
74
54
  */
75
55
  async generateSql(databaseId, question) {
76
- return {
77
- mcpServer: this.mcpServer,
78
- tool: this.resolveTool('generateSql'),
79
- params: { database_id: databaseId, question }
80
- };
56
+ return this.callMcpTool('generateSql', { database_id: databaseId, question });
81
57
  }
82
58
 
83
59
  /**
@@ -87,11 +63,7 @@ class AliyunDmsAdapter extends DatabaseManagerAdapter {
87
63
  * @returns {Promise<object>}
88
64
  */
89
65
  async optimizeSql(databaseId, sql) {
90
- return {
91
- mcpServer: this.mcpServer,
92
- tool: this.resolveTool('optimizeSql'),
93
- params: { database_id: databaseId, sql }
94
- };
66
+ return this.callMcpTool('optimizeSql', { database_id: databaseId, sql });
95
67
  }
96
68
  }
97
69
 
@@ -34,11 +34,7 @@ class AliyunRedisAdapter extends McpAdapter {
34
34
  * @returns {Promise<object>}
35
35
  */
36
36
  async query(query, time) {
37
- return {
38
- mcpServer: this.mcpServer,
39
- tool: this.resolveTool('query'),
40
- params: { query, time }
41
- };
37
+ return this.callMcpTool('query', { query, time });
42
38
  }
43
39
 
44
40
  /**
@@ -50,11 +46,7 @@ class AliyunRedisAdapter extends McpAdapter {
50
46
  * @returns {Promise<object>}
51
47
  */
52
48
  async queryRange(query, start, end, step) {
53
- return {
54
- mcpServer: this.mcpServer,
55
- tool: this.resolveTool('queryRange'),
56
- params: { query, start, end, step }
57
- };
49
+ return this.callMcpTool('queryRange', { query, start, end, step });
58
50
  }
59
51
 
60
52
  /**
@@ -63,11 +55,7 @@ class AliyunRedisAdapter extends McpAdapter {
63
55
  * @returns {Promise<object>}
64
56
  */
65
57
  async getLabelNames(params) {
66
- return {
67
- mcpServer: this.mcpServer,
68
- tool: this.resolveTool('getLabelNames'),
69
- params: params || {}
70
- };
58
+ return this.callMcpTool('getLabelNames', params || {});
71
59
  }
72
60
 
73
61
  /**
@@ -77,11 +65,7 @@ class AliyunRedisAdapter extends McpAdapter {
77
65
  * @returns {Promise<object>}
78
66
  */
79
67
  async getLabelValues(name, params) {
80
- return {
81
- mcpServer: this.mcpServer,
82
- tool: this.resolveTool('getLabelValues'),
83
- params: { name, ...(params || {}) }
84
- };
68
+ return this.callMcpTool('getLabelValues', { name, ...(params || {}) });
85
69
  }
86
70
  }
87
71
 
@@ -11,6 +11,7 @@ class AliyunSlsAdapter extends LogServiceAdapter {
11
11
 
12
12
  // Register MCP tool mappings
13
13
  this.registerTool('queryLogs', 'queryLogs');
14
+ this.registerTool('listProjects', 'listProject');
14
15
  this.registerTool('listProject', 'listProject');
15
16
  }
16
17
 
@@ -46,19 +47,11 @@ class AliyunSlsAdapter extends LogServiceAdapter {
46
47
  }
47
48
 
48
49
  async queryLogs(params) {
49
- return {
50
- mcpServer: this.mcpServer,
51
- tool: this.resolveTool('queryLogs'),
52
- params
53
- };
50
+ return this.callMcpTool('queryLogs', params || {});
54
51
  }
55
52
 
56
53
  async listProjects() {
57
- return {
58
- mcpServer: this.mcpServer,
59
- tool: this.resolveTool('listProject'),
60
- params: {}
61
- };
54
+ return this.callMcpTool('listProjects', {});
62
55
  }
63
56
 
64
57
  /**
@@ -40,43 +40,23 @@ class FridayReportAdapter extends ReportAdapter {
40
40
  }
41
41
 
42
42
  async listBuilds(params) {
43
- return {
44
- mcpServer: this.mcpServer,
45
- tool: this.resolveTool('listBuilds'),
46
- params: params || {}
47
- };
43
+ return this.callMcpTool('listBuilds', params || {});
48
44
  }
49
45
 
50
46
  async getBuildInfo(buildId) {
51
- return {
52
- mcpServer: this.mcpServer,
53
- tool: this.resolveTool('getBuildInfo'),
54
- params: { id: buildId }
55
- };
47
+ return this.callMcpTool('getBuildInfo', { id: buildId });
56
48
  }
57
49
 
58
50
  async listJacocoReports(params) {
59
- return {
60
- mcpServer: this.mcpServer,
61
- tool: this.resolveTool('listJacoco'),
62
- params: params || {}
63
- };
51
+ return this.callMcpTool('listJacoco', params || {});
64
52
  }
65
53
 
66
54
  async listUnitReports(params) {
67
- return {
68
- mcpServer: this.mcpServer,
69
- tool: this.resolveTool('listJacocoUnit'),
70
- params: params || {}
71
- };
55
+ return this.callMcpTool('listJacocoUnit', params || {});
72
56
  }
73
57
 
74
58
  async getJobDetails(jobName) {
75
- return {
76
- mcpServer: this.mcpServer,
77
- tool: this.resolveTool('getJobDetails'),
78
- params: { jobName }
79
- };
59
+ return this.callMcpTool('getJobDetails', { jobName });
80
60
  }
81
61
  }
82
62
 
@@ -28,51 +28,27 @@ class YapiAdapter extends ApiDocAdapter {
28
28
  }
29
29
 
30
30
  async searchApis(params) {
31
- return {
32
- mcpServer: this.mcpServer,
33
- tool: this.resolveTool('searchApis'),
34
- params
35
- };
31
+ return this.callMcpTool('searchApis', params);
36
32
  }
37
33
 
38
34
  async getCategories(projectId) {
39
- return {
40
- mcpServer: this.mcpServer,
41
- tool: this.resolveTool('getCategories'),
42
- params: { projectId }
43
- };
35
+ return this.callMcpTool('getCategories', { projectId });
44
36
  }
45
37
 
46
38
  async saveApi(apiData) {
47
- return {
48
- mcpServer: this.mcpServer,
49
- tool: this.resolveTool('saveApi'),
50
- params: apiData
51
- };
39
+ return this.callMcpTool('saveApi', apiData);
52
40
  }
53
41
 
54
42
  async importSwagger(projectId, catId, swaggerData) {
55
- return {
56
- mcpServer: this.mcpServer,
57
- tool: this.resolveTool('importSwagger'),
58
- params: { projectId, catId, swaggerData }
59
- };
43
+ return this.callMcpTool('importSwagger', { projectId, catId, swaggerData });
60
44
  }
61
45
 
62
46
  async exportProject(projectId, type = 'swagger') {
63
- return {
64
- mcpServer: this.mcpServer,
65
- tool: this.resolveTool('exportProject'),
66
- params: { projectId, type }
67
- };
47
+ return this.callMcpTool('exportProject', { projectId, type });
68
48
  }
69
49
 
70
50
  async listProjects() {
71
- return {
72
- mcpServer: this.mcpServer,
73
- tool: this.resolveTool('listProjects'),
74
- params: {}
75
- };
51
+ return this.callMcpTool('listProjects', {});
76
52
  }
77
53
  }
78
54
 
@@ -27,51 +27,27 @@ class YuqueAdapter extends KnowledgeBaseAdapter {
27
27
  }
28
28
 
29
29
  async getRepos(params) {
30
- return {
31
- mcpServer: this.mcpServer,
32
- tool: this.resolveTool('getRepos'),
33
- params
34
- };
30
+ return this.callMcpTool('getRepos', params);
35
31
  }
36
32
 
37
33
  async getDocs(namespace, params = {}) {
38
- return {
39
- mcpServer: this.mcpServer,
40
- tool: this.resolveTool('getDocs'),
41
- params: { namespace, ...params }
42
- };
34
+ return this.callMcpTool('getDocs', { namespace, ...params });
43
35
  }
44
36
 
45
37
  async getDoc(namespace, slug) {
46
- return {
47
- mcpServer: this.mcpServer,
48
- tool: this.resolveTool('getDoc'),
49
- params: { namespace, slug }
50
- };
38
+ return this.callMcpTool('getDoc', { namespace, slug });
51
39
  }
52
40
 
53
41
  async createDoc(namespace, docData) {
54
- return {
55
- mcpServer: this.mcpServer,
56
- tool: this.resolveTool('createDoc'),
57
- params: { namespace, ...docData }
58
- };
42
+ return this.callMcpTool('createDoc', { namespace, ...docData });
59
43
  }
60
44
 
61
45
  async updateDoc(namespace, slug, docData) {
62
- return {
63
- mcpServer: this.mcpServer,
64
- tool: this.resolveTool('updateDoc'),
65
- params: { namespace, slug, ...docData }
66
- };
46
+ return this.callMcpTool('updateDoc', { namespace, slug, ...docData });
67
47
  }
68
48
 
69
49
  async search(query, type = 'doc') {
70
- return {
71
- mcpServer: this.mcpServer,
72
- tool: this.resolveTool('search'),
73
- params: { q: query, type }
74
- };
50
+ return this.callMcpTool('search', { q: query, type });
75
51
  }
76
52
 
77
53
  /**
@@ -79,11 +55,7 @@ class YuqueAdapter extends KnowledgeBaseAdapter {
79
55
  * @returns {Promise<object>}
80
56
  */
81
57
  async getCurrentUser() {
82
- return {
83
- mcpServer: this.mcpServer,
84
- tool: this.resolveTool('getCurrentUser'),
85
- params: {}
86
- };
58
+ return this.callMcpTool('getCurrentUser', {});
87
59
  }
88
60
  }
89
61