@xalia/agent 0.5.7 → 0.5.8

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.
Files changed (35) hide show
  1. package/dist/agent/src/agent/agent.js +3 -0
  2. package/dist/agent/src/agent/agentUtils.js +6 -12
  3. package/dist/agent/src/agent/mcpServerManager.js +1 -1
  4. package/dist/agent/src/agent/openAILLMStreaming.js +14 -7
  5. package/dist/agent/src/agent/sudoMcpServerManager.js +13 -13
  6. package/dist/agent/src/chat/client.js +24 -63
  7. package/dist/agent/src/chat/conversationManager.js +122 -12
  8. package/dist/agent/src/chat/db.js +9 -0
  9. package/dist/agent/src/chat/messages.js +27 -0
  10. package/dist/agent/src/chat/websocket.js +14 -0
  11. package/dist/agent/src/test/db.test.js +16 -0
  12. package/dist/agent/src/test/mcpServerManager.test.js +2 -2
  13. package/dist/agent/src/test/openaiStreaming.test.js +56 -28
  14. package/dist/agent/src/test/sudoMcpServerManager.test.js +10 -13
  15. package/dist/agent/src/tool/chatMain.js +7 -1
  16. package/dist/agent/src/tool/commandPrompt.js +9 -10
  17. package/package.json +1 -1
  18. package/src/agent/agent.ts +14 -4
  19. package/src/agent/agentUtils.ts +17 -23
  20. package/src/agent/mcpServerManager.ts +3 -1
  21. package/src/agent/openAILLMStreaming.ts +14 -7
  22. package/src/agent/sudoMcpServerManager.ts +17 -18
  23. package/src/chat/client.ts +35 -45
  24. package/src/chat/conversationManager.ts +147 -12
  25. package/src/chat/db.ts +14 -0
  26. package/src/chat/messages.ts +31 -0
  27. package/src/chat/websocket.ts +14 -0
  28. package/src/test/db.test.ts +22 -1
  29. package/src/test/mcpServerManager.test.ts +2 -2
  30. package/src/test/openaiStreaming.test.ts +64 -30
  31. package/src/test/sudoMcpServerManager.test.ts +11 -16
  32. package/src/tool/chatMain.ts +11 -2
  33. package/src/tool/commandPrompt.ts +8 -15
  34. package/dist/agent/src/chat/frontendClient.js +0 -74
  35. package/src/chat/frontendClient.ts +0 -123
@@ -67,6 +67,53 @@ const TEST_TRAILING_USAGE = [
67
67
  },
68
68
  },
69
69
  ];
70
+ const AGGREGATED_MESSAGE = {
71
+ id: "gen-1753923406-nsIKHyFRoJqkUntBnQTw",
72
+ choices: [
73
+ {
74
+ message: {
75
+ content: "test",
76
+ role: "assistant",
77
+ refusal: null,
78
+ tool_calls: undefined,
79
+ },
80
+ finish_reason: "stop",
81
+ index: 0,
82
+ logprobs: null,
83
+ },
84
+ ],
85
+ created: 1753923406,
86
+ model: "openai/gpt-4o",
87
+ object: "chat.completion",
88
+ service_tier: undefined,
89
+ system_fingerprint: "fp_a288987b44",
90
+ usage: {
91
+ completion_tokens: 50,
92
+ prompt_tokens: 271,
93
+ total_tokens: 321,
94
+ completion_tokens_details: { reasoning_tokens: 0 },
95
+ prompt_tokens_details: { cached_tokens: 0 },
96
+ },
97
+ };
98
+ const TEST_TRAILING_USAGE_WITH_3_CHUNKS = [
99
+ {
100
+ ...TEST_TRAILING_USAGE[0],
101
+ choices: [
102
+ {
103
+ delta: { content: "test", role: "assistant" },
104
+ finish_reason: null,
105
+ index: 0,
106
+ logprobs: null,
107
+ },
108
+ ],
109
+ },
110
+ {
111
+ ...TEST_TRAILING_USAGE[1],
112
+ choices: [{ ...TEST_TRAILING_USAGE[1].choices[0], finish_reason: "stop" }],
113
+ usage: undefined,
114
+ },
115
+ { ...TEST_TRAILING_USAGE[1], choices: [] },
116
+ ];
70
117
  describe("OpenAI Streaming", () => {
71
118
  it("should support standard termination", async function () {
72
119
  const chunks = TEST_STANDARD;
@@ -101,33 +148,14 @@ describe("OpenAI Streaming", () => {
101
148
  (0, chai_1.expect)(chunks.length).eql(2);
102
149
  const { initMessage } = (0, openAILLMStreaming_1.initializeCompletion)(chunks[0]);
103
150
  (0, openAILLMStreaming_1.updateCompletion)(initMessage, chunks[1]);
104
- (0, chai_1.expect)(initMessage).eql({
105
- id: "gen-1753923406-nsIKHyFRoJqkUntBnQTw",
106
- choices: [
107
- {
108
- message: {
109
- content: "test",
110
- role: "assistant",
111
- refusal: null,
112
- tool_calls: undefined,
113
- },
114
- finish_reason: "stop",
115
- index: 0,
116
- logprobs: null,
117
- },
118
- ],
119
- created: 1753923406,
120
- model: "openai/gpt-4o",
121
- object: "chat.completion",
122
- service_tier: undefined,
123
- system_fingerprint: "fp_a288987b44",
124
- usage: {
125
- completion_tokens: 50,
126
- prompt_tokens: 271,
127
- total_tokens: 321,
128
- completion_tokens_details: { reasoning_tokens: 0 },
129
- prompt_tokens_details: { cached_tokens: 0 },
130
- },
131
- });
151
+ (0, chai_1.expect)(initMessage).eql(AGGREGATED_MESSAGE);
152
+ });
153
+ it("should support trailing usage with 3 chunks", async function () {
154
+ const chunks = TEST_TRAILING_USAGE_WITH_3_CHUNKS;
155
+ (0, chai_1.expect)(chunks.length).eql(3);
156
+ const { initMessage } = (0, openAILLMStreaming_1.initializeCompletion)(chunks[0]);
157
+ (0, openAILLMStreaming_1.updateCompletion)(initMessage, chunks[1]);
158
+ (0, openAILLMStreaming_1.updateCompletion)(initMessage, chunks[2]);
159
+ (0, chai_1.expect)(initMessage).eql(AGGREGATED_MESSAGE);
132
160
  });
133
161
  });
@@ -6,38 +6,35 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.prettyPrintTool = prettyPrintTool;
7
7
  const chai_1 = require("chai");
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
- const mcpServerManager_1 = require("../agent/mcpServerManager");
10
9
  const sudoMcpServerManager_1 = require("../agent/sudoMcpServerManager");
11
- let managers = undefined;
10
+ let manager = undefined;
12
11
  async function getServerManagers() {
13
- if (!managers) {
14
- const tm = new mcpServerManager_1.McpServerManager();
15
- const sm = await sudoMcpServerManager_1.SkillManager.initialize(tm, (_url) => {
12
+ if (!manager) {
13
+ manager = await sudoMcpServerManager_1.SkillManager.initialize((_url) => {
16
14
  throw "unexpected call to openUrl";
17
15
  }, sudoMcpServerManager_1.LOCAL_SERVER_URL, "dummy_key");
18
- managers = [tm, sm];
19
16
  }
20
- return managers;
17
+ return manager;
21
18
  }
22
19
  async function shutdownAll() {
23
- if (managers) {
24
- await managers[0].shutdown();
20
+ if (manager) {
21
+ await manager.shutdown();
25
22
  }
26
- managers = undefined;
23
+ manager = undefined;
27
24
  }
28
25
  describe("SudoMcpServerManager", async () => {
29
26
  it("should fetch servers from deployed backend", async () => {
30
- const [, sm] = await getServerManagers();
27
+ const sm = await getServerManagers();
31
28
  const serverBriefs = sm.getServerBriefs();
32
29
  (0, chai_1.expect)(serverBriefs.length).greaterThan(0);
33
30
  }).timeout(10000);
34
31
  it("should fetch tools for a server", async () => {
35
- const [, sm] = await getServerManagers();
32
+ const sm = await getServerManagers();
36
33
  const tools = await sm.getServerTools("sudomcp_simplecalc");
37
34
  (0, chai_1.expect)(tools.length).greaterThan(0);
38
35
  }).timeout(10000);
39
36
  it("should add a new MCP server", async () => {
40
- const [, sm] = await getServerManagers();
37
+ const sm = await getServerManagers();
41
38
  await sm.addMcpServer("sudomcp_simplecalc", true);
42
39
  const serverBriefs = sm.getServerBriefs();
43
40
  (0, chai_1.expect)(serverBriefs.some((brief) => brief.name === "sudomcp_simplecalc")).eql(true);
@@ -42,6 +42,7 @@ const tool_1 = require("@xalia/xmcp/tool");
42
42
  const sdk_1 = require("@xalia/xmcp/sdk");
43
43
  const client_1 = require("../chat/client");
44
44
  const server_1 = require("../chat/server");
45
+ const messages_1 = require("../chat/messages");
45
46
  const prompt_1 = require("./prompt");
46
47
  const options = __importStar(require("./options"));
47
48
  const commandPrompt_1 = require("./commandPrompt");
@@ -162,7 +163,12 @@ function getCLIOnMessage() {
162
163
  process_1.stdout.write(`[${msg.from}]: ${msg.message}\n`);
163
164
  break;
164
165
  case "agent_msg":
165
- process_1.stdout.write(`[AGENT]: ${msg.message}\n`);
166
+ {
167
+ const text = (0, messages_1.decodeAssistantMessageParam)(msg.message);
168
+ if (text) {
169
+ process_1.stdout.write(`[AGENT]: ${text}\n`);
170
+ }
171
+ }
166
172
  break;
167
173
  case "agent_msg_chunk":
168
174
  if (startMsg) {
@@ -84,17 +84,17 @@ class CommandPrompt {
84
84
  break;
85
85
  }
86
86
  try {
87
- await this.runCommand(agent, sudoMcpServerManager.getMcpServerManager(), sudoMcpServerManager, cmds);
87
+ await this.runCommand(agent, sudoMcpServerManager, cmds);
88
88
  }
89
89
  catch (e) {
90
90
  console.log(`ERROR: ${e}`);
91
91
  }
92
92
  }
93
93
  }
94
- async runCommand(agent, mcpServerManager, sudoMcpServerManager, cmds) {
94
+ async runCommand(agent, sudoMcpServerManager, cmds) {
95
95
  switch (cmds[0]) {
96
96
  case "lt":
97
- this.listTools(mcpServerManager);
97
+ this.listTools(sudoMcpServerManager);
98
98
  break;
99
99
  case "ls":
100
100
  this.listServers(sudoMcpServerManager);
@@ -103,22 +103,22 @@ class CommandPrompt {
103
103
  await this.addServer(sudoMcpServerManager, cmds[1]);
104
104
  break;
105
105
  case "rs":
106
- await mcpServerManager.removeMcpServer(cmds[1]);
106
+ await sudoMcpServerManager.removeMcpServer(cmds[1]);
107
107
  break;
108
108
  case "e":
109
- mcpServerManager.enableTool(cmds[1], cmds[2]);
109
+ sudoMcpServerManager.enableTool(cmds[1], cmds[2]);
110
110
  console.log(`Enabled tool ${cmds[2]} for server ${cmds[1]}`);
111
111
  break;
112
112
  case "d":
113
- mcpServerManager.disableTool(cmds[1], cmds[2]);
113
+ sudoMcpServerManager.disableTool(cmds[1], cmds[2]);
114
114
  console.log(`Disabled tool ${cmds[2]} for server ${cmds[1]}`);
115
115
  break;
116
116
  case "ea":
117
- mcpServerManager.enableAllTools(cmds[1]);
117
+ sudoMcpServerManager.enableAllTools(cmds[1]);
118
118
  console.log(`Enabled all tools for server ${cmds[1]}`);
119
119
  break;
120
120
  case "da":
121
- mcpServerManager.disableAllTools(cmds[1]);
121
+ sudoMcpServerManager.disableAllTools(cmds[1]);
122
122
  console.log(`Disabled all tools for server ${cmds[1]}`);
123
123
  break;
124
124
  case "wc":
@@ -189,10 +189,9 @@ Have you installed server ${serverName} using the SudoMCP CLI tool?`;
189
189
  throw e;
190
190
  }
191
191
  }
192
- const msm = sudoMcpServerManager.getMcpServerManager();
193
192
  console.log(`Added server: ${serverName} (enabled all tools).`);
194
193
  console.log(`Current tool list:`);
195
- this.listTools(msm);
194
+ this.listTools(sudoMcpServerManager);
196
195
  }
197
196
  writeConversation(agent, fileName) {
198
197
  const conversation = agent.getConversation();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xalia/agent",
3
- "version": "0.5.7",
3
+ "version": "0.5.8",
4
4
  "keywords": [],
5
5
  "author": "",
6
6
  "license": "ISC",
@@ -1,10 +1,7 @@
1
1
  import * as dotenv from "dotenv";
2
2
  import { OpenAI } from "openai";
3
3
  import { McpServerManager } from "./mcpServerManager";
4
- import {
5
- ChatCompletionContentPart,
6
- ChatCompletionUserMessageParam,
7
- } from "openai/resources.mjs";
4
+ import { ChatCompletionContentPart } from "openai/resources.mjs";
8
5
  import { strict as assert } from "assert";
9
6
  import { ILLM } from "./llm";
10
7
  import { AgentProfile, getLogger } from "@xalia/xmcp/sdk";
@@ -19,6 +16,12 @@ export type ChatCompletionMessageParam = OpenAI.ChatCompletionMessageParam;
19
16
  export type ChatCompletionMessageToolCall =
20
17
  OpenAI.ChatCompletionMessageToolCall;
21
18
 
19
+ export type ChatCompletionAssistantMessageParam =
20
+ OpenAI.ChatCompletionAssistantMessageParam;
21
+
22
+ export type ChatCompletionUserMessageParam =
23
+ OpenAI.ChatCompletionUserMessageParam;
24
+
22
25
  // Role: If content, give it to UI
23
26
  export type OnMessageCB = {
24
27
  (msg: string, msgEnd: boolean): Promise<void>;
@@ -41,6 +44,8 @@ export interface IConversation {
41
44
  setSystemPrompt(systemPrompt: string): void;
42
45
  getModel(): string;
43
46
  setModel(model: string): void;
47
+
48
+ shutdown(): Promise<void>;
44
49
  }
45
50
 
46
51
  dotenv.config();
@@ -132,7 +137,12 @@ export class Agent implements IConversation {
132
137
  if (!userMessage) {
133
138
  return undefined;
134
139
  }
140
+ return this.userMessageRaw(userMessage);
141
+ }
135
142
 
143
+ public async userMessageRaw(
144
+ userMessage: ChatCompletionUserMessageParam
145
+ ): Promise<ChatCompletionMessageParam | undefined> {
136
146
  this.messages.push(userMessage);
137
147
  let completion = await this.chatCompletion();
138
148
 
@@ -34,7 +34,7 @@ async function createAgent(
34
34
  platform: IPlatform,
35
35
  openaiApiKey: string | undefined,
36
36
  stream: boolean = false,
37
- mcpServerManager?: McpServerManager
37
+ mcpServerManager: McpServerManager
38
38
  ): Promise<Agent> {
39
39
  let llm: ILLM | undefined;
40
40
 
@@ -90,26 +90,9 @@ export async function createAgentWithSkills(
90
90
  conversation: OpenAI.ChatCompletionMessageParam[] | undefined,
91
91
  stream: boolean = false
92
92
  ): Promise<[Agent, SkillManager]> {
93
- // Create agent
94
- logger.debug("[createAgentAndSudoMcpServerManager] creating agent ...");
95
- const agent = await createAgent(
96
- llmUrl,
97
- agentProfile.model,
98
- agentProfile.system_prompt,
99
- onMessage,
100
- onToolCall,
101
- platform,
102
- llmApiKey,
103
- stream
104
- );
105
- if (conversation) {
106
- agent.setConversation(conversation);
107
- }
108
-
109
93
  // Init SudoMcpServerManager
110
94
  logger.debug("[createAgentWithSkills] creating SudoMcpServerManager.");
111
95
  const sudoMcpServerManager = await SkillManager.initialize(
112
- agent.getMcpServerManager(),
113
96
  platform.openUrl,
114
97
  sudomcpConfig.backend_url,
115
98
  sudomcpConfig.api_key,
@@ -121,7 +104,19 @@ export async function createAgentWithSkills(
121
104
  );
122
105
  await sudoMcpServerManager.restoreMcpSettings(agentProfile.mcp_settings);
123
106
 
124
- logger.debug("[createAgentWithSkills] done");
107
+ // Create agent using the McpServerManager just created
108
+ const agent = await createAgentFromSkillManager(
109
+ llmUrl,
110
+ agentProfile,
111
+ onMessage,
112
+ onToolCall,
113
+ platform,
114
+ llmApiKey,
115
+ sudoMcpServerManager,
116
+ conversation,
117
+ stream
118
+ );
119
+
125
120
  return [agent, sudoMcpServerManager];
126
121
  }
127
122
 
@@ -137,8 +132,7 @@ export async function createAgentFromSkillManager(
137
132
  stream: boolean = false
138
133
  ): Promise<Agent> {
139
134
  // Create agent
140
- logger.debug("[createAgentAndSudoMcpServerManager] creating agent ...");
141
- const mcpServerManager = skillManager.getMcpServerManager();
135
+ logger.debug("[createAgentFromSkillManager] creating agent ...");
142
136
  const agent = await createAgent(
143
137
  llmUrl,
144
138
  agentProfile.model,
@@ -148,13 +142,13 @@ export async function createAgentFromSkillManager(
148
142
  platform,
149
143
  llmApiKey,
150
144
  stream,
151
- mcpServerManager
145
+ skillManager
152
146
  );
153
147
  if (conversation) {
154
148
  agent.setConversation(conversation);
155
149
  }
156
150
 
157
- logger.debug("[createAgentWithSkills] done");
151
+ logger.debug("[createAgentFromSkillManager] done");
158
152
  return agent;
159
153
  }
160
154
 
@@ -151,6 +151,8 @@ export interface IMcpServerManager {
151
151
  disableAllTools(mcpServerName: string): void;
152
152
  enableTool(mcpServerName: string, toolName: string): void;
153
153
  disableTool(mcpServerName: string, toolName: string): void;
154
+
155
+ shutdown(): Promise<void>;
154
156
  }
155
157
 
156
158
  /**
@@ -186,7 +188,7 @@ export class McpServerManager implements IMcpServerManager {
186
188
  return this.getMcpServerInternal(mcpServerName);
187
189
  }
188
190
 
189
- public async addMcpServer(
191
+ public async addMcpServerWithSSEUrl(
190
192
  mcpServerName: string,
191
193
  url: string,
192
194
  apiKey?: string,
@@ -316,9 +316,10 @@ function initializeCompletionChoices(
316
316
  chunkChoices: OpenAI.Chat.Completions.ChatCompletionChunk.Choice[]
317
317
  ): { choices: OpenAI.Chat.Completions.ChatCompletion.Choice[]; done: boolean } {
318
318
  // Technically, one choice could be done and the other still have some
319
- // content to stream. We keep it simple for now and assume only single
320
- // choices, which allows us to mark everything as done if any choice we hit is
321
- // done.
319
+ // content to stream. We keep it simple for now and allow zero or one
320
+ // choice per chunk, which allows us to mark everything as done if any
321
+ // choice we hit is done. Zero choices can occur in usage-only chunks at
322
+ // the end of the stream.
322
323
  assert(chunkChoices.length < 2);
323
324
 
324
325
  let msgDone = false;
@@ -339,10 +340,11 @@ function updateCompletionChoices(
339
340
  chunkChoices: OpenAI.Chat.Completions.ChatCompletionChunk.Choice[]
340
341
  ): boolean {
341
342
  // Technically, one choice could be done and the other still have some
342
- // content to stream. We keep it simple for now and assume only single
343
- // choices, which allows us to mark everything as done if any choice we hit is
344
- // done.
345
- assert(chunkChoices.length === 1);
343
+ // content to stream. We keep it simple for now and allow zero or one
344
+ // choice per chunk, which allows us to mark everything as done if any
345
+ // choice we hit is done. Zero choices can occur in usage-only chunks at
346
+ // the end of the stream.
347
+ assert(chunkChoices.length < 2);
346
348
  assert(completionChoices.length === 1);
347
349
 
348
350
  let msgDone = false;
@@ -481,6 +483,9 @@ export class OpenAILLMStreaming implements ILLM {
481
483
  messages,
482
484
  tools,
483
485
  stream: true,
486
+ stream_options: {
487
+ include_usage: true,
488
+ },
484
489
  });
485
490
 
486
491
  // Check the type casting above
@@ -507,6 +512,8 @@ export class OpenAILLMStreaming implements ILLM {
507
512
 
508
513
  if (onMessage) {
509
514
  // Inform the call of a message fragment if it contains any text.
515
+ // Note: chunks may have zero choices (e.g., usage-only chunks), so
516
+ // we safely access the first choice.
510
517
 
511
518
  const delta = chunk.choices[0]?.delta;
512
519
  if (delta?.content) {
@@ -40,11 +40,10 @@ class SanitizedServerBrief extends McpServerBrief {
40
40
  }
41
41
 
42
42
  /**
43
- * A manager which can expose a set of mcp servers and set them to an
44
- * McpServerManager.
43
+ * An McpServerManager which can list a set of servers, and enable them in
44
+ * response to requests.
45
45
  */
46
- export interface ISkillManager {
47
- getMcpServerManager(): IMcpServerManager;
46
+ export interface ISkillManager extends IMcpServerManager {
48
47
  getServerBriefs(): McpServerBrief[];
49
48
 
50
49
  /**
@@ -55,15 +54,16 @@ export interface ISkillManager {
55
54
  * is enabled.
56
55
  */
57
56
  addMcpServer(serverName: string, enableAll: boolean): Promise<void>;
57
+
58
+ shutdown(): Promise<void>;
58
59
  }
59
60
 
60
61
  /**
61
62
  * Manages access to the catalogue of servers hosted by sudomcp. Supports
62
63
  * adding these servers to McpServerManager.
63
64
  */
64
- export class SkillManager implements ISkillManager {
65
+ export class SkillManager extends McpServerManager implements ISkillManager {
65
66
  private constructor(
66
- private mcpServerManager: McpServerManager,
67
67
  private apiClient: ApiClient,
68
68
  private serverBriefs: SanitizedServerBrief[],
69
69
  private serverBriefsMap: { [serverName: string]: SanitizedServerBrief },
@@ -75,14 +75,15 @@ export class SkillManager implements ISkillManager {
75
75
  ) => void,
76
76
  // Redirect to this page after successful authorization
77
77
  private authorized_url: string | undefined
78
- ) {}
78
+ ) {
79
+ super();
80
+ }
79
81
 
80
82
  /**
81
83
  * Initialize an ApiClient to interface with SudoMCP backend and
82
84
  * fetch the current list of ServerBriefs.
83
85
  */
84
86
  public static async initialize(
85
- mcpServerManager: McpServerManager,
86
87
  openUrl: (
87
88
  url: string,
88
89
  authResultP: Promise<boolean>,
@@ -102,7 +103,6 @@ export class SkillManager implements ISkillManager {
102
103
 
103
104
  const [mcpServers, mcpServersMap] = buildServersList(servers);
104
105
  return new SkillManager(
105
- mcpServerManager,
106
106
  apiClient,
107
107
  mcpServers,
108
108
  mcpServersMap,
@@ -112,6 +112,10 @@ export class SkillManager implements ISkillManager {
112
112
  );
113
113
  }
114
114
 
115
+ public async shutdown(): Promise<void> {
116
+ return super.shutdown();
117
+ }
118
+
115
119
  /// TODO: Bit awkward that we have to restore via this class, but it's the
116
120
  /// only class which knows how to restore (restart) the mcp servers.
117
121
  public async restoreMcpSettings(
@@ -143,13 +147,13 @@ export class SkillManager implements ISkillManager {
143
147
  }
144
148
  if (enabled.length === 0) {
145
149
  logger.debug(` restoring "${serverName}": (all tools)`);
146
- this.mcpServerManager.enableAllTools(serverName);
150
+ this.enableAllTools(serverName);
147
151
  return;
148
152
  }
149
153
 
150
154
  logger.debug(` restoring "${serverName}": ${JSON.stringify(enabled)}`);
151
155
  for (const toolName of enabled) {
152
- this.mcpServerManager.enableTool(serverName, toolName);
156
+ this.enableTool(serverName, toolName);
153
157
  }
154
158
  };
155
159
  Object.entries(mcpConfig).map((e) => enableTools(e));
@@ -174,10 +178,6 @@ export class SkillManager implements ISkillManager {
174
178
  return this.serverBriefs;
175
179
  }
176
180
 
177
- public getMcpServerManager(): McpServerManager {
178
- return this.mcpServerManager;
179
- }
180
-
181
181
  /**
182
182
  * Return tool list for a given MCP server. Queries the backend
183
183
  * if necessary and caches the result.
@@ -219,10 +219,9 @@ export class SkillManager implements ISkillManager {
219
219
  this.authorized_url
220
220
  );
221
221
 
222
- const msm = this.mcpServerManager;
223
- await msm.addMcpServerWithClient(client, serverName, tools);
222
+ await this.addMcpServerWithClient(client, serverName, tools);
224
223
  if (enableAll) {
225
- msm.enableAllTools(serverName);
224
+ this.enableAllTools(serverName);
226
225
  }
227
226
  }
228
227