@bike4mind/cli 0.2.5-feat-cli-dynamic-model-fetching.17090 → 0.2.5-feat-cli-docker-mcp-support.17095
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/README.md +50 -4
- package/dist/index.js +154 -205
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -172,13 +172,15 @@ export SERPER_API_KEY="your-key-here"
|
|
|
172
172
|
|
|
173
173
|
MCP (Model Context Protocol) servers provide additional tools and capabilities. Configure them in `~/.bike4mind/config.json`:
|
|
174
174
|
|
|
175
|
+
#### Internal MCP Servers (Node.js)
|
|
176
|
+
|
|
177
|
+
For MCP servers bundled with the monorepo, you can omit `command` and `args` - the CLI will automatically discover them:
|
|
178
|
+
|
|
175
179
|
```json
|
|
176
180
|
{
|
|
177
181
|
"mcpServers": [
|
|
178
182
|
{
|
|
179
183
|
"name": "github",
|
|
180
|
-
"command": "node",
|
|
181
|
-
"args": ["path/to/mcp/server.js"],
|
|
182
184
|
"env": {
|
|
183
185
|
"GITHUB_ACCESS_TOKEN": "ghp_..."
|
|
184
186
|
},
|
|
@@ -188,12 +190,56 @@ MCP (Model Context Protocol) servers provide additional tools and capabilities.
|
|
|
188
190
|
}
|
|
189
191
|
```
|
|
190
192
|
|
|
191
|
-
|
|
193
|
+
#### External MCP Servers (Docker)
|
|
194
|
+
|
|
195
|
+
You can run MCP servers in Docker containers for isolation and portability:
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"mcpServers": [
|
|
200
|
+
{
|
|
201
|
+
"name": "github",
|
|
202
|
+
"command": "docker",
|
|
203
|
+
"args": ["run", "-i", "--rm", "-e", "GITHUB_TOKEN", "ghcr.io/github/github-mcp-server"],
|
|
204
|
+
"env": {
|
|
205
|
+
"GITHUB_TOKEN": "ghp_..."
|
|
206
|
+
},
|
|
207
|
+
"enabled": true
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Docker Configuration Notes:**
|
|
214
|
+
- The `-i` flag is required for stdin communication with the MCP server
|
|
215
|
+
- Use `-e VAR_NAME` (without value) to pass environment variables from the host
|
|
216
|
+
- The `--rm` flag ensures containers are cleaned up after use
|
|
217
|
+
- Requires Docker to be installed and running
|
|
218
|
+
|
|
219
|
+
#### External MCP Servers (npx/Custom Commands)
|
|
220
|
+
|
|
221
|
+
You can also run any MCP server via npx or custom executables:
|
|
222
|
+
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"mcpServers": [
|
|
226
|
+
{
|
|
227
|
+
"name": "filesystem",
|
|
228
|
+
"command": "npx",
|
|
229
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"],
|
|
230
|
+
"env": {},
|
|
231
|
+
"enabled": true
|
|
232
|
+
}
|
|
233
|
+
]
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Available Built-in MCP Servers:**
|
|
192
238
|
- 🔧 **GitHub** - Repository management, issues, PRs (requires `GITHUB_ACCESS_TOKEN`)
|
|
193
239
|
- 🔧 **LinkedIn** - Post management, analytics (requires `LINKEDIN_ACCESS_TOKEN`, `COMPANY_NAME`)
|
|
194
240
|
- 🔧 **Atlassian** - Jira/Confluence integration (requires `ATLASSIAN_ACCESS_TOKEN`, `ATLASSIAN_CLOUD_ID`, `ATLASSIAN_SITE_URL`)
|
|
195
241
|
|
|
196
|
-
**Note:** MCP servers must be built and available in the `b4m-core/packages/mcp/dist/src/` directory. The CLI will automatically find them if you're running from the monorepo.
|
|
242
|
+
**Note:** Internal MCP servers must be built and available in the `b4m-core/packages/mcp/dist/src/` directory. The CLI will automatically find them if you're running from the monorepo. For Docker-based servers, ensure Docker is installed and the image is accessible.
|
|
197
243
|
|
|
198
244
|
## Session Storage
|
|
199
245
|
|
package/dist/index.js
CHANGED
|
@@ -685,128 +685,103 @@ var EXPORT_FORMAT_OPTIONS = [
|
|
|
685
685
|
{ label: "markdown", value: "markdown" },
|
|
686
686
|
{ label: "json", value: "json" }
|
|
687
687
|
];
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
688
|
+
var CONFIG_ITEMS = [
|
|
689
|
+
{
|
|
690
|
+
key: "maxIterations",
|
|
691
|
+
label: "Max Iterations",
|
|
692
|
+
type: "select",
|
|
693
|
+
options: MAX_ITERATIONS_OPTIONS,
|
|
694
|
+
getValue: (config) => config.preferences.maxIterations,
|
|
695
|
+
setValue: (config, value) => ({
|
|
696
|
+
...config,
|
|
697
|
+
preferences: {
|
|
698
|
+
...config.preferences,
|
|
699
|
+
maxIterations: value
|
|
700
|
+
}
|
|
701
|
+
})
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
key: "maxTokens",
|
|
705
|
+
label: "Max Tokens",
|
|
706
|
+
type: "number",
|
|
707
|
+
min: 256,
|
|
708
|
+
max: 128e3,
|
|
709
|
+
step: 256,
|
|
710
|
+
getValue: (config) => config.preferences.maxTokens,
|
|
711
|
+
setValue: (config, value) => ({
|
|
712
|
+
...config,
|
|
713
|
+
preferences: {
|
|
714
|
+
...config.preferences,
|
|
715
|
+
maxTokens: value
|
|
716
|
+
}
|
|
717
|
+
})
|
|
718
|
+
},
|
|
719
|
+
{
|
|
720
|
+
key: "temperature",
|
|
721
|
+
label: "Temperature",
|
|
722
|
+
type: "number",
|
|
723
|
+
min: 0,
|
|
724
|
+
max: 2,
|
|
725
|
+
step: 0.1,
|
|
726
|
+
getValue: (config) => config.preferences.temperature,
|
|
727
|
+
setValue: (config, value) => ({
|
|
728
|
+
...config,
|
|
729
|
+
preferences: {
|
|
730
|
+
...config.preferences,
|
|
731
|
+
temperature: value
|
|
732
|
+
}
|
|
733
|
+
})
|
|
734
|
+
},
|
|
735
|
+
{
|
|
736
|
+
key: "autoSave",
|
|
737
|
+
label: "Auto Save",
|
|
738
|
+
type: "boolean",
|
|
739
|
+
getValue: (config) => config.preferences.autoSave,
|
|
740
|
+
setValue: (config, value) => ({
|
|
741
|
+
...config,
|
|
742
|
+
preferences: {
|
|
743
|
+
...config.preferences,
|
|
744
|
+
autoSave: value
|
|
745
|
+
}
|
|
746
|
+
})
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
key: "theme",
|
|
750
|
+
label: "Theme",
|
|
751
|
+
type: "select",
|
|
752
|
+
options: THEME_OPTIONS,
|
|
753
|
+
getValue: (config) => config.preferences.theme,
|
|
754
|
+
setValue: (config, value) => ({
|
|
755
|
+
...config,
|
|
756
|
+
preferences: {
|
|
757
|
+
...config.preferences,
|
|
758
|
+
theme: value
|
|
759
|
+
}
|
|
760
|
+
})
|
|
761
|
+
},
|
|
762
|
+
{
|
|
763
|
+
key: "exportFormat",
|
|
764
|
+
label: "Export Format",
|
|
765
|
+
type: "select",
|
|
766
|
+
options: EXPORT_FORMAT_OPTIONS,
|
|
767
|
+
getValue: (config) => config.preferences.exportFormat,
|
|
768
|
+
setValue: (config, value) => ({
|
|
769
|
+
...config,
|
|
770
|
+
preferences: {
|
|
771
|
+
...config.preferences,
|
|
772
|
+
exportFormat: value
|
|
773
|
+
}
|
|
774
|
+
})
|
|
709
775
|
}
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
key: "maxIterations",
|
|
713
|
-
label: "Max Iterations",
|
|
714
|
-
type: "select",
|
|
715
|
-
options: MAX_ITERATIONS_OPTIONS,
|
|
716
|
-
getValue: (config) => config.preferences.maxIterations,
|
|
717
|
-
setValue: (config, value) => ({
|
|
718
|
-
...config,
|
|
719
|
-
preferences: {
|
|
720
|
-
...config.preferences,
|
|
721
|
-
maxIterations: value
|
|
722
|
-
}
|
|
723
|
-
})
|
|
724
|
-
},
|
|
725
|
-
{
|
|
726
|
-
key: "maxTokens",
|
|
727
|
-
label: "Max Tokens",
|
|
728
|
-
type: "number",
|
|
729
|
-
min: 256,
|
|
730
|
-
max: 128e3,
|
|
731
|
-
step: 256,
|
|
732
|
-
getValue: (config) => config.preferences.maxTokens,
|
|
733
|
-
setValue: (config, value) => ({
|
|
734
|
-
...config,
|
|
735
|
-
preferences: {
|
|
736
|
-
...config.preferences,
|
|
737
|
-
maxTokens: value
|
|
738
|
-
}
|
|
739
|
-
})
|
|
740
|
-
},
|
|
741
|
-
{
|
|
742
|
-
key: "temperature",
|
|
743
|
-
label: "Temperature",
|
|
744
|
-
type: "number",
|
|
745
|
-
min: 0,
|
|
746
|
-
max: 2,
|
|
747
|
-
step: 0.1,
|
|
748
|
-
getValue: (config) => config.preferences.temperature,
|
|
749
|
-
setValue: (config, value) => ({
|
|
750
|
-
...config,
|
|
751
|
-
preferences: {
|
|
752
|
-
...config.preferences,
|
|
753
|
-
temperature: value
|
|
754
|
-
}
|
|
755
|
-
})
|
|
756
|
-
},
|
|
757
|
-
{
|
|
758
|
-
key: "autoSave",
|
|
759
|
-
label: "Auto Save",
|
|
760
|
-
type: "boolean",
|
|
761
|
-
getValue: (config) => config.preferences.autoSave,
|
|
762
|
-
setValue: (config, value) => ({
|
|
763
|
-
...config,
|
|
764
|
-
preferences: {
|
|
765
|
-
...config.preferences,
|
|
766
|
-
autoSave: value
|
|
767
|
-
}
|
|
768
|
-
})
|
|
769
|
-
},
|
|
770
|
-
{
|
|
771
|
-
key: "theme",
|
|
772
|
-
label: "Theme",
|
|
773
|
-
type: "select",
|
|
774
|
-
options: THEME_OPTIONS,
|
|
775
|
-
getValue: (config) => config.preferences.theme,
|
|
776
|
-
setValue: (config, value) => ({
|
|
777
|
-
...config,
|
|
778
|
-
preferences: {
|
|
779
|
-
...config.preferences,
|
|
780
|
-
theme: value
|
|
781
|
-
}
|
|
782
|
-
})
|
|
783
|
-
},
|
|
784
|
-
{
|
|
785
|
-
key: "exportFormat",
|
|
786
|
-
label: "Export Format",
|
|
787
|
-
type: "select",
|
|
788
|
-
options: EXPORT_FORMAT_OPTIONS,
|
|
789
|
-
getValue: (config) => config.preferences.exportFormat,
|
|
790
|
-
setValue: (config, value) => ({
|
|
791
|
-
...config,
|
|
792
|
-
preferences: {
|
|
793
|
-
...config.preferences,
|
|
794
|
-
exportFormat: value
|
|
795
|
-
}
|
|
796
|
-
})
|
|
797
|
-
}
|
|
798
|
-
);
|
|
799
|
-
return items;
|
|
800
|
-
}
|
|
801
|
-
function ConfigEditor({ config, availableModels, onSave, onClose }) {
|
|
776
|
+
];
|
|
777
|
+
function ConfigEditor({ config, onSave, onClose }) {
|
|
802
778
|
const [selectedIndex, setSelectedIndex] = useState2(0);
|
|
803
779
|
const [editedConfig, setEditedConfig] = useState2(config);
|
|
804
780
|
const [saveError, setSaveError] = useState2(null);
|
|
805
781
|
const [isSaving, setIsSaving] = useState2(false);
|
|
806
|
-
const configItems = useMemo2(() => buildConfigItems(availableModels), [availableModels]);
|
|
807
782
|
const hasChanges = useMemo2(() => {
|
|
808
|
-
return JSON.stringify(config.preferences) !== JSON.stringify(editedConfig.preferences)
|
|
809
|
-
}, [config.preferences, editedConfig.preferences
|
|
783
|
+
return JSON.stringify(config.preferences) !== JSON.stringify(editedConfig.preferences);
|
|
784
|
+
}, [config.preferences, editedConfig.preferences]);
|
|
810
785
|
const handleSaveAndClose = async () => {
|
|
811
786
|
if (hasChanges) {
|
|
812
787
|
try {
|
|
@@ -823,13 +798,13 @@ function ConfigEditor({ config, availableModels, onSave, onClose }) {
|
|
|
823
798
|
onClose();
|
|
824
799
|
};
|
|
825
800
|
useInput2((input, key) => {
|
|
826
|
-
const currentItem =
|
|
801
|
+
const currentItem = CONFIG_ITEMS[selectedIndex];
|
|
827
802
|
if (key.upArrow) {
|
|
828
|
-
setSelectedIndex((prev) => prev > 0 ? prev - 1 :
|
|
803
|
+
setSelectedIndex((prev) => prev > 0 ? prev - 1 : CONFIG_ITEMS.length - 1);
|
|
829
804
|
return;
|
|
830
805
|
}
|
|
831
806
|
if (key.downArrow) {
|
|
832
|
-
setSelectedIndex((prev) => prev <
|
|
807
|
+
setSelectedIndex((prev) => prev < CONFIG_ITEMS.length - 1 ? prev + 1 : 0);
|
|
833
808
|
return;
|
|
834
809
|
}
|
|
835
810
|
if ((key.escape || input === "q") && !isSaving) {
|
|
@@ -887,7 +862,7 @@ function ConfigEditor({ config, availableModels, onSave, onClose }) {
|
|
|
887
862
|
}
|
|
888
863
|
return String(value);
|
|
889
864
|
};
|
|
890
|
-
return /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, marginY: 1 }, /* @__PURE__ */ React8.createElement(Box8, { justifyContent: "space-between", marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, "Settings"), isSaving ? /* @__PURE__ */ React8.createElement(Text7, { color: "yellow" }, "Saving...") : hasChanges ? /* @__PURE__ */ React8.createElement(Text7, { dimColor: true, color: "yellow" }, "(unsaved changes)") : null), saveError && /* @__PURE__ */ React8.createElement(Box8, { marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text7, { color: "red" }, "Error: ", saveError)), /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", marginBottom: 1 },
|
|
865
|
+
return /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, marginY: 1 }, /* @__PURE__ */ React8.createElement(Box8, { justifyContent: "space-between", marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, "Settings"), isSaving ? /* @__PURE__ */ React8.createElement(Text7, { color: "yellow" }, "Saving...") : hasChanges ? /* @__PURE__ */ React8.createElement(Text7, { dimColor: true, color: "yellow" }, "(unsaved changes)") : null), saveError && /* @__PURE__ */ React8.createElement(Box8, { marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text7, { color: "red" }, "Error: ", saveError)), /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", marginBottom: 1 }, CONFIG_ITEMS.map((item, index) => {
|
|
891
866
|
const isSelected = index === selectedIndex;
|
|
892
867
|
const value = item.getValue(editedConfig);
|
|
893
868
|
const displayValue = formatValue(item, value);
|
|
@@ -1017,7 +992,6 @@ function App({
|
|
|
1017
992
|
onPermissionResponse,
|
|
1018
993
|
commandHistory = [],
|
|
1019
994
|
config,
|
|
1020
|
-
availableModels = [],
|
|
1021
995
|
onSaveConfig
|
|
1022
996
|
}) {
|
|
1023
997
|
const messages = useCliStore((state) => state.session?.messages || []);
|
|
@@ -1059,15 +1033,7 @@ ${errorBlock}`;
|
|
|
1059
1033
|
},
|
|
1060
1034
|
[onMessage, onCommand, setIsThinking]
|
|
1061
1035
|
);
|
|
1062
|
-
return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column" }, /* @__PURE__ */ React9.createElement(StatusBar, { sessionName, model: currentModel, tokenUsage: totalTokens }), showConfigEditor && config && onSaveConfig ? /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React9.createElement(
|
|
1063
|
-
ConfigEditor,
|
|
1064
|
-
{
|
|
1065
|
-
config,
|
|
1066
|
-
availableModels,
|
|
1067
|
-
onSave: onSaveConfig,
|
|
1068
|
-
onClose: () => setShowConfigEditor(false)
|
|
1069
|
-
}
|
|
1070
|
-
)) : permissionPrompt ? /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React9.createElement(
|
|
1036
|
+
return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column" }, /* @__PURE__ */ React9.createElement(StatusBar, { sessionName, model: currentModel, tokenUsage: totalTokens }), showConfigEditor && config && onSaveConfig ? /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React9.createElement(ConfigEditor, { config, onSave: onSaveConfig, onClose: () => setShowConfigEditor(false) })) : permissionPrompt ? /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React9.createElement(
|
|
1071
1037
|
PermissionPrompt,
|
|
1072
1038
|
{
|
|
1073
1039
|
toolName: permissionPrompt.toolName,
|
|
@@ -1455,8 +1421,8 @@ var CliConfigSchema = z.object({
|
|
|
1455
1421
|
mcpServers: z.array(
|
|
1456
1422
|
z.object({
|
|
1457
1423
|
name: z.string(),
|
|
1458
|
-
command: z.string(),
|
|
1459
|
-
args: z.array(z.string()),
|
|
1424
|
+
command: z.string().optional(),
|
|
1425
|
+
args: z.array(z.string()).optional(),
|
|
1460
1426
|
env: z.record(z.string()),
|
|
1461
1427
|
enabled: z.boolean()
|
|
1462
1428
|
})
|
|
@@ -8824,12 +8790,16 @@ var MCPClient = class {
|
|
|
8824
8790
|
mcp;
|
|
8825
8791
|
transport = null;
|
|
8826
8792
|
envVariables;
|
|
8793
|
+
customCommand;
|
|
8794
|
+
customArgs;
|
|
8827
8795
|
tools = [];
|
|
8828
8796
|
serverName;
|
|
8829
|
-
constructor({ envVariables, name, selectedRepositories }) {
|
|
8797
|
+
constructor({ envVariables, name, selectedRepositories, command, args }) {
|
|
8830
8798
|
this.mcp = new Client2({ name: "mcp-client-cli", version: "1.0.0" });
|
|
8831
8799
|
this.envVariables = [...envVariables];
|
|
8832
8800
|
this.serverName = name;
|
|
8801
|
+
this.customCommand = command;
|
|
8802
|
+
this.customArgs = args;
|
|
8833
8803
|
if (name === "github" && selectedRepositories) {
|
|
8834
8804
|
const reposJson = JSON.stringify(selectedRepositories);
|
|
8835
8805
|
this.envVariables.push({
|
|
@@ -8840,37 +8810,48 @@ var MCPClient = class {
|
|
|
8840
8810
|
}
|
|
8841
8811
|
async connectToServer() {
|
|
8842
8812
|
try {
|
|
8843
|
-
const
|
|
8844
|
-
|
|
8845
|
-
|
|
8846
|
-
|
|
8847
|
-
|
|
8848
|
-
|
|
8849
|
-
|
|
8850
|
-
|
|
8851
|
-
|
|
8852
|
-
|
|
8853
|
-
|
|
8854
|
-
|
|
8855
|
-
|
|
8856
|
-
|
|
8857
|
-
|
|
8858
|
-
|
|
8859
|
-
|
|
8860
|
-
|
|
8861
|
-
|
|
8862
|
-
|
|
8863
|
-
|
|
8864
|
-
|
|
8813
|
+
const envVarsObject = this.envVariables.reduce((acc, env) => ({
|
|
8814
|
+
...acc,
|
|
8815
|
+
[env.key]: env.value
|
|
8816
|
+
}), {});
|
|
8817
|
+
let command;
|
|
8818
|
+
let args;
|
|
8819
|
+
if (this.customCommand && this.customCommand.trim() !== "") {
|
|
8820
|
+
command = this.customCommand;
|
|
8821
|
+
args = this.customArgs ?? [];
|
|
8822
|
+
console.log(`[MCP] Using external command for ${this.serverName}: ${command} ${args.join(" ")}`);
|
|
8823
|
+
} else {
|
|
8824
|
+
const root = process.env.INIT_CWD || process.cwd();
|
|
8825
|
+
const candidatePaths = [
|
|
8826
|
+
// When running from SST Lambda with node_modules structure (copyFiles)
|
|
8827
|
+
path12.join(root, `node_modules/@bike4mind/mcp/dist/src/${this.serverName}/index.js`),
|
|
8828
|
+
// When running from SST Lambda deployed environment (/var/task)
|
|
8829
|
+
path12.join(root, `b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
8830
|
+
// When running from SST Lambda (.sst/artifacts/mcpHandler-dev), navigate to monorepo root (3 levels up)
|
|
8831
|
+
path12.join(root, `../../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
8832
|
+
// When running from packages/client (Next.js app), navigate to monorepo root (2 levels up)
|
|
8833
|
+
path12.join(root, `../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
8834
|
+
// Original paths (backward compatibility)
|
|
8835
|
+
path12.join(root, `/b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
8836
|
+
path12.join(root, "core", "mcp", "servers", this.serverName, "dist", "index.js")
|
|
8837
|
+
];
|
|
8838
|
+
const serverScriptPath = candidatePaths.find((p) => existsSync6(p));
|
|
8839
|
+
if (!serverScriptPath) {
|
|
8840
|
+
const getDirectories = (source) => readdirSync3(source, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
8841
|
+
console.error(`[MCP] Server script not found. Tried paths:`, candidatePaths);
|
|
8842
|
+
console.error(`[MCP] Available directories in ${root}:`, getDirectories(root));
|
|
8843
|
+
throw new Error(`MCP Server script path not found for ${this.serverName}. Root: ${root}, Available dirs: ${getDirectories(root).join(", ")}`);
|
|
8844
|
+
}
|
|
8845
|
+
command = process.execPath;
|
|
8846
|
+
args = [serverScriptPath];
|
|
8847
|
+
console.log(`[MCP] Using server: ${this.serverName} at ${serverScriptPath}`);
|
|
8848
|
+
}
|
|
8865
8849
|
this.transport = new StdioClientTransport({
|
|
8866
|
-
command
|
|
8867
|
-
args
|
|
8850
|
+
command,
|
|
8851
|
+
args,
|
|
8868
8852
|
env: {
|
|
8869
|
-
...process.env,
|
|
8870
|
-
...
|
|
8871
|
-
...acc,
|
|
8872
|
-
[env.key]: env.value
|
|
8873
|
-
}), {})
|
|
8853
|
+
...Object.fromEntries(Object.entries(process.env).filter((entry) => entry[1] !== void 0)),
|
|
8854
|
+
...envVarsObject
|
|
8874
8855
|
}
|
|
8875
8856
|
});
|
|
8876
8857
|
this.transport.onerror = (error) => {
|
|
@@ -8978,7 +8959,9 @@ var McpManager = class {
|
|
|
8978
8959
|
}));
|
|
8979
8960
|
const client = new MCPClient({
|
|
8980
8961
|
envVariables,
|
|
8981
|
-
name: serverConfig.name
|
|
8962
|
+
name: serverConfig.name,
|
|
8963
|
+
command: serverConfig.command,
|
|
8964
|
+
args: serverConfig.args
|
|
8982
8965
|
});
|
|
8983
8966
|
await client.connectToServer();
|
|
8984
8967
|
const mcpData = {
|
|
@@ -9249,40 +9232,9 @@ var ServerLlmBackend = class {
|
|
|
9249
9232
|
}
|
|
9250
9233
|
/**
|
|
9251
9234
|
* Get available models from server
|
|
9252
|
-
*
|
|
9253
|
-
* Falls back to hardcoded list if API fails
|
|
9235
|
+
* For now, returns hardcoded list of supported models
|
|
9254
9236
|
*/
|
|
9255
9237
|
async getModelInfo() {
|
|
9256
|
-
try {
|
|
9257
|
-
logger.debug("[ServerLlmBackend] Fetching models from /api/models");
|
|
9258
|
-
const response = await this.apiClient.get("/api/models");
|
|
9259
|
-
if (!response || typeof response !== "object" || !Array.isArray(response.models)) {
|
|
9260
|
-
logger.warn("[ServerLlmBackend] Invalid API response format, using fallback models");
|
|
9261
|
-
logger.info("\u26A0\uFE0F Using fallback model list (API returned invalid format)");
|
|
9262
|
-
return this.getFallbackModels();
|
|
9263
|
-
}
|
|
9264
|
-
const filteredModels = response.models.filter((model) => model.type === "text" && model.supportsTools === true);
|
|
9265
|
-
logger.debug(`[ServerLlmBackend] Fetched ${filteredModels.length} CLI-compatible models`);
|
|
9266
|
-
if (filteredModels.length === 0) {
|
|
9267
|
-
logger.warn("[ServerLlmBackend] No CLI-compatible models found from API, using fallback");
|
|
9268
|
-
logger.info("\u26A0\uFE0F Using fallback model list (no CLI-compatible models available)");
|
|
9269
|
-
return this.getFallbackModels();
|
|
9270
|
-
}
|
|
9271
|
-
logger.info(`\u{1F4CB} Loaded ${filteredModels.length} models from server`);
|
|
9272
|
-
return filteredModels;
|
|
9273
|
-
} catch (error) {
|
|
9274
|
-
logger.warn(
|
|
9275
|
-
`[ServerLlmBackend] Failed to fetch models from API, using fallback: ${error instanceof Error ? error.message : String(error)}`
|
|
9276
|
-
);
|
|
9277
|
-
logger.info("\u26A0\uFE0F Using fallback model list (API unavailable)");
|
|
9278
|
-
return this.getFallbackModels();
|
|
9279
|
-
}
|
|
9280
|
-
}
|
|
9281
|
-
/**
|
|
9282
|
-
* Fallback models when API is unavailable
|
|
9283
|
-
* Returns hardcoded list of commonly supported models
|
|
9284
|
-
*/
|
|
9285
|
-
getFallbackModels() {
|
|
9286
9238
|
return [
|
|
9287
9239
|
{
|
|
9288
9240
|
id: "claude-sonnet-4-5-20250929",
|
|
@@ -9467,7 +9419,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
|
|
|
9467
9419
|
// package.json
|
|
9468
9420
|
var package_default = {
|
|
9469
9421
|
name: "@bike4mind/cli",
|
|
9470
|
-
version: "0.2.5-feat-cli-
|
|
9422
|
+
version: "0.2.5-feat-cli-docker-mcp-support.17095+1671ebc5f",
|
|
9471
9423
|
type: "module",
|
|
9472
9424
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
9473
9425
|
license: "UNLICENSED",
|
|
@@ -9569,10 +9521,10 @@ var package_default = {
|
|
|
9569
9521
|
},
|
|
9570
9522
|
devDependencies: {
|
|
9571
9523
|
"@bike4mind/agents": "0.1.0",
|
|
9572
|
-
"@bike4mind/common": "2.37.1-feat-cli-
|
|
9573
|
-
"@bike4mind/mcp": "1.19.6-feat-cli-
|
|
9574
|
-
"@bike4mind/services": "2.32.2-feat-cli-
|
|
9575
|
-
"@bike4mind/utils": "2.1.1-feat-cli-
|
|
9524
|
+
"@bike4mind/common": "2.37.1-feat-cli-docker-mcp-support.17095+1671ebc5f",
|
|
9525
|
+
"@bike4mind/mcp": "1.19.6-feat-cli-docker-mcp-support.17095+1671ebc5f",
|
|
9526
|
+
"@bike4mind/services": "2.32.2-feat-cli-docker-mcp-support.17095+1671ebc5f",
|
|
9527
|
+
"@bike4mind/utils": "2.1.1-feat-cli-docker-mcp-support.17095+1671ebc5f",
|
|
9576
9528
|
"@types/diff": "^5.0.9",
|
|
9577
9529
|
"@types/jsonwebtoken": "^9.0.4",
|
|
9578
9530
|
"@types/node": "^22.9.0",
|
|
@@ -9584,7 +9536,7 @@ var package_default = {
|
|
|
9584
9536
|
typescript: "^5.9.3",
|
|
9585
9537
|
vitest: "^3.2.4"
|
|
9586
9538
|
},
|
|
9587
|
-
gitHead: "
|
|
9539
|
+
gitHead: "1671ebc5f5250ee3a79c12b4c549b2c256e71f4d"
|
|
9588
9540
|
};
|
|
9589
9541
|
|
|
9590
9542
|
// src/config/constants.ts
|
|
@@ -9867,10 +9819,8 @@ Remember: Use context from previous messages to understand follow-up questions.`
|
|
|
9867
9819
|
agent,
|
|
9868
9820
|
mcpManager,
|
|
9869
9821
|
permissionManager,
|
|
9870
|
-
config
|
|
9822
|
+
config
|
|
9871
9823
|
// Store config for synchronous access
|
|
9872
|
-
availableModels: models
|
|
9873
|
-
// Store models for ConfigEditor
|
|
9874
9824
|
}));
|
|
9875
9825
|
setStoreSession(newSession);
|
|
9876
9826
|
setIsInitialized(true);
|
|
@@ -10306,7 +10256,6 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
10306
10256
|
onCommand: handleCommand,
|
|
10307
10257
|
commandHistory,
|
|
10308
10258
|
config: state.config,
|
|
10309
|
-
availableModels: state.availableModels,
|
|
10310
10259
|
onSaveConfig: handleSaveConfig,
|
|
10311
10260
|
onPermissionResponse: (response) => {
|
|
10312
10261
|
if (state.permissionPrompt) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bike4mind/cli",
|
|
3
|
-
"version": "0.2.5-feat-cli-
|
|
3
|
+
"version": "0.2.5-feat-cli-docker-mcp-support.17095+1671ebc5f",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -102,10 +102,10 @@
|
|
|
102
102
|
},
|
|
103
103
|
"devDependencies": {
|
|
104
104
|
"@bike4mind/agents": "0.1.0",
|
|
105
|
-
"@bike4mind/common": "2.37.1-feat-cli-
|
|
106
|
-
"@bike4mind/mcp": "1.19.6-feat-cli-
|
|
107
|
-
"@bike4mind/services": "2.32.2-feat-cli-
|
|
108
|
-
"@bike4mind/utils": "2.1.1-feat-cli-
|
|
105
|
+
"@bike4mind/common": "2.37.1-feat-cli-docker-mcp-support.17095+1671ebc5f",
|
|
106
|
+
"@bike4mind/mcp": "1.19.6-feat-cli-docker-mcp-support.17095+1671ebc5f",
|
|
107
|
+
"@bike4mind/services": "2.32.2-feat-cli-docker-mcp-support.17095+1671ebc5f",
|
|
108
|
+
"@bike4mind/utils": "2.1.1-feat-cli-docker-mcp-support.17095+1671ebc5f",
|
|
109
109
|
"@types/diff": "^5.0.9",
|
|
110
110
|
"@types/jsonwebtoken": "^9.0.4",
|
|
111
111
|
"@types/node": "^22.9.0",
|
|
@@ -117,5 +117,5 @@
|
|
|
117
117
|
"typescript": "^5.9.3",
|
|
118
118
|
"vitest": "^3.2.4"
|
|
119
119
|
},
|
|
120
|
-
"gitHead": "
|
|
120
|
+
"gitHead": "1671ebc5f5250ee3a79c12b4c549b2c256e71f4d"
|
|
121
121
|
}
|