Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.5.5] - 2025-10-26

### Fixed

- **Salesforce CLI Path Resolution on Windows**: Fixed issue where `sf` command in PATH was being incorrectly quoted on Windows
- The `deploy_start` tool and all other SF CLI commands now work correctly when SF CLI is in the system PATH
- Only quote SF CLI paths when they contain spaces (indicating full path like "C:\Program Files\sf\bin\sf.cmd")
- Don't quote plain command names (like "sf") that should be resolved from PATH
- Fixes "Command failed: 'sf' is not recognized" errors on Windows
- Applied fix to both `executeSfCommand` and `executeSfCommandRaw` functions in sfCommand.ts

## [1.5.4] - 2025-10-22

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"dxt_version": "0.2",
"name": "salesforce-mcp-server",
"display_name": "Salesforce MCP Server",
"version": "1.5.4",
"version": "1.5.5",
"description": "Salesforce MCP Server - Interact with Salesforce orgs through AI assistants",
"icon": "icon.png",
"long_description": "Enables AI assistants to execute Apex code, query Salesforce data, and manage org metadata using your existing Salesforce CLI authentication. Perfect for developers and administrators who want to automate Salesforce tasks through natural language interactions.\n\nSupports environment variables:\n- READ_ONLY=true - Prevents Apex code execution\n- ALLOWED_ORGS=ALL or comma-separated org list - Restricts access to specific orgs (default: ALL)",
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@advanced-communities/salesforce-mcp-server",
"version": "1.5.4",
"version": "1.5.5",
"description": "MCP server enabling AI assistants to interact with Salesforce orgs through the Salesforce CLI",
"main": "./src/index.ts",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function buildServerDescription(): string {
const allowedOrgs = permissions.getAllowedOrgs();
const permissionInfo = [];

let description = `Salesforce MCP Server v1.5.3 - AI-powered Salesforce automation via CLI integration\n`;
let description = `Salesforce MCP Server v1.5.5 - AI-powered Salesforce automation via CLI integration\n`;
description += `Capabilities: Apex execution, SOQL queries, org management, code testing & coverage\n`;

if (readOnlyMode) {
Expand Down
20 changes: 12 additions & 8 deletions src/utils/sfCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ function findSfPath(): string {

export function executeSfCommand(command: string): Promise<any> {
const sfPath = findSfPath();
const fullCommand = command.replace(/^sf\s+/, `"${sfPath}" `);
// Only quote the path if it contains spaces (indicating it's a full path, not a command name)
const quotedPath = sfPath.includes(" ") ? `"${sfPath}"` : sfPath;
const fullCommand = command.replace(/^sf\s+/, `${quotedPath} `);

return new Promise((resolve, reject) => {
exec(
Expand All @@ -65,8 +67,8 @@ export function executeSfCommand(command: string): Promise<any> {
reject(
new Error(
"Salesforce CLI (sf) not found. Please ensure it is installed and accessible. " +
"Visit https://developer.salesforce.com/tools/salesforcecli for installation instructions."
)
"Visit https://developer.salesforce.com/tools/salesforcecli for installation instructions.",
),
);
return;
}
Expand Down Expand Up @@ -95,14 +97,16 @@ export function executeSfCommand(command: string): Promise<any> {
} catch (parseError) {
reject(parseError);
}
}
},
);
});
}

export function executeSfCommandRaw(command: string): Promise<string> {
const sfPath = findSfPath();
const fullCommand = command.replace(/^sf\s+/, `"${sfPath}" `);
// Only quote the path if it contains spaces (indicating it's a full path, not a command name)
const quotedPath = sfPath.includes(" ") ? `"${sfPath}"` : sfPath;
const fullCommand = command.replace(/^sf\s+/, `${quotedPath} `);

return new Promise((resolve, reject) => {
exec(
Expand All @@ -117,8 +121,8 @@ export function executeSfCommandRaw(command: string): Promise<string> {
reject(
new Error(
"Salesforce CLI (sf) not found. Please ensure it is installed and accessible. " +
"Visit https://developer.salesforce.com/tools/salesforcecli for installation instructions."
)
"Visit https://developer.salesforce.com/tools/salesforcecli for installation instructions.",
),
);
} else {
// For scanner commands, non-zero exit code with stdout means violations were found
Expand All @@ -137,7 +141,7 @@ export function executeSfCommandRaw(command: string): Promise<string> {
}
// Return raw stdout without JSON parsing
resolve(stdout);
}
},
);
});
}