From 5c9cea4d7323f81dc4a5b86960567cc4589f859f Mon Sep 17 00:00:00 2001 From: Dmitry Katson Date: Mon, 12 Jan 2026 12:24:12 +0600 Subject: [PATCH] Fix macOS/Linux compatibility issues in Python MCP Proxy - Update README with platform-specific commands (python3 for macOS/Linux) - Fix setup_flow.py to use platform-aware Python commands in generated configs - Add troubleshooting notes for PATH warnings and version updates - Update maintainer scripts and documentation --- samples/BcMCPProxyPython/README.md | 42 ++++++++++++++----- .../bc_mcp_proxy/setup_flow.py | 9 ++-- .../BcMCPProxyPython/maintainer/PUBLISHING.md | 8 ++++ .../maintainer/scripts/publish.ps1 | 13 +++++- .../maintainer/scripts/publish.sh | 11 +++++ samples/BcMCPProxyPython/pyproject.toml | 2 +- 6 files changed, 70 insertions(+), 15 deletions(-) diff --git a/samples/BcMCPProxyPython/README.md b/samples/BcMCPProxyPython/README.md index 8dbeaac8..b26da285 100644 --- a/samples/BcMCPProxyPython/README.md +++ b/samples/BcMCPProxyPython/README.md @@ -14,7 +14,7 @@ This Python implementation was created to provide a simpler, cross-platform alte - **Easier Installation**: Install directly from PyPI with a single command (`pip install bc-mcp-proxy`), no need to build or download executables - **Cross-Platform**: Works on Windows, macOS, and Linux without platform-specific builds -- **Unified Setup**: Interactive setup command (`python -m bc_mcp_proxy setup`) handles configuration, authentication, and generates client configs automatically +- **Unified Setup**: Interactive setup command (`python3 -m bc_mcp_proxy setup` on macOS/Linux, `python -m bc_mcp_proxy setup` on Windows) handles configuration, authentication, and generates client configs automatically - **Better IDE Integration**: Works seamlessly with Cursor, VS Code, and other MCP clients that expect Python-based tools - **Same Functionality**: Provides the same MCP proxy capabilities as the .NET version, connecting stdio-based MCP clients to Business Central's MCP HTTP endpoint @@ -53,10 +53,23 @@ Both versions provide the same core functionality—choose the Python version if 2. **Run the unified setup command** in a terminal (PowerShell, Command Prompt, bash, zsh, etc.): - ```bash + **Windows:** + ```powershell python -m pip install --upgrade bc-mcp-proxy && python -m bc_mcp_proxy setup ``` + **macOS/Linux:** + ```bash + python3 -m pip install --upgrade bc-mcp-proxy && python3 -m bc_mcp_proxy setup + ``` + + **Important:** On macOS/Linux, use `python3` (not `python`) for both commands. If you see "command not found: python", you're using the wrong command. + + **Note:** If pip says "already satisfied" but you need the latest version, add `--force-reinstall`: + ```bash + python3 -m pip install --upgrade --force-reinstall bc-mcp-proxy && python3 -m bc_mcp_proxy setup + ``` + The interactive setup will: - Prompt for your Business Central tenant ID, client ID, environment, and company - Launch the device-code login flow (so you sign in immediately) @@ -109,12 +122,20 @@ When no custom bearer token is supplied, the proxy performs a device-code flow. After setup, you can run the proxy manually using the command printed by setup, or with: -```bash +**Windows:** +```powershell python -m bc_mcp_proxy --TenantId "" --ClientId "" --Environment "" --Company "" -# or -bc-mcp-proxy --TenantId "" --ClientId "" --Environment "" --Company "" ``` +**macOS/Linux:** +```bash +python3 -m bc_mcp_proxy --TenantId "" --ClientId "" --Environment "" --Company "" +``` + +**Note:** On macOS/Linux, if you see a PATH warning during installation, you can either: +- Add the script directory to your PATH (e.g., `export PATH="$HOME/Library/Python/3.12/bin:$PATH"` in `~/.zshrc` or `~/.bashrc`) +- Or always use `python3 -m bc_mcp_proxy` instead of the `bc-mcp-proxy` command + When the proxy logs `Connecting to Business Central MCP endpoint...` followed by device-code instructions, sign in (if prompted). The proxy stays running until you stop it. Configuration files, logs, and generated MCP snippets are stored at: @@ -122,7 +143,7 @@ Configuration files, logs, and generated MCP snippets are stored at: - **Windows**: `%USERPROFILE%\.bc_mcp_proxy\` - **macOS/Linux**: `~/.bc_mcp_proxy/` -Re-run `python -m bc_mcp_proxy setup` at any time to update or regenerate these files. +Re-run `python3 -m bc_mcp_proxy setup` (macOS/Linux) or `python -m bc_mcp_proxy setup` (Windows) at any time to update or regenerate these files. ## Troubleshooting @@ -142,15 +163,16 @@ Re-run `python -m bc_mcp_proxy setup` at any time to update or regenerate these - Confirm the environment supports MCP preview feature 3. **MCP Client Not Detecting Server** - - Verify the Python path in your MCP configuration is correct - - Check that the `bc-mcp-proxy` package is installed (run `python -m pip list | grep bc-mcp-proxy`) + - Verify the Python path in your MCP configuration is correct (use `python3` on macOS/Linux, `python` on Windows) + - Check that the `bc-mcp-proxy` package is installed (run `python3 -m pip list | grep bc-mcp-proxy` on macOS/Linux, or `python -m pip list | findstr bc-mcp-proxy` on Windows) - If using a virtual environment, ensure the MCP client uses the correct Python interpreter - Restart your MCP client after configuration changes 4. **"No module named bc_mcp_proxy" Error** - - Install the package globally: `python -m pip install --upgrade bc-mcp-proxy` - - Or use `--user` flag: `python -m pip install --user --upgrade bc-mcp-proxy` + - Install the package globally: `python3 -m pip install --upgrade bc-mcp-proxy` (macOS/Linux) or `python -m pip install --upgrade bc-mcp-proxy` (Windows) + - Or use `--user` flag: `python3 -m pip install --user --upgrade bc-mcp-proxy` (macOS/Linux) or `python -m pip install --user --upgrade bc-mcp-proxy` (Windows) - Or update your MCP config to use the full path to the Python interpreter that has the package installed + - On macOS/Linux, if you see a PATH warning, use `python3 -m bc_mcp_proxy` instead of the `bc-mcp-proxy` command 5. **Repeated Sign-in Prompts** - The token cache may not be writable. Set `--DeviceCacheLocation` to a directory you control diff --git a/samples/BcMCPProxyPython/bc_mcp_proxy/setup_flow.py b/samples/BcMCPProxyPython/bc_mcp_proxy/setup_flow.py index 28ba182d..3c5ea7d7 100644 --- a/samples/BcMCPProxyPython/bc_mcp_proxy/setup_flow.py +++ b/samples/BcMCPProxyPython/bc_mcp_proxy/setup_flow.py @@ -111,7 +111,8 @@ def generate_client_configs( config: ProxyConfig, ) -> tuple[Dict[str, Any], Dict[str, Any], Dict[str, Any]]: """Produce MCP client configuration dictionaries.""" - executable = sys.executable or "python" + # Use the current Python interpreter, with platform-aware fallback + executable = sys.executable or ("python3" if sys.platform != "win32" else "python") args: List[str] = [ "-m", "bc_mcp_proxy", @@ -191,7 +192,8 @@ def print_next_steps(config: ProxyConfig, cursor_url: str, vscode_url: str) -> N if config.configuration_name: args.extend(["--ConfigurationName", config.configuration_name]) - command_preview = " ".join([repr(sys.executable or 'python'), "-m", "bc_mcp_proxy", *map(_shell_quote, args)]) + python_cmd = sys.executable or ("python3" if sys.platform != "win32" else "python") + command_preview = " ".join([repr(python_cmd), "-m", "bc_mcp_proxy", *map(_shell_quote, args)]) print("\nSetup complete! Next steps:") print("1) Add the MCP server to your preferred client:") @@ -205,7 +207,8 @@ def print_next_steps(config: ProxyConfig, cursor_url: str, vscode_url: str) -> N print("3) Configuration files have been saved to:") print(f" {OUTPUT_DIR}\n") - print("You can rerun 'python -m bc_mcp_proxy setup' at any time to update these settings.") + python_cmd = "python3" if sys.platform != "win32" else "python" + print(f"You can rerun '{python_cmd} -m bc_mcp_proxy setup' at any time to update these settings.") def _shell_quote(value: str) -> str: diff --git a/samples/BcMCPProxyPython/maintainer/PUBLISHING.md b/samples/BcMCPProxyPython/maintainer/PUBLISHING.md index 4186e7ff..5136834d 100644 --- a/samples/BcMCPProxyPython/maintainer/PUBLISHING.md +++ b/samples/BcMCPProxyPython/maintainer/PUBLISHING.md @@ -33,12 +33,20 @@ Run the helper script (PowerShell or Bash) from the package root directory. It i Once artifacts exist in `dist/`, publish them with `twine`. The helper scripts install `twine` and call `python -m twine upload`. +**Important**: When prompted for credentials: +- **Username**: `__token__` (literally, with underscores) +- **Password**: Your PyPI API token (the full token starting with `pypi-`) + +Alternatively, you can set the `TWINE_PASSWORD` environment variable to avoid the prompt: + ```powershell +$env:TWINE_PASSWORD = "pypi-your-token-here" ./maintainer/scripts/publish.ps1 # uploads to pypi ./maintainer/scripts/publish.ps1 testpypi # uploads to TestPyPI ``` ```bash +export TWINE_PASSWORD="pypi-your-token-here" ./maintainer/scripts/publish.sh # uploads to pypi ./maintainer/scripts/publish.sh testpypi # uploads to TestPyPI ``` diff --git a/samples/BcMCPProxyPython/maintainer/scripts/publish.ps1 b/samples/BcMCPProxyPython/maintainer/scripts/publish.ps1 index 9a9b06bd..de1ee501 100644 --- a/samples/BcMCPProxyPython/maintainer/scripts/publish.ps1 +++ b/samples/BcMCPProxyPython/maintainer/scripts/publish.ps1 @@ -18,5 +18,16 @@ Write-Host "Installing twine..." -ForegroundColor Cyan python -m pip install --upgrade twine | Out-Null Write-Host "Uploading artifacts to '$Repository'..." -ForegroundColor Cyan -python -m twine upload --repository "$Repository" dist/* +Write-Host "" +Write-Host "When prompted for credentials:" -ForegroundColor Yellow +Write-Host " Username: __token__" -ForegroundColor Yellow +Write-Host " Password: " -ForegroundColor Yellow +Write-Host "" + +if ($env:TWINE_PASSWORD) { + Write-Host "Using TWINE_PASSWORD environment variable..." -ForegroundColor Cyan + python -m twine upload --repository "$Repository" --username "__token__" --password "$env:TWINE_PASSWORD" dist/* +} else { + python -m twine upload --repository "$Repository" dist/* +} diff --git a/samples/BcMCPProxyPython/maintainer/scripts/publish.sh b/samples/BcMCPProxyPython/maintainer/scripts/publish.sh index b54aefe2..0380ae8c 100644 --- a/samples/BcMCPProxyPython/maintainer/scripts/publish.sh +++ b/samples/BcMCPProxyPython/maintainer/scripts/publish.sh @@ -15,5 +15,16 @@ echo "Installing twine..." python -m pip install --upgrade twine >/dev/null echo "Uploading artifacts to '${REPOSITORY}'..." +echo "" +echo "When prompted for credentials:" +echo " Username: __token__" +echo " Password: " +echo "" + +if [ -n "${TWINE_PASSWORD:-}" ]; then + echo "Using TWINE_PASSWORD environment variable..." + python -m twine upload --repository "${REPOSITORY}" --username "__token__" --password "${TWINE_PASSWORD}" dist/* +else python -m twine upload --repository "${REPOSITORY}" dist/* +fi diff --git a/samples/BcMCPProxyPython/pyproject.toml b/samples/BcMCPProxyPython/pyproject.toml index 17cd0b5e..eafe1a89 100644 --- a/samples/BcMCPProxyPython/pyproject.toml +++ b/samples/BcMCPProxyPython/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "bc-mcp-proxy" -version = "0.1.2" +version = "0.1.3" description = "Python-based MCP stdio proxy for Microsoft Dynamics 365 Business Central" readme = "README.md" requires-python = ">=3.10"