@bike4mind/cli 0.2.5-feat-auto-context-customization.17095 → 0.2.5-feat-server-side-tool-execution.17096

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/dist/index.js CHANGED
@@ -4,9 +4,9 @@ import {
4
4
  getEffectiveApiKey,
5
5
  getOpenWeatherKey,
6
6
  getSerperKey
7
- } from "./chunk-55PRVW6C.js";
8
- import "./chunk-GXADX53I.js";
9
- import "./chunk-QFDR3XXO.js";
7
+ } from "./chunk-WNBKV4FX.js";
8
+ import "./chunk-LEG2UM5Q.js";
9
+ import "./chunk-6AJODFPC.js";
10
10
  import {
11
11
  BFLImageService,
12
12
  BaseStorage,
@@ -15,7 +15,7 @@ import {
15
15
  OpenAIBackend,
16
16
  OpenAIImageService,
17
17
  XAIImageService
18
- } from "./chunk-RM2KFSVU.js";
18
+ } from "./chunk-LYNNVNEC.js";
19
19
  import {
20
20
  Logger
21
21
  } from "./chunk-AMDXHL6S.js";
@@ -73,7 +73,7 @@ import {
73
73
  XAI_IMAGE_MODELS,
74
74
  b4mLLMTools,
75
75
  getMcpProviderMetadata
76
- } from "./chunk-2RFX62SX.js";
76
+ } from "./chunk-WR6YZRQV.js";
77
77
  import {
78
78
  __require
79
79
  } from "./chunk-PDX44BCA.js";
@@ -1408,16 +1408,16 @@ var AuthTokensSchema = z.object({
1408
1408
  var ApiConfigSchema = z.object({
1409
1409
  customUrl: z.string().url().optional()
1410
1410
  });
1411
+ var LegacyApiConfigSchema = z.object({
1412
+ environment: z.enum(["production", "staging", "preview", "local", "custom"]),
1413
+ customUrl: z.string().url().optional()
1414
+ });
1411
1415
  var CliConfigSchema = z.object({
1412
1416
  version: z.string(),
1413
1417
  userId: z.string(),
1414
1418
  auth: AuthTokensSchema.optional(),
1415
1419
  defaultModel: z.string(),
1416
1420
  apiConfig: ApiConfigSchema.optional(),
1417
- toolApiKeys: z.object({
1418
- openweather: z.string().optional(),
1419
- serper: z.string().optional()
1420
- }).optional(),
1421
1421
  mcpServers: z.array(
1422
1422
  z.object({
1423
1423
  name: z.string(),
@@ -1442,15 +1442,36 @@ var CliConfigSchema = z.object({
1442
1442
  }),
1443
1443
  trustedTools: z.array(z.string()).optional().default([])
1444
1444
  });
1445
+ var getCliPackageRoot = () => {
1446
+ const currentFile = new URL(import.meta.url).pathname;
1447
+ const currentDir = path4.dirname(currentFile);
1448
+ if (currentDir.endsWith("/dist") || currentDir.includes("/dist/")) {
1449
+ return path4.resolve(currentDir, "..");
1450
+ }
1451
+ if (currentDir.includes("/src")) {
1452
+ const srcIndex = currentDir.lastIndexOf("/src");
1453
+ return currentDir.substring(0, srcIndex);
1454
+ }
1455
+ return process.cwd();
1456
+ };
1445
1457
  var DEFAULT_CONFIG = {
1446
1458
  version: "0.1.0",
1447
1459
  userId: uuidv4(),
1448
1460
  defaultModel: "claude-sonnet-4-5-20250929",
1449
- toolApiKeys: {
1450
- openweather: void 0,
1451
- serper: void 0
1452
- },
1453
- mcpServers: [],
1461
+ mcpServers: [
1462
+ // B4M server-side tools (weather, serper) via MCP proxy
1463
+ {
1464
+ name: "b4m-tools",
1465
+ command: "node",
1466
+ args: [path4.join(getCliPackageRoot(), "bin/b4m-mcp-proxy.mjs")],
1467
+ // Absolute path to wrapper script
1468
+ env: {
1469
+ // Token and API URL injected dynamically by wrapper script
1470
+ B4M_TIMEOUT: "30000"
1471
+ },
1472
+ enabled: true
1473
+ }
1474
+ ],
1454
1475
  preferences: {
1455
1476
  maxTokens: 4096,
1456
1477
  temperature: 0.7,
@@ -1505,11 +1526,14 @@ var ConfigStore = class {
1505
1526
  const data = await fs4.readFile(this.configPath, "utf-8");
1506
1527
  const rawConfig = JSON.parse(data);
1507
1528
  if (rawConfig.apiConfig && "environment" in rawConfig.apiConfig) {
1508
- const oldApiConfig = rawConfig.apiConfig;
1509
- if (oldApiConfig.environment === "custom" && oldApiConfig.customUrl) {
1510
- rawConfig.apiConfig = { customUrl: oldApiConfig.customUrl };
1511
- } else {
1512
- rawConfig.apiConfig = {};
1529
+ const legacyConfigResult = LegacyApiConfigSchema.safeParse(rawConfig.apiConfig);
1530
+ if (legacyConfigResult.success) {
1531
+ const oldApiConfig = legacyConfigResult.data;
1532
+ if (oldApiConfig.environment === "custom" && oldApiConfig.customUrl) {
1533
+ rawConfig.apiConfig = { customUrl: oldApiConfig.customUrl };
1534
+ } else {
1535
+ rawConfig.apiConfig = {};
1536
+ }
1513
1537
  }
1514
1538
  }
1515
1539
  const validated = CliConfigSchema.parse(rawConfig);
@@ -1526,10 +1550,6 @@ var ConfigStore = class {
1526
1550
  ...DEFAULT_CONFIG.tools,
1527
1551
  ...validated.tools
1528
1552
  },
1529
- toolApiKeys: {
1530
- ...DEFAULT_CONFIG.toolApiKeys,
1531
- ...validated.toolApiKeys || {}
1532
- },
1533
1553
  trustedTools: validated.trustedTools || []
1534
1554
  };
1535
1555
  return this.config;
@@ -1564,10 +1584,6 @@ var ConfigStore = class {
1564
1584
  tools: {
1565
1585
  ...existingConfig.tools,
1566
1586
  ...config.tools || {}
1567
- },
1568
- toolApiKeys: {
1569
- ...existingConfig.toolApiKeys,
1570
- ...config.toolApiKeys || {}
1571
1587
  }
1572
1588
  };
1573
1589
  }
@@ -1720,6 +1736,26 @@ var ConfigStore = class {
1720
1736
  }
1721
1737
  await this.save(config);
1722
1738
  }
1739
+ /**
1740
+ * Ensure B4M MCP server is configured (auto-add if missing)
1741
+ * This provides server-side tools (weather, serper) to the CLI
1742
+ */
1743
+ async ensureB4mMcpServer() {
1744
+ const config = await this.load();
1745
+ const hasB4mServer = config.mcpServers.some((s) => s.name === "b4m-tools");
1746
+ if (!hasB4mServer) {
1747
+ config.mcpServers.push({
1748
+ name: "b4m-tools",
1749
+ command: "node",
1750
+ args: [path4.join(getCliPackageRoot(), "bin/b4m-mcp-proxy.mjs")],
1751
+ env: {
1752
+ B4M_TIMEOUT: "30000"
1753
+ },
1754
+ enabled: true
1755
+ });
1756
+ await this.save(config);
1757
+ }
1758
+ }
1723
1759
  };
1724
1760
 
1725
1761
  // src/storage/CommandHistoryStore.ts
@@ -3087,9 +3123,7 @@ var updateSchema = z76.object({
3087
3123
  name: z76.string().optional(),
3088
3124
  description: z76.string().optional(),
3089
3125
  billingContact: z76.string().optional(),
3090
- currentCredits: z76.coerce.number().optional(),
3091
- systemPrompt: z76.string().max(1e4).optional()
3092
- // ~2500 tokens
3126
+ currentCredits: z76.coerce.number().optional()
3093
3127
  });
3094
3128
 
3095
3129
  // ../../b4m-core/packages/services/dist/src/organizationService/delete.js
@@ -4283,8 +4317,8 @@ async function processAndStoreImages(images, context) {
4283
4317
  const buffer = await downloadImage(image);
4284
4318
  const fileType = await fileTypeFromBuffer2(buffer);
4285
4319
  const filename = `${uuidv45()}.${fileType?.ext}`;
4286
- const path13 = await context.imageGenerateStorage.upload(buffer, filename, {});
4287
- return path13;
4320
+ const path14 = await context.imageGenerateStorage.upload(buffer, filename, {});
4321
+ return path14;
4288
4322
  }));
4289
4323
  }
4290
4324
  async function updateQuestAndReturnMarkdown(storedImageUrls, context) {
@@ -5468,8 +5502,8 @@ async function processAndStoreImage(imageUrl, context) {
5468
5502
  const buffer = await downloadImage2(imageUrl);
5469
5503
  const fileType = await fileTypeFromBuffer3(buffer);
5470
5504
  const filename = `${uuidv46()}.${fileType?.ext}`;
5471
- const path13 = await context.imageGenerateStorage.upload(buffer, filename, {});
5472
- return path13;
5505
+ const path14 = await context.imageGenerateStorage.upload(buffer, filename, {});
5506
+ return path14;
5473
5507
  }
5474
5508
  async function updateQuestAndReturnMarkdown2(storedImagePath, context) {
5475
5509
  await context.onFinish?.("edit_image", storedImagePath);
@@ -7881,92 +7915,6 @@ var deleteFileTool = {
7881
7915
  })
7882
7916
  };
7883
7917
 
7884
- // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/knowledgeBaseSearch/index.js
7885
- function formatSearchResults(files) {
7886
- if (files.length === 0) {
7887
- return "No documents found matching your search query in your knowledge base.";
7888
- }
7889
- const formattedFiles = files.map((file, index) => {
7890
- const tags = file.tags?.map((t) => t.name).join(", ") || "none";
7891
- const notes = file.notes ? `
7892
- Notes: ${file.notes}` : "";
7893
- const fileType = file.type || "FILE";
7894
- return `${index + 1}. **${file.fileName}**
7895
- Type: ${fileType} | MIME: ${file.mimeType}
7896
- Tags: ${tags}${notes}`;
7897
- });
7898
- return `Found ${files.length} document(s) in your knowledge base:
7899
-
7900
- ` + formattedFiles.join("\n\n") + "\n\n*To use these documents in your conversation, you can ask me to reference specific files by name.*";
7901
- }
7902
- var knowledgeBaseSearchTool = {
7903
- name: "search_knowledge_base",
7904
- implementation: (context) => ({
7905
- toolFn: async (value) => {
7906
- const params = value;
7907
- const { query, tags, file_type, max_results = 5 } = params;
7908
- console.log("\u{1F4DA} Knowledge Base Search: Starting search for query:", query);
7909
- if (!context.db.fabfiles) {
7910
- console.error("\u274C Knowledge Base Search: fabfiles repository not available");
7911
- return "Knowledge base search is not available at this time.";
7912
- }
7913
- try {
7914
- const searchResults = await context.db.fabfiles.search(context.userId, query, {
7915
- tags: tags || [],
7916
- type: file_type,
7917
- shared: false
7918
- // Search all accessible files, not just shared
7919
- }, {
7920
- page: 1,
7921
- limit: Math.min(max_results, 10)
7922
- // Cap at 10 results
7923
- }, {
7924
- by: "fileName",
7925
- direction: "asc"
7926
- }, {
7927
- includeShared: true
7928
- // Include organization and explicitly shared files
7929
- });
7930
- console.log("\u{1F4DA} Knowledge Base Search: Found", searchResults.data.length, "results");
7931
- return formatSearchResults(searchResults.data);
7932
- } catch (error) {
7933
- console.error("\u274C Knowledge Base Search: Error during search:", error);
7934
- return "An error occurred while searching your knowledge base. Please try again.";
7935
- }
7936
- },
7937
- toolSchema: {
7938
- name: "search_knowledge_base",
7939
- description: "Search the user's uploaded knowledge base (fab files). Returns relevant documents from the user's own files, organization-shared files, and files explicitly shared with them. Use this tool when the user asks about their own documents, uploaded files, or organization knowledge.",
7940
- parameters: {
7941
- type: "object",
7942
- properties: {
7943
- query: {
7944
- type: "string",
7945
- description: "The search query to find relevant documents by filename or content"
7946
- },
7947
- tags: {
7948
- type: "array",
7949
- items: { type: "string" },
7950
- description: "Optional: filter results to only include files with these tags"
7951
- },
7952
- file_type: {
7953
- type: "string",
7954
- enum: ["pdf", "text", "image", "excel", "word", "json", "csv", "markdown", "code", "url"],
7955
- description: "Optional: filter results by file type"
7956
- },
7957
- max_results: {
7958
- type: "number",
7959
- description: "Maximum number of results to return (default: 5, max: 10)",
7960
- minimum: 1,
7961
- maximum: 10
7962
- }
7963
- },
7964
- required: ["query"]
7965
- }
7966
- }
7967
- })
7968
- };
7969
-
7970
7918
  // ../../b4m-core/packages/services/dist/src/llm/tools/index.js
7971
7919
  var tools = {
7972
7920
  dice_roll: diceRollTool,
@@ -7994,9 +7942,7 @@ var tools = {
7994
7942
  create_file: createFileTool,
7995
7943
  glob_files: globFilesTool,
7996
7944
  grep_search: grepSearchTool,
7997
- delete_file: deleteFileTool,
7998
- // Knowledge base search
7999
- search_knowledge_base: knowledgeBaseSearchTool
7945
+ delete_file: deleteFileTool
8000
7946
  };
8001
7947
  var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model) => {
8002
7948
  const context = {
@@ -8276,21 +8222,21 @@ var NoOpStorage = class extends BaseStorage {
8276
8222
  async upload(input, destination, options) {
8277
8223
  return `/tmp/${destination}`;
8278
8224
  }
8279
- async download(path13) {
8225
+ async download(path14) {
8280
8226
  throw new Error("Download not supported in CLI");
8281
8227
  }
8282
- async delete(path13) {
8228
+ async delete(path14) {
8283
8229
  }
8284
- async getSignedUrl(path13) {
8285
- return `/tmp/${path13}`;
8230
+ async getSignedUrl(path14) {
8231
+ return `/tmp/${path14}`;
8286
8232
  }
8287
- getPublicUrl(path13) {
8288
- return `/tmp/${path13}`;
8233
+ getPublicUrl(path14) {
8234
+ return `/tmp/${path14}`;
8289
8235
  }
8290
- async getPreview(path13) {
8291
- return `/tmp/${path13}`;
8236
+ async getPreview(path14) {
8237
+ return `/tmp/${path14}`;
8292
8238
  }
8293
- async getMetadata(path13) {
8239
+ async getMetadata(path14) {
8294
8240
  return { size: 0, contentType: "application/octet-stream" };
8295
8241
  }
8296
8242
  };
@@ -8362,7 +8308,7 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
8362
8308
  }
8363
8309
  };
8364
8310
  }
8365
- function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext, toolApiKeys) {
8311
+ function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext) {
8366
8312
  const logger2 = new CliLogger();
8367
8313
  const storage = new NoOpStorage();
8368
8314
  const user = {
@@ -8377,50 +8323,27 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
8377
8323
  };
8378
8324
  const onFinish = async (toolName, data) => {
8379
8325
  };
8380
- const mockAdminSettings = {
8381
- findBySettingName: async (settingName) => {
8382
- if (settingName === "OpenWeatherKey") {
8383
- const key = toolApiKeys?.openweather || process.env.OPENWEATHER_API_KEY;
8384
- if (key) {
8385
- return { settingValue: key };
8386
- }
8387
- }
8388
- if (settingName === "SerperKey") {
8389
- const key = toolApiKeys?.serper || process.env.SERPER_API_KEY;
8390
- if (key) {
8391
- return { settingValue: key };
8392
- }
8393
- }
8394
- return null;
8395
- }
8396
- };
8397
8326
  const dbAdapters = {
8398
8327
  db: {
8399
8328
  apiKeys: null,
8400
- adminSettings: mockAdminSettings
8329
+ adminSettings: null
8401
8330
  }
8402
8331
  };
8403
- const hasSerperKey = !!(toolApiKeys?.serper || process.env.SERPER_API_KEY);
8404
- const hasOpenWeatherKey = !!(toolApiKeys?.openweather || process.env.OPENWEATHER_API_KEY);
8405
8332
  const toolConfig = {
8406
- // Enable these tools for CLI (no external API keys needed)
8333
+ // Local-only tools (no external API keys needed)
8407
8334
  dice_roll: {},
8408
8335
  math_evaluate: {},
8409
8336
  current_datetime: {},
8410
8337
  prompt_enhancement: {},
8411
- // File operation tools (CLI-specific)
8338
+ // File operation tools (CLI-specific, local execution)
8412
8339
  file_read: {},
8413
8340
  create_file: {},
8414
8341
  glob_files: {},
8415
8342
  grep_search: {},
8416
- delete_file: {},
8417
- // Tools requiring API keys (only include if API key is available)
8418
- ...hasSerperKey && { web_search: {} },
8419
- // Requires SERPER_API_KEY
8420
- ...hasOpenWeatherKey && { weather_info: {} },
8421
- // Requires OPENWEATHER_API_KEY
8422
- ...hasSerperKey && { deep_research: {} }
8423
- // Requires SERPER_API_KEY
8343
+ delete_file: {}
8344
+ // REMOVED: weather_info, web_search, deep_research
8345
+ // These are now provided by B4M MCP server (b4m-tools)
8346
+ // They execute server-side using B4M company API keys
8424
8347
  // Disable web-only tools
8425
8348
  // blog_publish: undefined,
8426
8349
  // blog_edit: undefined,
@@ -8880,12 +8803,14 @@ var MCPClient = class {
8880
8803
  mcp;
8881
8804
  transport = null;
8882
8805
  envVariables;
8806
+ customScriptPath;
8883
8807
  tools = [];
8884
8808
  serverName;
8885
- constructor({ envVariables, name, selectedRepositories }) {
8809
+ constructor({ envVariables, name, selectedRepositories, customScriptPath }) {
8886
8810
  this.mcp = new Client2({ name: "mcp-client-cli", version: "1.0.0" });
8887
8811
  this.envVariables = [...envVariables];
8888
8812
  this.serverName = name;
8813
+ this.customScriptPath = customScriptPath;
8889
8814
  if (name === "github" && selectedRepositories) {
8890
8815
  const reposJson = JSON.stringify(selectedRepositories);
8891
8816
  this.envVariables.push({
@@ -8896,26 +8821,35 @@ var MCPClient = class {
8896
8821
  }
8897
8822
  async connectToServer() {
8898
8823
  try {
8899
- const root = process.env.INIT_CWD || process.cwd();
8900
- const candidatePaths = [
8901
- // When running from SST Lambda with node_modules structure (copyFiles)
8902
- path12.join(root, `node_modules/@bike4mind/mcp/dist/src/${this.serverName}/index.js`),
8903
- // When running from SST Lambda deployed environment (/var/task)
8904
- path12.join(root, `b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8905
- // When running from SST Lambda (.sst/artifacts/mcpHandler-dev), navigate to monorepo root (3 levels up)
8906
- path12.join(root, `../../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8907
- // When running from packages/client (Next.js app), navigate to monorepo root (2 levels up)
8908
- path12.join(root, `../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8909
- // Original paths (backward compatibility)
8910
- path12.join(root, `/b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8911
- path12.join(root, "core", "mcp", "servers", this.serverName, "dist", "index.js")
8912
- ];
8913
- const serverScriptPath = candidatePaths.find((p) => existsSync6(p));
8914
- if (!serverScriptPath) {
8915
- const getDirectories = (source) => readdirSync3(source, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
8916
- console.error(`[MCP] Server script not found. Tried paths:`, candidatePaths);
8917
- console.error(`[MCP] Available directories in ${root}:`, getDirectories(root));
8918
- throw new Error(`MCP Server script path not found for ${this.serverName}. Root: ${root}, Available dirs: ${getDirectories(root).join(", ")}`);
8824
+ let serverScriptPath;
8825
+ if (this.customScriptPath) {
8826
+ if (!existsSync6(this.customScriptPath)) {
8827
+ throw new Error(`Custom MCP server script not found at: ${this.customScriptPath}`);
8828
+ }
8829
+ serverScriptPath = this.customScriptPath;
8830
+ } else {
8831
+ const root = process.env.INIT_CWD || process.cwd();
8832
+ const candidatePaths = [
8833
+ // When running from SST Lambda with node_modules structure (copyFiles)
8834
+ path12.join(root, `node_modules/@bike4mind/mcp/dist/src/${this.serverName}/index.js`),
8835
+ // When running from SST Lambda deployed environment (/var/task)
8836
+ path12.join(root, `b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8837
+ // When running from SST Lambda (.sst/artifacts/mcpHandler-dev), navigate to monorepo root (3 levels up)
8838
+ path12.join(root, `../../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8839
+ // When running from packages/client (Next.js app), navigate to monorepo root (2 levels up)
8840
+ path12.join(root, `../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8841
+ // Original paths (backward compatibility)
8842
+ path12.join(root, `/b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8843
+ path12.join(root, "core", "mcp", "servers", this.serverName, "dist", "index.js")
8844
+ ];
8845
+ const foundPath = candidatePaths.find((p) => existsSync6(p));
8846
+ if (!foundPath) {
8847
+ const getDirectories = (source) => readdirSync3(source, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
8848
+ console.error(`[MCP] Server script not found. Tried paths:`, candidatePaths);
8849
+ console.error(`[MCP] Available directories in ${root}:`, getDirectories(root));
8850
+ throw new Error(`MCP Server script path not found for ${this.serverName}. Root: ${root}, Available dirs: ${getDirectories(root).join(", ")}`);
8851
+ }
8852
+ serverScriptPath = foundPath;
8919
8853
  }
8920
8854
  console.log(`[MCP] Using server: ${this.serverName} at ${serverScriptPath}`);
8921
8855
  this.transport = new StdioClientTransport({
@@ -8997,6 +8931,20 @@ var MCPClient = class {
8997
8931
  };
8998
8932
 
8999
8933
  // src/utils/mcpAdapter.ts
8934
+ import path13 from "path";
8935
+ import { fileURLToPath } from "url";
8936
+ var getCliPackageRoot2 = () => {
8937
+ const currentFile = fileURLToPath(import.meta.url);
8938
+ const currentDir = path13.dirname(currentFile);
8939
+ if (currentDir.includes("/dist")) {
8940
+ return path13.resolve(currentDir, "..");
8941
+ }
8942
+ if (currentDir.includes("/src")) {
8943
+ const srcIndex = currentDir.lastIndexOf("/src");
8944
+ return currentDir.substring(0, srcIndex);
8945
+ }
8946
+ return process.cwd();
8947
+ };
9000
8948
  var McpManager = class {
9001
8949
  constructor(config) {
9002
8950
  this.servers = /* @__PURE__ */ new Map();
@@ -9032,9 +8980,16 @@ var McpManager = class {
9032
8980
  key,
9033
8981
  value
9034
8982
  }));
8983
+ let scriptPath = serverConfig.args?.[0];
8984
+ if (scriptPath && !path13.isAbsolute(scriptPath)) {
8985
+ scriptPath = path13.join(getCliPackageRoot2(), scriptPath);
8986
+ logger.debug(`Resolved MCP script path: ${scriptPath}`);
8987
+ }
9035
8988
  const client = new MCPClient({
9036
8989
  envVariables,
9037
- name: serverConfig.name
8990
+ name: serverConfig.name,
8991
+ // Pass custom script path for bundled servers like b4m-tools
8992
+ customScriptPath: scriptPath
9038
8993
  });
9039
8994
  await client.connectToServer();
9040
8995
  const mcpData = {
@@ -9492,7 +9447,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
9492
9447
  // package.json
9493
9448
  var package_default = {
9494
9449
  name: "@bike4mind/cli",
9495
- version: "0.2.5-feat-auto-context-customization.17095+87596453c",
9450
+ version: "0.2.5-feat-server-side-tool-execution.17096+d6b936a82",
9496
9451
  type: "module",
9497
9452
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
9498
9453
  license: "UNLICENSED",
@@ -9525,6 +9480,7 @@ var package_default = {
9525
9480
  scripts: {
9526
9481
  dev: "tsx src/index.tsx",
9527
9482
  build: "tsup",
9483
+ postbuild: "node scripts/bundle-mcp-proxy.mjs",
9528
9484
  typecheck: "tsc --noEmit",
9529
9485
  test: "vitest run",
9530
9486
  "test:watch": "vitest",
@@ -9594,10 +9550,11 @@ var package_default = {
9594
9550
  },
9595
9551
  devDependencies: {
9596
9552
  "@bike4mind/agents": "0.1.0",
9597
- "@bike4mind/common": "2.37.1-feat-auto-context-customization.17095+87596453c",
9598
- "@bike4mind/mcp": "1.19.6-feat-auto-context-customization.17095+87596453c",
9599
- "@bike4mind/services": "2.32.2-feat-auto-context-customization.17095+87596453c",
9600
- "@bike4mind/utils": "2.1.1-feat-auto-context-customization.17095+87596453c",
9553
+ "@bike4mind/common": "2.37.1-feat-server-side-tool-execution.17096+d6b936a82",
9554
+ "@bike4mind/mcp": "1.19.6-feat-server-side-tool-execution.17096+d6b936a82",
9555
+ "@bike4mind/mcp-server-b4m-proxy": "1.0.1-feat-server-side-tool-execution.17096+d6b936a82",
9556
+ "@bike4mind/services": "2.32.2-feat-server-side-tool-execution.17096+d6b936a82",
9557
+ "@bike4mind/utils": "2.1.1-feat-server-side-tool-execution.17096+d6b936a82",
9601
9558
  "@types/diff": "^5.0.9",
9602
9559
  "@types/jsonwebtoken": "^9.0.4",
9603
9560
  "@types/node": "^22.9.0",
@@ -9609,7 +9566,7 @@ var package_default = {
9609
9566
  typescript: "^5.9.3",
9610
9567
  vitest: "^3.2.4"
9611
9568
  },
9612
- gitHead: "87596453cb00639e899f648a585324f86425ab17"
9569
+ gitHead: "d6b936a82aed081ee4ef534a0e5260bc9fbe5714"
9613
9570
  };
9614
9571
 
9615
9572
  // src/config/constants.ts
@@ -9716,6 +9673,7 @@ function CliApp() {
9716
9673
  isAuthenticated = true;
9717
9674
  const daysUntilExpiry = Math.floor((expiresAt.getTime() - Date.now()) / (1e3 * 60 * 60 * 24));
9718
9675
  console.log(`\u2705 Authenticated (expires in ${daysUntilExpiry} day${daysUntilExpiry !== 1 ? "s" : ""})`);
9676
+ await state.configStore.ensureB4mMcpServer();
9719
9677
  }
9720
9678
  }
9721
9679
  if (!isAuthenticated) {
@@ -9813,10 +9771,6 @@ function CliApp() {
9813
9771
  setPermissionPrompt(prompt);
9814
9772
  });
9815
9773
  };
9816
- console.log("\u{1F511} Tool API Keys:", {
9817
- openweather: config.toolApiKeys?.openweather ? "\u2713 configured" : "\u2717 missing",
9818
- serper: config.toolApiKeys?.serper ? "\u2713 configured" : "\u2717 missing"
9819
- });
9820
9774
  const agentContext = {
9821
9775
  currentAgent: null,
9822
9776
  observationQueue: []
@@ -9827,18 +9781,35 @@ function CliApp() {
9827
9781
  modelInfo.id,
9828
9782
  permissionManager,
9829
9783
  promptFn,
9830
- agentContext,
9831
- config.toolApiKeys
9784
+ agentContext
9832
9785
  );
9833
- console.log(`\u{1F6E0}\uFE0F Loaded ${b4mTools.length} B4M tool(s)`);
9834
- const mcpManager = new McpManager(config);
9835
- await mcpManager.initialize();
9836
- const mcpTools = mcpManager.getTools();
9837
- if (mcpTools.length > 0) {
9838
- const toolCounts = mcpManager.getToolCount();
9839
- toolCounts.forEach(({ serverName, count }) => {
9840
- console.log(` \u{1F4E1} ${serverName}: ${count} tool(s)`);
9841
- });
9786
+ console.log(`\u{1F6E0}\uFE0F Loaded ${b4mTools.length} local tool(s)`);
9787
+ let mcpManager = null;
9788
+ let mcpTools = [];
9789
+ try {
9790
+ mcpManager = new McpManager(config);
9791
+ await mcpManager.initialize();
9792
+ mcpTools = mcpManager.getTools();
9793
+ if (mcpTools.length > 0) {
9794
+ const toolCounts = mcpManager.getToolCount();
9795
+ toolCounts.forEach(({ serverName, count }) => {
9796
+ console.log(` \u{1F4E1} ${serverName}: ${count} tool(s)`);
9797
+ });
9798
+ }
9799
+ const hasB4mServer = mcpManager.getServerNames().includes("b4m-tools");
9800
+ if (hasB4mServer) {
9801
+ console.log("\u{1F310} B4M server tools available (weather, web search)");
9802
+ } else if (!authTokens) {
9803
+ console.log("\u2139\uFE0F Weather and search tools require authentication");
9804
+ console.log(" Run /login to enable B4M server tools");
9805
+ }
9806
+ } catch (error) {
9807
+ console.log("\u26A0\uFE0F MCP server initialization failed - continuing with local tools only");
9808
+ if (error instanceof Error) {
9809
+ console.log(` Error: ${error.message}`);
9810
+ }
9811
+ mcpManager = null;
9812
+ mcpTools = [];
9842
9813
  }
9843
9814
  const allTools = [...b4mTools, ...mcpTools];
9844
9815
  console.log(`\u2705 Total: ${allTools.length} tool(s) available`);
@@ -10302,9 +10273,10 @@ No usage data available for the last ${USAGE_DAYS} days.`);
10302
10273
  {
10303
10274
  apiUrl: loginApiUrl,
10304
10275
  configStore: state.configStore,
10305
- onSuccess: () => {
10276
+ onSuccess: async () => {
10306
10277
  setState((prev) => ({ ...prev, showLoginFlow: false }));
10307
10278
  console.log("\n\u2705 Login successful! Initializing CLI...\n");
10279
+ await state.configStore.ensureB4mMcpServer();
10308
10280
  init().catch((err) => {
10309
10281
  console.error("\n\u274C Initialization failed:", err.message, "\n");
10310
10282
  exit();
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-2RFX62SX.js";
4
+ } from "./chunk-WR6YZRQV.js";
5
5
  import "./chunk-PDX44BCA.js";
6
6
 
7
7
  // ../../b4m-core/packages/services/dist/src/notebookCurationService/llmMarkdownGenerator.js
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-2RFX62SX.js";
4
+ } from "./chunk-WR6YZRQV.js";
5
5
  import "./chunk-PDX44BCA.js";
6
6
 
7
7
  // ../../b4m-core/packages/services/dist/src/notebookCurationService/markdownGenerator.js