wso2-bi-salesforce-mcp-server
This MCP server lets AI assistants set up, run, and manage Ballerina + Salesforce integrations inside a WSO2 Integrator (BI) workspace — from zero credentials to a running REST service in one conversation — using a suite of 20 tools.
OAuth2 & Authentication
Generate a Salesforce OAuth2 authorization URL (
sf_get_oauth_auth_url)Exchange an authorization code for a refresh token (
sf_exchange_oauth_code)Obtain tokens via username+password flow without a browser (
sf_get_token_password_flow)
Credential & Connection Management
Validate Salesforce credentials via a live API call (
sf_validate_connection)Write/update
Config.tomlwith rotated credentials (sf_write_config_toml)Generate an import-ready Postman collection with credentials baked in (
sf_generate_postman_collection)Import credentials from an existing Postman collection file (
sf_import_postman_credentials)
Discovery & Metadata
List all standard and custom SObjects in a Salesforce org (
sf_list_sobjects)Retrieve full field-level metadata for any SObject (
sf_describe_sobject)
Project Scaffolding
One-shot end-to-end setup: validate credentials, auto-detect sandbox/production, scaffold project with CRUD endpoints and optional CDC/Platform Event listeners, optionally build (
sf_quickstart)Granular project scaffolding without the credential validation step (
sf_scaffold_project)Add a new SObject to an already-scaffolded project (
sf_add_custom_object)Add a CDC or Platform Event listener to an existing project (
sf_add_cdc_listener)
Build & Deployment
Compile a Ballerina project via
bal build(sf_build_project)Start the Ballerina service in the background, returning its PID and URL (
sf_deploy_project)Stop a running Ballerina service (
sf_stop_project)
Onboarding & Guidance
Step-by-step setup guide for Salesforce Connected Apps and credentials (
sf_setup_guide)Verify
balCLI installation and version compatibility (sf_check_prerequisites)
Provides tools for setting up, building, and managing Salesforce integrations using Ballerina within a WSO2 Integrator environment, including credential management, project scaffolding, and deployment.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@wso2-bi-salesforce-mcp-serverCreate a new Ballerina Salesforce integration project"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
wso2-bi-salesforce-mcp-server
MCP server that lets AI assistants set up, run, and manage Ballerina + Salesforce integrations inside a WSO2 Integrator (BI) workspace — from zero credentials to a running REST service in one conversation.
Gives AI assistants 20 tools to acquire OAuth2 tokens, validate credentials, discover SObjects, scaffold Ballerina projects, add CDC/Platform Event listeners, build, deploy, and stop the integration service — without exposing a shell command interface.
Prerequisites
Tool | Version | Purpose |
18+ | Run the MCP server | |
| Build and run the generated projects. Exact match recommended — scaffolded projects pin this distribution, and | |
Any | Clone the repo | |
Salesforce org | Any edition | Developer Edition is free — sign up |
You don't need Salesforce credentials yet. The MCP tools walk you through creating a Connected App and getting a refresh token.
Salesforce org setting (if using username-password flow): Setup → Identity → OAuth and OpenID Connect Settings → enable "Allow OAuth Username-Password Flows". This is a one-time 30-second toggle. Not required if using browser OAuth (Path C).
Related MCP server: MCP Salesforce Lite
Setup Ballerina + Salesforce — simple steps
From zero to a running integration. Steps 1–2 are one-time; after that npm run setup does the rest.
1. Install the toolchain
Ballerina
2201.x(Swan Lake) — ballerina.io/downloads (bal versionto check)Node.js 18+
2. One-time Salesforce setup (in your org → Setup)
Create a Connected App — App Manager → New Connected App → enable OAuth:
Callback URL:
https://<your-domain>.my.salesforce.com/services/oauth2/successScopes:
apiandrefresh_token (offline_access)Save, wait 2–10 min, then copy the Consumer Key and Consumer Secret.
Disable Refresh Token Rotation (do this if you'll run the publisher and CDC together) — the Connected App → Manage → Edit Policies → OAuth Policies → uncheck "Enable Refresh Token Rotation" and set Refresh Token Policy = "Refresh token is valid until revoked". With rotation ON, the REST client and the CDC listeners share one refresh token and rotate it out from under each other (
invalid_grant/INVALID_SESSION_ID).Enable Change Data Capture (only for the consumer/event flow) — Setup → Change Data Capture → add the objects you want events for (e.g. Account). Requires Developer/Enterprise/Unlimited/Performance edition.
3. Install + build the MCP server
npm install
npm run build4. Configure and run
cp .env.example .env # fill in Consumer Key/Secret, SF_BASE_URL, and one auth option
chmod 600 .env
npm run setup # token → scaffold → bal build → run (live logs in your terminal)npm run setup obtains a refresh token (refresh token → password → browser OAuth, in that order), scaffolds a Ballerina project under ~/WSO2Integrator/<name>, runs bal build, then launches it in the foreground with live logs (Ctrl+C stops it).
Key .env knobs:
Key | Controls |
| Objects exposed as REST CRUD — the publisher flow (default |
| Objects you receive change events for — the consumer flow. One object = one listener. |
|
|
5. What you get
Publisher (REST API):
GET/POST/PUT/DELETE /<object>backed by the Salesforce connector — e.g.curl http://localhost:9090/accounts.Consumer (CDC): listeners that handle create/update/delete/restore events for your
CDC_OBJECTS.Self-heal: if a token expires, open
http://localhost:9090/auth/reauthonce to reauthorize — no restart.
⚠️ Running the publisher and CDC together requires Refresh Token Rotation OFF (step 2.2). They share one refresh token; with rotation on, each invalidates the other.
Installation
1. Clone or locate the project
# If you already have the project directory:
cd /path/to/wso2-bi-salesforce-mcp-server
# Or clone from source:
git clone <repo-url>
cd wso2-bi-salesforce-mcp-server2. Install dependencies
npm install3. Build the server
npm run buildThis compiles TypeScript to dist/. The entry point is dist/index.js.
4. Verify the build
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node dist/index.jsYou should see a JSON response listing all 20 tools.
Default project paths (auto-detected)
Projects are scaffolded into your WSO2 Integrator workspace by default. No configuration required.
Platform | Default |
macOS / Linux |
|
Windows |
|
If ~/WSO2Integrator doesn't exist, the server will create the project inside it. You can always override the path in any tool that accepts bi_path or project_path.
Adding the MCP to AI clients
Replace /absolute/path/to/wso2-bi-salesforce-mcp-server with the actual path on your machine.
Claude Desktop
Open Claude Desktop → Settings → Developer → Edit Config, or open the config file directly:
# macOS ~/Library/Application Support/Claude/claude_desktop_config.json # Windows %APPDATA%\Claude\claude_desktop_config.jsonAdd the server under
mcpServers:{ "mcpServers": { "ballerina-salesforce": { "command": "node", "args": [ "/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js" ] } } }Restart Claude Desktop. The 20 tools will appear automatically.
Claude Code (CLI)
Claude Code uses dedicated MCP config files, not settings.json. MCP servers never go in settings.json.
Recommended — CLI commands (writes the correct file automatically)
# User scope — available in all your projects (recommended for personal use)
claude mcp add --scope user --transport stdio ballerina-salesforce -- \
node /absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js
# Project scope — shared with your team via .mcp.json at the repo root
claude mcp add --scope project --transport stdio ballerina-salesforce -- \
node /absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.jsVerify:
claude mcp listManual — edit the config files directly
User scope (~/.claude.json — available in all your projects):
{
"mcpServers": {
"ballerina-salesforce": {
"command": "node",
"args": ["/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js"],
"type": "stdio"
}
}
}Project scope (.mcp.json at your project root — commit this to share with your team):
{
"mcpServers": {
"ballerina-salesforce": {
"command": "node",
"args": ["/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js"],
"type": "stdio"
}
}
}Note:
~/.claude/.mcp.jsonis not a valid path. User-scope MCP config lives in~/.claude.json(top-level key). Project-scope config lives in.mcp.jsonat the project root, not inside.claude/.
Cursor
Open Cursor → Settings → Features → MCP (or
Cursor Settings > MCP).Click Add new MCP server.
Fill in:
Name:
ballerina-salesforceType:
stdioCommand:
nodeArgs:
/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js
Or add directly to ~/.cursor/mcp.json:
{
"mcpServers": {
"ballerina-salesforce": {
"command": "node",
"args": [
"/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js"
]
}
}
}Restart Cursor after saving.
Windsurf
Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"ballerina-salesforce": {
"command": "node",
"args": [
"/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js"
]
}
}
}Restart Windsurf after saving.
VS Code
Continue.dev — add to ~/.continue/config.json:
{
"mcpServers": [
{
"name": "ballerina-salesforce",
"command": "node",
"args": [
"/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js"
]
}
]
}GitHub Copilot (VS Code MCP support) — add to VS Code settings.json:
{
"github.copilot.mcp.servers": {
"ballerina-salesforce": {
"command": "node",
"args": [
"/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js"
],
"type": "stdio"
}
}
}Zed
Add to ~/.config/zed/settings.json:
{
"context_servers": {
"ballerina-salesforce": {
"command": {
"path": "node",
"args": [
"/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js"
]
}
}
}
}OpenAI Codex CLI
Codex stores MCP servers in ~/.codex/config.toml (TOML, not JSON). Add a [mcp_servers.<name>] block:
[mcp_servers.ballerina-salesforce]
command = "node"
args = ["/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js"]Or use the CLI (recent Codex versions):
codex mcp add ballerina-salesforce -- node /absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js⚠️ Codex uses
mcp_servers(with an underscore) — every other client in this guide usesmcpServers(camelCase). Restart Codex or start a new session after editing.
Gemini CLI (Google)
Add to ~/.gemini/settings.json:
{
"mcpServers": {
"ballerina-salesforce": {
"command": "node",
"args": [
"/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js"
]
}
}
}Run /mcp inside a Gemini CLI session to confirm the server connected and list its tools.
Cline (VS Code extension)
In VS Code, open the Cline panel → MCP Servers → Configure MCP Servers. That opens cline_mcp_settings.json — add:
{
"mcpServers": {
"ballerina-salesforce": {
"command": "node",
"args": [
"/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js"
]
}
}
}The server appears in Cline's MCP Servers list once saved.
Goose, JetBrains AI Assistant, Warp & others
Any client that speaks MCP over stdio works — point it at node <abs-path>/dist/index.js. For example, Goose uses ~/.config/goose/config.yaml (or goose configure → Add Extension → Command-line Extension):
extensions:
ballerina-salesforce:
type: stdio
cmd: node
args:
- /absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js
enabled: trueFor JetBrains AI Assistant, Warp, and similar tools, use their "Add MCP server" UI with the command/args from the generic client section below.
HTTP mode (any agent)
Run the server as an HTTP endpoint — useful for remote agents, containers, or any client that supports HTTP-based MCP.
TRANSPORT=http PORT=3001 SF_MCP_HTTP_TOKEN=your-secret-token node dist/index.jsMCP endpoint:
http://127.0.0.1:3001/mcpAuth header:
Authorization: Bearer your-secret-tokenHealth check:
http://127.0.0.1:3001/healthz
⚠️ Always set
SF_MCP_HTTP_TOKENin HTTP mode. The server warns on startup if it is missing.
Any MCP-compatible client (generic)
The server uses stdio transport — the standard for local MCP servers.
Command:
nodeArgs:
["/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js"]Transport:
stdioProtocol: JSON-RPC 2.0 over stdin/stdout
One-shot setup script (.env → running service)
Prefer to configure everything once and run a single command, instead of feeding values to the assistant one prompt at a time? Use the .env-driven setup script. It drives the MCP server programmatically through the full pipeline — obtain a refresh token (if needed) → sf_quickstart (validate + scaffold + build) → sf_deploy_project — reusing the exact same tool logic, with no AI in the loop.
The script gets a refresh token three ways, in order of preference:
SF_REFRESH_TOKENin.env— used directly, fully non-interactive.SF_USERNAME+SF_PASSWORD— password flow (needs the org toggle); if it fails, the script automatically falls back to browser OAuth.Neither set (or pass
--browser) — interactive browser OAuth: the script builds the auth URL against your My Domain host, opens your browser, you approve and paste the?code=(or the full redirect URL) back into the terminal, and it exchanges + writesSF_REFRESH_TOKENinto.envso future runs need no browser.
cp .env.example .env # fill in your Salesforce config
chmod 600 .env # it holds secrets
npm run setup # or: ./setup.sh (also installs + builds if needed).env keys (see .env.example for the annotated template):
Key | Required | Description |
| ✅ | Connected App Consumer Key / Secret |
| ✅ | e.g. |
| one of these | Pre-obtained refresh token (works on any org) |
| one of these | Used to auto-obtain a token via the password flow (needs the org toggle) |
| — | Optional; sensible defaults applied |
Flags:
npm run setup -- --browser— force the interactive browser OAuth flow (skip token/password).npm run setup -- --no-deploy— stop after build; start it yourself later.npm run setup -- --no-build— scaffold only, skipbal build.
Auth tips: the SF_REFRESH_TOKEN path works on any org. The password path is fully hands-off but needs Setup → Identity → OAuth and OpenID Connect Settings → Allow OAuth Username-Password Flows enabled — if it isn't, the script falls back to browser OAuth automatically. The browser path also works on any org (no toggle), and after the first run your token is saved to .env so it's non-interactive thereafter.
The MCP server stays useful after this for conversational, iterative work — adding objects, CDC listeners, inspecting schemas. The script just automates the initial end-to-end setup.
Usage guide
Once configured, interact with the tools through your AI assistant using natural language. The assistant calls the correct tools automatically.
Quick start (one command)
The fastest path if you already have a Salesforce refresh token:
"Set up a Ballerina Salesforce integration. Client ID: 3MVG9..., Secret: ..., Refresh token: 5Aep..., Base URL: https://myorg.my.salesforce.com"This single phrase triggers sf_quickstart, which:
Validates your credentials with a live Salesforce API call
Auto-detects sandbox vs production from the URL
Scaffolds a complete Ballerina project at
~/WSO2Integrator/salesforce_integration/Writes
Config.tomlwith mode 0600 (owner read/write only)Returns the project path and ready-to-run instructions
Say "Also compile it" to add build: true and verify the project compiles immediately.
Starting from zero (full walkthrough)
If you don't have credentials yet, the assistant walks you through the full setup.
Step 1 — Get the setup guide:
"Show me the Salesforce setup guide"
"I'm new to Salesforce — where do I start?"
"What do I need to set up a Ballerina Salesforce integration?"Step 2 — Create a Connected App (3 min, manual in Salesforce):
The guide returned by
sf_setup_guidegives you the exact steps. In short:
Salesforce → Setup → App Manager → New Connected App
Enable OAuth: scopes
api+refresh_token (offline_access), callbackhttps://login.salesforce.com/services/oauth2/successSave → copy Consumer Key and Consumer Secret
Wait 2–10 min for the app to activate
Step 3 — Check prerequisites:
"Check if Ballerina is installed"
"Are my prerequisites met?"Step 4 — Get an OAuth refresh token:
"Get me an OAuth URL for client ID 3MVG9..."Open the returned URL in a browser, approve access, copy the ?code= value from the redirect URL, then:
"Exchange this OAuth code: aPrx..."Save the returned refresh_token and instance_url.
Step 5 — Scaffold and run:
"Set up a Salesforce integration for my org. Client ID: 3MVG9..., Secret: ..., Refresh token: 5Aep..., Base URL: https://myorg.my.salesforce.com"Step 6 — Deploy:
"Start the integration service"
"Deploy the Salesforce project"Step 7 — Stop when done:
"Stop the integration service"Example prompts
"Show me the Salesforce integration setup guide."
"Check if Ballerina is installed and ready."
"Get me an OAuth authorization URL for client ID 3MVG9... — this is a sandbox org."
"Exchange this code: aPrxQ7... and give me the refresh token."
"Validate my Salesforce connection — client ID 3MVG9..., secret ..., token 5Aep..., URL https://myorg.my.salesforce.com"
"List all custom objects in my Salesforce org."
"Describe the Invoice__c object fields."
"Set up a Ballerina Salesforce integration project with my credentials."
"Set up the project and also include Account CDC listeners so I get notified of Account changes."
"Add a listener for the OrderConfirmed__e platform event to my existing project."
"Add the Product2 object to my existing Salesforce integration project."
"Add the My_Custom__c object to my project — here are my credentials."
"Build my Salesforce integration project and show me any errors."
"Start the Salesforce service on port 8080."
"Update Config.toml in my project with these new credentials — my token was rotated."
"Stop the Salesforce integration service."Quick Start Prompts
Copy one of these into your AI agent (Claude Desktop, Claude Code, Cursor, etc.) to go from zero to a running integration in one conversation.
⚠️ One-time Salesforce admin step required for Path A and Path B (takes 30 seconds): Paths A and B use the Salesforce username-password OAuth flow, which is disabled by default since Salesforce Spring '22. Before running either path, enable it once in your org: Salesforce Setup → Identity → OAuth and OpenID Connect Settings → ✅ Allow OAuth Username-Password Flows
If you cannot enable this (enterprise org policy), use Path C (browser OAuth) instead — it has no such restriction.
🆕 Path A — First-time setup
Use this when you have Salesforce credentials but no existing Postman collection. The agent will generate a credential wallet, scaffold the Ballerina project, and start the service.
Set up a complete Ballerina + Salesforce integration for me.
My Salesforce details:
- Client ID: <consumer_key>
- Client Secret: <consumer_secret>
- Base URL: https://myorg.my.salesforce.com
- Username: me@myorg.com
- Password: myPasswordSecurityToken
(if your org uses a security token, append it to the password: myPasswordABC123)
Steps I want you to do:
1. Check prerequisites (bal CLI installed and version matches)
2. Generate a Postman collection and save it as my credential wallet
3. Use the returned credentials to run sf_quickstart (scaffold + build the project)
4. Deploy the service and tell me the PID and port💡 After step 2 you'll have a
~/WSO2Integrator/Salesforce Integration.postman_collection.jsonfile. Keep it — it's your credential wallet for future sessions. You can also import it into the Postman app to get fresh access tokens at any time.
🔁 Path B — Returning user (credential wallet already exists)
Use this in any future session after Path A. No credentials to type — the agent reads everything from the saved file.
Set up my Ballerina + Salesforce integration.
My credential wallet is at ~/WSO2Integrator/Salesforce Integration.postman_collection.json
Steps:
1. Import credentials from that Postman file
2. Run sf_quickstart with the extracted credentials
3. Deploy the service and give me the PID and port🌐 Path C — Browser OAuth (no password flow)
Use this if your org has the username-password flow disabled (common in enterprise orgs).
Set up my Ballerina + Salesforce integration using browser OAuth.
My Salesforce details:
- Client ID: <consumer_key>
- Client Secret: <consumer_secret>
- Base URL: https://myorg.my.salesforce.com
Steps:
1. Check prerequisites
2. Give me the OAuth authorization URL to open in my browser
3. After I paste back the auth code, exchange it for a refresh token
4. Run sf_quickstart to scaffold and build the project
5. Deploy the serviceStep-by-step workflow
Fastest path — generate a Postman collection (first-time setup):
1. sf_generate_postman_collection → give credentials once, auto-obtain token, save to ~/WSO2Integrator/*.postman_collection.json
2. sf_quickstart → validate + scaffold + (optional) build (ready_for_quickstart returned above)
3. sf_deploy_project → start the service
4. sf_stop_project → stop the service when doneFastest path — already have a Postman collection?
1. sf_import_postman_credentials → extract all credentials from .postman_collection.json
(if token expired) sf_get_token_password_flow → get fresh token, no browser needed
2. sf_quickstart → validate + scaffold + (optional) build
3. sf_deploy_project → start the service
4. sf_stop_project → stop the service when doneStarting from scratch (browser OAuth):
1. sf_setup_guide → first-time guide: Connected App setup, credential steps
2. sf_check_prerequisites → verify bal CLI version + platform info
3. sf_get_oauth_auth_url → generate authorization URL (open in browser)
4. sf_exchange_oauth_code → trade the ?code= for a refresh_token
5. sf_quickstart → validate + scaffold + (optional) build ← one call does it all
6. sf_deploy_project → start the service in the background
7. sf_stop_project → stop the service when doneStarting from scratch (no browser — username + password):
1. sf_check_prerequisites → verify Ballerina is installed
2. sf_get_token_password_flow → username+password → refresh_token (no browser)
3. sf_quickstart → validate + scaffold + build
4. sf_deploy_project → start the service
5. sf_stop_project → stop the service when doneOr broken out manually:
1. sf_setup_guide → read the setup instructions
2. sf_check_prerequisites → verify Ballerina is installed
3. sf_get_oauth_auth_url → get the auth URL
4. sf_exchange_oauth_code → exchange code → refresh_token
5. sf_validate_connection → confirm credentials work
6. sf_list_sobjects → discover SObjects in the org
7. sf_describe_sobject → inspect field metadata for a specific object
8. sf_scaffold_project → generate the Ballerina project
9. sf_build_project → compile with bal build
10. sf_deploy_project → start the service
11. sf_stop_project → stop the service when doneTool reference
Onboarding
sf_setup_guide
Returns a step-by-step guide for first-time users: how to create a Salesforce Connected App, obtain credentials, and which tools to call in order. Call this at the start of any Salesforce integration session.
"Show me the Salesforce setup guide"
"I've never set up a Salesforce Connected App — walk me through it"
"What scopes do I need for the Connected App?"Parameter | Type | Default | Description |
| boolean |
| Show sandbox (test.salesforce.com) variant |
sf_check_prerequisites
Verifies the bal CLI is installed and reports its version vs. the expected Ballerina distribution.
"Check if Ballerina is installed"
"Are my prerequisites met for the Salesforce integration?"
"What version of Ballerina do I have?"No parameters. Returns: bal_cli.available, bal_cli.version, bal_cli.expected_distribution, bal_cli.version_match (and bal_cli.version_warning when the installed distribution doesn't match 2201.12.0), node_version, platform, recommended_action.
OAuth2 authentication
sf_get_oauth_auth_url
Generates a Salesforce OAuth2 authorization URL. Open it in a browser to approve access — you receive a ?code= query parameter in the redirect URL.
The generated URL has the form:
https://<your-instance>/services/oauth2/authorize?response_type=code&client_id=<CONSUMER_KEY>&redirect_uri=<REDIRECT_URI>&scope=api%20refresh_token%20offline_accessPass sf_base_url (your org / My Domain URL) so the authorize endpoint targets your org's own host — e.g. https://myorg.my.salesforce.com/services/oauth2/authorize. This is the correct host for My Domain orgs and avoids "log in via your My Domain" redirects. If you omit sf_base_url, the URL falls back to login.salesforce.com (or test.salesforce.com when sandbox: true). The scope=api refresh_token offline_access is always included — offline_access is what makes Salesforce return a refresh token.
"Get me an OAuth URL for client ID 3MVG9... — my org is https://myorg.my.salesforce.com"
"Generate a Salesforce authorization URL — this is a sandbox"Parameter | Type | Default | Description |
| string | required | Consumer Key from your Connected App |
| string | — | Recommended. Org / My Domain URL. When set, the authorize URL (and the default redirect) use this host. |
| string |
| Must match a callback registered in your Connected App. When |
| boolean |
| Use |
Returns: auth_url (open this in a browser), redirect_uri (the one actually used — pass the same to sf_exchange_oauth_code), next_step.
sf_exchange_oauth_code
Exchanges the ?code= from the redirect URL for a long-lived refresh token.
The short-lived
access_tokenis intentionally masked in output — it's shown asaccess_token_previewonly. You never need it directly; the other tools refresh automatically on demand.
"Exchange this OAuth code: aPrxQ7..."
"I got the code from the redirect URL — exchange it for a refresh token"Parameter | Type | Default | Description |
| string | required | Consumer Key |
| string | required | Consumer Secret |
| string | required | The |
| string | success URL | Same URI used in |
| boolean |
| Must match where the code was obtained |
Returns: refresh_token (save this!), instance_url (use as sf_base_url in all other tools).
Common errors:
AUTH_INVALID_GRANT— code expired or already used; re-runsf_get_oauth_auth_urlAUTH_CONNECTED_APP_NOT_READY— wait 2–10 min after creating the Connected App
Validation & discovery
sf_validate_connection
Makes a live Salesforce API call to confirm credentials work before writing any files to disk.
"Validate my Salesforce connection"
"Test that my credentials work"Parameter | Type | Description |
| string | Consumer Key |
| string | Consumer Secret |
| string | Refresh token |
| string | e.g. |
Returns: connected, org_id, username, instance_url, is_sandbox.
sf_list_sobjects
Lists all SObjects in your org. Supports filtering and pagination.
"List all custom objects in my Salesforce org"
"Show me all Account-related SObjects"
"What objects are available in my org?"Parameter | Type | Default | Description |
credentials | — | required | All 4 credential fields |
| boolean |
| Include |
| string | — | Substring filter on name or label |
| integer |
| Max results (1–200) |
| integer |
| Pagination offset |
Returns: total, count, has_more, next_offset, sobjects[].
sf_describe_sobject
Returns full field metadata for a specific SObject — field names, types, nullability, and relationship references.
"Describe the Invoice__c object"
"What fields does the Account object have?"
"Show me the schema for My_Custom__c"Parameter | Type | Description |
credentials | — | All 4 credential fields |
| string | SObject API name, e.g. |
Returns: name, label, field_count, fields[] with full type info.
Project scaffolding
sf_quickstart ⭐ Start here
One-shot setup: validates credentials → auto-detects sandbox → scaffolds the Ballerina project → (optional) compiles.
This is the recommended entry point. Most users only need this one tool after exchanging their OAuth code.
"Set up a Ballerina Salesforce project with my credentials"
"Scaffold the Salesforce integration and compile it to check for errors"
"Set up the integration and also add Account and Contact CDC listeners"Parameter | Type | Default | Description |
| string | required | Consumer Key |
| string | required | Consumer Secret |
| string | required | Refresh token |
| string | required | e.g. |
| string |
| Ballerina package name |
| string |
| Ballerina org name in |
| string |
| WSO2 BI workspace root |
| string[] |
| SObject API names to scaffold CRUD for |
| array | — | CDC / Platform Event listeners to add (see below) |
| boolean |
| Run |
| boolean | auto-detected | Override sandbox detection (detected from URL by default) |
cdc_listeners entry — specify exactly one of:
Field | Type | Channel generated |
| string |
|
| boolean |
|
| string (ends |
|
| string[] | Which callbacks: |
Returns: status, connection, project_path, files_created, standard_sobjects, custom_sobjects, cdc_channels, ballerina_version, next_steps.
sf_scaffold_project
Granular alternative to sf_quickstart — scaffolds without the live credential validation step. Accepts the same parameters as sf_quickstart except build.
"Scaffold a Salesforce project — I've already validated my credentials"
"Create the project files for Account, Contact, and Invoice__c"Project management
sf_write_config_toml
Overwrites Config.toml in an existing project with new credentials. Use this after token rotation without re-scaffolding the whole project.
Written with mode 0600 (owner read/write only). Sandbox is auto-detected from sf_base_url.
"Update the credentials in my existing project — my token was rotated"
"Rewrite Config.toml with these new values"Parameter | Type | Description |
| string | Path to the existing Ballerina project |
credentials | — | All 4 credential fields |
sf_add_custom_object
Adds a new SObject to an already-scaffolded project without re-scaffolding everything.
Standard SObjects: creates
<object>.balreferencing the pre-built type fromballerinax/salesforce.types— nodescribeAPI call needed.Custom (
__c) objects: describes the schema live, appends a typed record totypes.bal, and creates<object>.bal.
Returns: files_updated[], manual_step (route snippet to paste into main.bal).
"Add the Product2 object to my existing project"
"Add Invoice__c to the project — here are my credentials"
"I need to support Asset in addition to what's already scaffolded"Parameter | Type | Description |
| string | Path to the existing project |
credentials | — | Required only for custom ( |
| string | SObject API name, e.g. |
sf_add_cdc_listener
Adds an event-driven listener file to an existing project. Generates a .bal file with handler stubs using the same OAuth2 credentials already in main.bal — no extra Config.toml entries needed.
"Add a CDC listener for Account changes to my project"
"Listen for all CDC-enabled object changes"
"Add a platform event listener for OrderConfirmed__e"
"Add an Account listener but only scaffold onCreate and onUpdate"Parameter | Type | Description |
| string | Path to the existing project |
| string | SObject name → channel |
| boolean | All objects → channel |
| string (ends | Platform event → channel |
| string[] | CDC callbacks to scaffold (default: all four) |
Specify exactly one of
sobject,all_changes, orplatform_event.
⚠️ CDC requires a Salesforce admin step: Setup → Integrations → Change Data Capture → enable objects. The MCP server generates the Ballerina code but cannot enable CDC in Salesforce itself.
Build & run
sf_build_project
Runs bal build in the project directory. Takes 30–90s on first build (downloads the connector from Ballerina Central). Reports the full compiler output.
"Build my Salesforce project"
"Compile the integration and show me any errors"
"Run bal build and check if everything is OK"Parameter | Type | Description |
| string | Path to the Ballerina project |
Returns: success, output (full compiler output), project_path.
sf_deploy_project
Starts the Ballerina service in the background via bal run. Waits up to 90 seconds for the HTTP listener banner (a cold bal run compiles before serving, which can take 30–120s). Ports are passed as configurable overrides so the reported service_url always matches the actual listener. The tool only reports an error if the process actually exits — a slow cold start is not treated as failure.
"Start the Salesforce integration service"
"Deploy the project on port 8080"
"Run the Ballerina service and give me the PID"Parameter | Type | Default | Description |
| string | required | Path to the project |
| integer |
| HTTP listener port |
Returns: pid (save this for sf_stop_project), started, service_url, health_check, output, message.
Endpoints once running:
Method | Path | Description |
|
| Health check — returns |
|
| Query all records (SOQL, LIMIT 200) |
|
| Get a single record by Salesforce ID |
|
| Create a record |
|
| Update a record |
|
| Delete a record |
sf_stop_project
Stops a service started by sf_deploy_project. Only PIDs registered by this MCP server session can be stopped — it will not kill arbitrary system processes.
"Stop the Salesforce service"
"Kill the integration process with PID 12345"Parameter | Type | Description |
| integer | PID returned by |
Postman & password-flow (no browser needed)
sf_generate_postman_collection ⭐ Generate a credential wallet
Takes your Salesforce credentials once, auto-obtains a refresh token via the password flow, and saves a ready-to-import Postman Collection v2.1 to disk. That single file becomes your reusable credential wallet:
Use in Postman — import and click "Get New Access Token" at any time, no configuration needed.
Use with this MCP — pass the saved file to
sf_import_postman_credentialsin any future session. No copy-pasting, no browser flows, no repeated auth setup.
The generated collection includes three folders:
🔐 Authentication — Password Flow (no browser), Step 1-2 auth-code flow, and Token Refresh requests with auto-save test scripts
🔍 Salesforce REST API — Validate Connection, List SObjects, Describe Account, SOQL Query, Create Account
🔗 Ballerina Integration Service — Health Check, List/Create Accounts via the local Ballerina service
"Generate a Postman collection for my Salesforce org"
"Create a Salesforce Postman collection and save my credentials"
"Set up Postman for my Salesforce integration — username is me@myorg.com"Parameter | Type | Default | Description |
| string | required | Consumer Key from the Connected App |
| string | required | Consumer Secret |
| string | required | e.g. |
| string | required | Salesforce username (email) |
| string | required | Password (append security token if required: |
| string |
| Redirect URI registered in your Connected App |
| string |
| Display name for the Postman collection |
| string |
| Where to save the file |
Returns: collection_saved_to (file path), ready_for_quickstart (use directly with sf_quickstart), refresh_token_obtained (true/false).
One-time Salesforce Setup requirement (same as sf_get_token_password_flow):
Setup → Identity → OAuth and OpenID Connect Settings → enable "Allow OAuth Username-Password Flows"
sf_import_postman_credentials ⭐ Fastest onboarding
Reads a .postman_collection.json file and extracts every Salesforce credential it can find — clientId, clientSecret, refreshToken, instanceUrl, username, password — from the collection-level OAuth2 block and individual request bodies. No copy-pasting required.
Returns a ready_for_quickstart block you can pass directly to sf_quickstart.
If the refresh token is expired, it tells you exactly which tool to call next (sf_get_token_password_flow).
"Import credentials from my Postman collection at ~/Documents/MCP-servers/wso2-bi-salesforce-mcp-server/_BalSFConnector.postman_collection.json"
"Read my Postman collection and set up the integration"
"Extract Salesforce credentials from ~/Downloads/MyOrg.postman_collection.json and validate them"Parameter | Type | Default | Description |
| string | required | Absolute or |
| boolean |
| Make a live Salesforce API call to confirm extracted credentials work |
Returns: credentials_found (secrets masked), ready_for_quickstart block, password_flow_args (if username+password present but no refresh token), next_action guidance.
What it extracts from the Postman file:
Postman location | Fields extracted |
Collection |
|
Request body (urlencoded) |
|
Request URL (query params) |
|
sf_get_token_password_flow
Gets a Salesforce OAuth2 refresh token using username + password only — no browser, no auth code redirect.
"Get a Salesforce refresh token using my username and password — no browser"
"Use the username/password from my Postman collection to get a refresh token"Parameter | Type | Description |
| string | Consumer Key from the Connected App |
| string | Consumer Secret |
| string | Salesforce username (email) |
| string | Password. If your org uses a security token, append it directly: |
| string | e.g. |
Returns: refresh_token, instance_url, ready_for_quickstart block.
One-time Salesforce Setup requirement (30 seconds):
Setup → Identity → OAuth and OpenID Connect Settings → enable "Allow OAuth Username-Password Flows"
Common errors:
Error | Cause | Fix |
| Wrong password or missing security token | Append security token to password |
| Wrong | Check the Connected App's Consumer Key/Secret |
| Username-password flow not enabled | Enable it in Setup → Identity → OAuth and OpenID Connect Settings |
No | Connected App missing | Add "Perform requests at any time (refresh_token, offline_access)" scope |
Generated project structure
~/WSO2Integrator/salesforce_integration/
├── Ballerina.toml # Package: ballerinax/salesforce@8.7.0, dist 2201.12.0
├── Config.toml # Mode 0600, gitignored — credentials + port
├── .gitignore # Excludes Config.toml, target/, .ballerina/, Dependencies.toml
├── main.bal # HTTP service + salesforce:Client + configurable vars
├── types.bal # Custom __c typed records (empty if no custom objects)
├── account.bal # Account CRUD: query, getById, create, update, delete
├── contact.bal # Contact CRUD
├── lead.bal # Lead CRUD
├── opportunity.bal # Opportunity CRUD
├── cdc_account.bal # (if requested) CDC listener for Account changes
├── event_order__e.bal # (if requested) Platform event listener for Order__e
└── README.md # Auto-generated project usage docsStandard vs custom SObjects
SObject type | Record type source | Describe API call? | Entry in types.bal? |
Standard ( |
| ❌ No | ❌ No |
Custom ( | Generated from live describe | ✅ Yes | ✅ Yes |
Using pre-built types means standard SObjects need zero describe calls during scaffolding — the project generates in seconds regardless of how many standard objects you include.
Credentials & environment variables for the generated project are documented in detail in the Configuration section below.
Sample project
A complete, runnable reference project is included at examples/sample_salesforce_integration/. It demonstrates both integration flows with production-quality error handling:
examples/sample_salesforce_integration/
├── Ballerina.toml # connector v8.7.0, dist 2201.12.0
├── Config.toml.example # copy to Config.toml and fill in your credentials
├── .gitignore
├── main.bal # HTTP service + shared salesforce:Client
├── account.bal # Account CRUD with error classification + retry
├── cdc_account.bal # CDC consumer flow (/data/AccountChangeEvent)
├── event_sample.bal # Platform event consumer flow (/event/Sample_Event__e)
├── errors.bal # Typed errors, retry helper, HTTP status mapping
└── README.md # Run instructions, curl examples, troubleshootingPublishing flow — POST /accounts → sfClient->create(), GET /accounts/{id} → sfClient->getById(), etc.
Consuming flow — salesforce:Listener on /data/AccountChangeEvent with onCreate, onUpdate, onDelete, onRestore stubs, and a separate listener on /event/Sample_Event__e with onMessage.
Error handling — typed errors (RecordNotFound, ValidationFailed, DuplicateRecord, AuthFailed), HTTP status mapping (404/400/409/502/500), withRetry with exponential back-off for transient Salesforce errors (REQUEST_LIMIT_EXCEEDED, etc.).
cd examples/sample_salesforce_integration
cp Config.toml.example Config.toml
# fill in credentials
bal runMCP server project structure
wso2-bi-salesforce-mcp-server/
├── src/
│ ├── index.ts # Entry point — server factory, stdio + HTTP transports
│ ├── types.ts # Shared TypeScript types, ToolError, error codes, maskSecret
│ ├── constants.ts # SF constants, URL validation, sandbox detection, versions
│ ├── schemas/
│ │ └── tools.ts # Zod schemas for all 20 tool inputs
│ ├── services/
│ │ ├── salesforce.ts # Token management, SObject describe/list, validateConnection
│ │ ├── filesystem.ts # writeFile, balBuild, balRun, checkBalCli, expandPath
│ │ └── generator.ts # Ballerina code generators (main.bal, types.bal, CDC listeners)
│ └── tools/
│ ├── oauth.ts # sf_get_oauth_auth_url, sf_exchange_oauth_code
│ ├── salesforce.ts # sf_setup_guide, sf_check_prerequisites, sf_validate_connection,
│ │ # sf_list_sobjects, sf_describe_sobject
│ ├── ballerina.ts # sf_quickstart, sf_scaffold_project, sf_write_config_toml,
│ │ # sf_add_custom_object, sf_add_cdc_listener,
│ │ # sf_build_project, sf_deploy_project, sf_stop_project
│ └── postman.ts # sf_generate_postman_collection, sf_import_postman_credentials, sf_get_token_password_flow
├── examples/
│ └── sample_salesforce_integration/ # Complete runnable reference project
├── dist/ # Compiled JavaScript (git-ignored)
├── package.json
├── tsconfig.json
└── README.mdConfiguration
There are two distinct layers of configuration: (1) the MCP server itself (how the Node process runs) and (2) the generated Ballerina project (how the integration authenticates to Salesforce at runtime). They're separate — you rarely touch the server config, while the project config is written for you by the tools.
1. MCP server — environment variables
Set these on the node dist/index.js process (e.g. in your MCP client config's env block, or your shell). All are optional.
Variable | Default | Description |
|
| Transport mode: |
|
| HTTP listener port — HTTP mode only. |
| — | Bearer token required on all |
|
| Absolute path to the |
|
| Colon-separated extra directories that |
Example — pinning a bal binary and an extra project root in a Claude Desktop config:
{
"mcpServers": {
"ballerina-salesforce": {
"command": "node",
"args": ["/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js"],
"env": {
"BAL_BIN": "/Users/me/.ballerina/bin/bal",
"SF_MCP_ALLOWED_ROOTS": "/data/projects"
}
}
}
}2. Generated project — Config.toml
Every scaffolded project gets a Config.toml in its root, written with mode 0600 (owner read/write only) and git-ignored. The MCP tools populate it for you — this reference is for when you want to edit or rotate it by hand. Each key maps to a configurable variable in main.bal.
Key | Type | Example | Description |
| string |
| Connected App Consumer Key. |
| string |
| Connected App Consumer Secret. |
| string |
| Long-lived OAuth2 refresh token. The connector mints short-lived access tokens from this at runtime. |
| string |
| Token endpoint. Auto-set to |
| string |
| Your org instance URL. |
| string |
| Salesforce REST API version the connector targets. |
| int |
| HTTP listener port for the generated service. |
To rotate credentials without re-scaffolding, prefer the
sf_write_config_tomltool — it re-writes the file with mode0600and re-detects sandbox vs. production for you.
Runtime credential sources (precedence)
main.bal reads each credential from Config.toml first, falling back to an environment variable if the file value is absent. The same project therefore runs unchanged across environments:
Environment | How credentials are supplied |
Local dev |
|
Docker / WSO2 BI runtime | Env vars: |
CI | Either — |
The port can also be overridden at launch without editing the file:
bal run -CservicePort=8080(this is exactly whatsf_deploy_projectdoes with itsportparameter).
Development
# Rebuild after changes
npm run build
# Watch mode (recompiles on save)
npm run dev
# Clean and rebuild
rm -rf dist && npm run buildTo add a new tool:
Add the Zod schema to
src/schemas/tools.tsAdd the handler in the appropriate file under
src/tools/Register it with
server.registerTool(...)in that file's register functionRun
npm run build
Security
Credential protection
Hostname allow-list:
sf_base_urlis validated against*.salesforce.com,*.force.com,*.cloudforce.com, and*.salesforce-setup.combefore any credential is sent. Arbitrary URLs are rejected — prevents SSRF and credential exfiltration.Config.tomlwritten with mode0600: Only the owning user can read it. Enforced on every write including credential rotation.Token masking:
sf_exchange_oauth_codemasks the short-livedaccess_tokenin its output. Only therefresh_tokenis shown (it's the one you need to save).
Path safety
All user-supplied paths (
project_path,bi_path) are resolved and verified to lie under$HOMEor$TMPDIR. Path traversal attempts (../../etc/passwd) throwPATH_TRAVERSALimmediately.
Process safety
sf_deploy_projectregisters spawned PIDs in-process.sf_stop_projectonly terminates PIDs it started — it refuses to kill arbitrary system processes.
HTTP transport
Binds to
127.0.0.1only — no external exposure by default.Set
SF_MCP_HTTP_TOKENto requireAuthorization: Bearer <token>on every/mcprequest./healthzis always unauthenticated (returns server name and version only).
Structured error codes
Every tool error returns a machine-readable code field so agents can handle failures precisely:
Code | Meaning |
| Refresh token revoked or wrong endpoint (production vs sandbox) |
| New Connected App still activating — wait 2–10 min |
| Wrong Consumer Key or Secret |
|
|
| Path resolves outside allowed roots |
| Project directory or file not found |
| Project or module file already exists |
|
|
| Compilation failed — see |
| Required file missing (e.g. |
| Network error — check connectivity and retry |
| Validation error (e.g. invalid SObject name format) |
| Unexpected error |
Troubleshooting
AUTH_CONNECTED_APP_NOT_READY on first use
Salesforce Connected Apps take 2–10 minutes to activate after creation. Wait and retry sf_exchange_oauth_code or sf_validate_connection.
bal not found
which bal # should print a path like /usr/local/bin/bal
bal version # should print Ballerina 2201.12.0 (Swan Lake)If missing, install from ballerina.io/downloads. If bal is installed but not on PATH:
BAL_BIN=/path/to/bal node dist/index.jsFirst bal build is slow
The first build downloads ballerinax/salesforce@8.7.0 from Ballerina Central. Ensure you have internet access and allow up to 3 minutes. Subsequent builds use the local cache.
CDC events not arriving
Enable CDC for the object: Salesforce Setup → Integrations → Change Data Capture → select your object → Save.
CDC requires Enterprise, Unlimited, Performance, or Developer Edition.
Ensure OAuth scopes include
apiandrefresh_token.
Platform event listener fails to start
The channel /event/YourEvent__e must exist in your org before the listener can attach. Create the Platform Event in Salesforce Setup → Platform Events.
Service starts but /health returns connection refused
The 90-second startup window elapsed before the listener banner was detected — a cold bal run compiles before serving. The service may still be starting; wait a few more seconds and retry. Check the output field in the sf_deploy_project result for compiler or bind errors.
PATH_TRAVERSAL error
Your project_path or bi_path resolves outside $HOME or $TMPDIR. Use a path inside your home directory, or run with extra roots:
SF_MCP_ALLOWED_ROOTS=/data/projects node dist/index.jsToken expired mid-session
Access tokens are short-lived (~2 hours). The connector refreshes them automatically using the stored refresh_token. If you see INVALID_SESSION_ID errors, the refresh token itself may have been revoked — re-run sf_get_oauth_auth_url and sf_exchange_oauth_code to get a new one, then call sf_write_config_toml to update the project without re-scaffolding.
Available Tools
18 toolssf_add_cdc_listenerAdd a Salesforce CDC or Platform-Event ListenerA
Adds an event-driven listener to an existing scaffolded project.
A Salesforce listener can subscribe to:
Object CDC: /data/ChangeEvent (set 'sobject')
All CDC events: /data/ChangeEvents (set 'all_changes': true)
Platform events: /event/__e (set 'platform_event')
CDC listeners get onCreate/onUpdate/onDelete/onRestore stubs (you can narrow this via 'events'). Platform-event listeners get onMessage.
The listener reuses the OAuth2 credentials already configured in main.bal — no extra Config.toml entries required.
| Name | Required | Description | Default |
|---|---|---|---|
| project_path | Yes | Path to the existing Ballerina project | |
| listener | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses behavioral traits such as reusing existing OAuth2 credentials and the stubs generated for different listener types. However, it does not discuss side effects like project file modifications, mutability, or idempotency beyond the annotations (which are neutral). More detail on what changes are made could improve transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, using bullet points for clarity, and front-loaded with the main purpose. Every sentence adds value without redundancy. Efficient for an AI agent to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (nested object parameter) and lack of output schema, the description sufficiently covers the three subscription modes, events behavior, and credential reuse. It could be more complete by mentioning prerequisites or error scenarios, but it provides adequate context for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds meaning beyond the input schema by explaining the channel names for each listener type (e.g., /data/AccountChangeEvent) and that the 'events' parameter is ignored for platform events. This enriches the schema's descriptions, which already cover each parameter. The description compensates for the 50% schema description coverage by providing contextual semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool adds an event-driven listener to an existing scaffolded project, with specific verb 'adds' and resource 'listener'. It distinguishes from sibling tools like sf_scaffold_project and sf_build_project by focusing on adding a listener to an already scaffolded project.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for existing scaffolded projects and explains the three subscription modes, but does not provide explicit guidance on when to use this tool vs alternatives or when not to use it. No exclusions or conditional contexts are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_add_custom_objectAdd a Salesforce SObject to an Existing Ballerina ProjectA
Adds a new SObject to an already-scaffolded project. For standard SObjects: creates a .bal file that uses the pre-built type from ballerinax/salesforce.types (no types.bal change needed). For custom (__c) objects: also appends a typed record to types.bal.
Returns the resource-route snippet to paste into main.bal.
| Name | Required | Description | Default |
|---|---|---|---|
| project_path | Yes | Path to the existing Ballerina project | |
| sf_client_id | Yes | Salesforce Connected App Consumer Key (Client ID) | |
| sf_client_secret | Yes | Salesforce Connected App Consumer Secret (Client Secret) | |
| sf_refresh_token | Yes | Salesforce OAuth2 Refresh Token obtained after authorization | |
| sf_base_url | Yes | Salesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname) | |
| object_name | Yes | SObject API name to add, e.g. 'My_Custom__c' |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses different behaviors for standard vs custom objects (appending to types.bal) and the return value, beyond what annotations provide. However, it does not mention error conditions, duplicate handling, or verification steps, though annotations already indicate non-destructive and open-world nature.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no unnecessary words, front-loaded with the core action, and efficiently covers the key distinction and output.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description explains the purpose and output (resource-route snippet) but lacks detail on error scenarios, prerequisites (e.g., scaffolded project, valid Salesforce connection), and exact file locations. Given the complexity of 6 required parameters and file modification, it is moderately complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers all 6 parameters with descriptions; the tool description adds only marginal context (e.g., 'already-scaffolded' relating to project_path). With 100% schema coverage, baseline is 3 and the description provides no additional parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Adds a new SObject' and clearly identifies the context 'to an already-scaffolded project'. It distinguishes between standard and custom objects with distinct behaviors, and uniquely defines the tool among siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage after project scaffolding but does not explicitly state prerequisites, exclusions, or alternatives. It lacks guidance on when not to use this tool, such as when the project is not yet scaffolded or when a different operation (e.g., describing an SObject) is more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_build_projectBuild Ballerina ProjectAIdempotent
Runs 'bal build' inside the project directory and reports the result.
| Name | Required | Description | Default |
|---|---|---|---|
| project_path | Yes | Path to the Ballerina project to build |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide idempotentHint=true, and description adds that it 'reports the result,' which clarifies output. However, description does not disclose potential side effects like file generation (e.g., target directory) or what exactly the result contains (e.g., success/failure, logs). With annotations covering safety, the description adds minimal context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, no waste. All information is front-loaded and succinct. Every word serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple build tool with one parameter and no output schema, the description covers the main action but omits details on failure handling, return value format, or any subsequent steps. Could be more helpful with brief mention of typical output structure.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and parameter 'project_path' has a clear description. The tool description does not add any additional meaning beyond the schema, so baseline of 3 is appropriate. No extra info on format, constraints, or examples.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool runs 'bal build' on a project directory and reports the result. It distinguishes from sibling tools like 'sf_deploy_project' (deploying) and 'sf_scaffold_project' (scaffolding), providing a specific verb-resource combination.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., project must have been scaffolded), expected state before building, or when other tools like 'sf_deploy_project' would be more appropriate. Lacks explicit when-not-to-use or alternative references.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_check_prerequisitesCheck Prerequisites (Ballerina CLI)ARead-onlyIdempotent
Verifies that the 'bal' CLI is installed and reports its version. Run this first to catch missing prerequisites before scaffolding.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds context beyond annotations: specifies what the tool checks (installation and version) and implies no side effects. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with primary action, no wasted words. Efficient and clear.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with no output schema, the description covers the main purpose. Slightly incomplete about error behavior if CLI missing, but still adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters exist; baseline of 4 applies as description does not need to explain parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description uses specific verb 'Verifies' and identifies exact resource 'bal CLI installed and version'. Clearly distinguishes from sibling tools which focus on Salesforce operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises to run this first before scaffolding, providing clear usage context. No mention of when not to use, but the guidance is direct.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_deploy_projectDeploy and Run Ballerina Project on WSO2 Integrator RuntimeA
Starts the Ballerina service in the background via 'bal run'. The port is passed through as a Ballerina configurable override so the reported service_url matches the actual listener.
Returns started=true when the listener has actually come up, plus a PID you can pass to sf_stop_project to terminate the service later.
| Name | Required | Description | Default |
|---|---|---|---|
| project_path | Yes | Path to the Ballerina project to deploy | |
| port | No | HTTP listener port (default: 9090) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and destructiveHint=false, providing baseline safety info. The description adds that the service runs in the background, returns a PID for later stop via sf_stop_project, and waits for the listener to come up. This adds behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: first states action, second explains port handling, third describes return values. Front-loaded with key information. No redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given tool complexity (2 params, no output schema), the description adequately covers purpose, outcome (started=true, PID), and linkage to stop tool. It could mention error states or prerequisites, but overall complete for its scope.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema already describes both parameters (project_path, port) with descriptions and constraints, achieving 100% coverage. The description adds that the port is passed as a configurable override and that service_url matches the listener, enhancing understanding beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool starts a Ballerina service via 'bal run', passes a port, and returns started=true and a PID. It distinguishes from siblings like sf_build_project (build only) and sf_stop_project (stop).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance on when to use this tool vs alternatives, but the context signals show siblings like sf_build_project and sf_stop_project, and the description implies use after building. However, it lacks explicit when-not-to-use or alternative tool mentions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_describe_sobjectDescribe a Salesforce SObjectARead-onlyIdempotent
Returns full field-level metadata for a specific SObject. Use this to inspect available fields, their types, and relationships before generating typed Ballerina record definitions.
Errors:
"NOT_FOUND": Object does not exist or is not accessible to this user
| Name | Required | Description | Default |
|---|---|---|---|
| sf_client_id | Yes | Salesforce Connected App Consumer Key (Client ID) | |
| sf_client_secret | Yes | Salesforce Connected App Consumer Secret (Client Secret) | |
| sf_refresh_token | Yes | Salesforce OAuth2 Refresh Token obtained after authorization | |
| sf_base_url | Yes | Salesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname) | |
| object_name | Yes | SObject API name to describe, e.g. 'Account' or 'My_Custom__c' |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations show readOnly, idempotent. Description adds error details ('NOT_FOUND') and confirms return type, aligning with and extending annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely concise: two sentences and error list, with no extraneous content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Adequately describes the purpose and return value; no output schema but the nature of a describe tool is clear. Errors are documented. Complete enough for an AI agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the description doesn't need to add param details. Description indirectly mentions object_name but adds minimal extra meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns full field-level metadata for a specific SObject, distinguishing it from sibling tools like sf_list_sobjects.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit use case: inspect fields before generating Ballerina records. Does not specify when not to use, but context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_exchange_oauth_codeExchange Salesforce OAuth2 Authorization Code for TokensA
Exchanges an OAuth2 authorization code for tokens. Set sandbox=true if the code was obtained from test.salesforce.com.
Returns the refresh_token (save this — it's long-lived!) and instance_url. The short-lived access_token is intentionally masked in the output to keep it out of MCP transcripts; you don't need it directly — pass refresh_token to the other tools and they obtain fresh access tokens on demand.
Error Handling:
"invalid_grant": code expired or already used — re-run sf_get_oauth_auth_url
"invalid_client": wrong client_id / client_secret (or Connected App still activating; wait 2-10 min after creating it)
| Name | Required | Description | Default |
|---|---|---|---|
| sf_client_id | Yes | Salesforce Connected App Consumer Key (Client ID) | |
| sf_client_secret | Yes | Salesforce Connected App Consumer Secret (Client Secret) | |
| code | Yes | Authorization code from the OAuth redirect | |
| redirect_uri | No | Same redirect URI used when generating the auth URL | https://login.salesforce.com/services/oauth2/success |
| sandbox | No | Exchange against test.salesforce.com (sandbox) instead of login.salesforce.com |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint=false, destructiveHint=false, idempotentHint=false, openWorldHint=true. The description goes beyond annotations by disclosing that the access_token is masked in output (keeping it out of transcripts) and that refresh_token is long-lived. Error scenarios are detailed with actionable advice. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is succinct with no superfluous text. Key sections are clearly separated: main action, parameter note, output details, error handling. Every sentence contributes essential information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of OAuth token exchange, the description adequately covers the purpose, all parameters, return values (refresh_token, instance_url), behavior (access_token masked), and error cases. No output schema exists, but the description compensates. The agent can confidently use this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds meaning: it clarifies the sandbox parameter's effect (test.salesforce.com vs login.salesforce.com), implies that redirect_uri must match the one used previously, and explains that the code comes from the OAuth redirect. This enriches the bare schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool exchanges an OAuth2 authorization code for tokens, distinguishing it from sibling tools like sf_get_oauth_auth_url and sf_get_token_password_flow. The verb 'exchange' and resource 'authorization code' are specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use it (after obtaining the code) and provides error-specific guidance (e.g., re-run sf_get_oauth_auth_url for invalid_grant). It also mentions the sandbox parameter. However, it does not explicitly contrast with the password flow or other authentication tools, leaving some implicit use-case differentiation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_generate_postman_collectionGenerate Salesforce Postman Collection (with auto-obtained refresh token)A
Creates a complete, import-ready Postman collection for your Salesforce org:
Auto-obtains a refresh token using the username+password flow (no browser).
Bakes ALL credentials into the collection (collection variables + OAuth2 config).
Saves the .postman_collection.json to disk.
Returns a ready_for_quickstart block — call sf_quickstart immediately after, or save the file path and use sf_import_postman_credentials any time later.
The generated collection includes: • Password flow, auth-code flow (Steps 1–3), and refresh-token requests • Test scripts that auto-save tokens to collection variables on every response • Salesforce REST API folder (validate, list SObjects, SOQL, create Account) • Ballerina service folder (health check, Account CRUD via local service)
This is the recommended first step — run it once, reuse the collection forever.
| Name | Required | Description | Default |
|---|---|---|---|
| sf_client_id | Yes | Salesforce Connected App Consumer Key (Client ID) | |
| sf_client_secret | Yes | Salesforce Connected App Consumer Secret (Client Secret) | |
| sf_base_url | Yes | Salesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname) | |
| username | Yes | Salesforce username (email). Used to auto-obtain a refresh token via the password flow. | |
| password | Yes | Salesforce password. Append your security token if required: myPassword + ABC123 → myPasswordABC123 | |
| redirect_uri | No | Redirect URI registered in your Connected App (also written into the collection). | https://login.salesforce.com/services/oauth2/success |
| collection_name | No | Display name for the Postman collection (default: 'Salesforce Integration'). | Salesforce Integration |
| output_path | No | Where to save the .postman_collection.json. Defaults to ~/WSO2Integrator/<collection_name>.postman_collection.json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Detailed disclosure of automation: auto-obtains refresh token, bakes credentials, saves to disk, and returns a block. Annotations indicate non-destructive and open world, which aligns with the description. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with a clear lead sentence and bullet points for contents. Every sentence adds value, though could be slightly more streamlined.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the entire process, components of the generated collection, and return value. Completes the picture for a complex tool with no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema already describes all parameters with 100% coverage, and the description adds extra context (e.g., appending security token for password, default output path). Provides value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it creates a complete Postman collection for Salesforce, listing contents and connecting to sibling tools like sf_quickstart and sf_import_postman_credentials. It distinguishes itself by being the recommended first step.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states it is the recommended first step and provides clear next steps: call sf_quickstart immediately or use sf_import_postman_credentials later. No ambiguity about when to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_get_oauth_auth_urlGet Salesforce OAuth2 Authorization URLARead-onlyIdempotent
Generates the Salesforce OAuth2 authorization URL for a Connected App. Open the returned URL in a browser to approve access. After approving, Salesforce redirects to the redirect_uri with a 'code' query parameter — pass that code to sf_exchange_oauth_code to obtain your refresh token.
Set sandbox=true to use test.salesforce.com instead of login.salesforce.com.
| Name | Required | Description | Default |
|---|---|---|---|
| sf_client_id | Yes | Salesforce Connected App Consumer Key (Client ID) | |
| redirect_uri | No | Redirect URI registered in your Connected App | https://login.salesforce.com/services/oauth2/success |
| sandbox | No | Use sandbox login server (test.salesforce.com) instead of login.salesforce.com |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true. The description adds context that this is a URL generation step requiring user interaction and describes the follow-up redirect and code parameter, enhancing understanding of behavior beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences: first defines purpose, second details the flow, third optional switch. Front-loaded, no redundancy, every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Tool has 3 params, no output schema. Description covers flow and next steps, but could briefly mention that the generated URL includes the client_id and redirect_uri. Overall sufficiently complete for an auth URL generation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 100% coverage. Description adds real-world meaning: explains sandbox parameter effect, role of redirect_uri in flow, and identifies sf_client_id as Consumer Key, providing practical usage context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool generates the Salesforce OAuth2 authorization URL for a Connected App, with specific verb and resource. It differentiates from siblings by naming the next step (sf_exchange_oauth_code) and implying the code flow, not other auth methods.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description outlines the complete flow: generate URL → browser approval → code exchange, indicating when to use this tool. However, it does not explicitly exclude alternative flows like password grant (sf_get_token_password_flow), leaving minor ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_get_token_password_flowGet Salesforce Tokens via Username-Password Flow (No Browser)A
Obtains Salesforce OAuth2 tokens using the username+password grant — no browser, no auth-code redirect required.
Requirements on the Connected App (one-time Salesforce Setup):
Scope: "Perform requests at any time (refresh_token, offline_access)"
Setup → Identity → OAuth and OpenID Connect Settings → "Allow OAuth Username-Password Flows" = ON
Append security token to password if required: myPasswordABC123
Returns refresh_token and a ready_for_quickstart block for sf_quickstart.
| Name | Required | Description | Default |
|---|---|---|---|
| sf_client_id | Yes | Salesforce Connected App Consumer Key (Client ID) | |
| sf_client_secret | Yes | Salesforce Connected App Consumer Secret (Client Secret) | |
| username | Yes | Salesforce username (email), e.g. me@myorg.com | |
| password | Yes | Salesforce password. If your org uses a security token, append it directly: password+securitytoken | |
| sf_base_url | Yes | Salesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false, destructiveHint=false, idempotentHint=false. The description adds context about requiring a Connected App configuration, security token handling, and return values. It does not contradict annotations and provides useful behavioral details beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, front-loaded with the core purpose, and structured with a bullet list for requirements. Every sentence adds value without unnecessary wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the absence of an output schema, the description mentions return values (refresh_token and ready_for_quickstart block) and prerequisites. It covers most essential aspects for invoking the tool but omits error handling or failure scenarios.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions for all 5 parameters. The description adds extra semantics by explaining how to append security token to password and that sf_base_url auto-detects sandbox. This enhances the schema's information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'obtains' and the resource 'Salesforce OAuth2 tokens using the username+password grant'. It distinguishes from sibling tools like sf_exchange_oauth_code and sf_get_oauth_auth_url by explicitly mentioning 'no browser, no auth-code redirect required'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit requirements for the Connected App setup and password security token appending. It mentions the return of refresh_token and a block for sf_quickstart, but does not explicitly list alternative tools or when not to use this flow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_import_postman_credentialsImport Salesforce Credentials from Postman CollectionARead-onlyIdempotent
Reads a Postman collection (.postman_collection.json) — including ones generated by sf_generate_postman_collection — and extracts Salesforce OAuth2 credentials (clientId, clientSecret, refreshToken, instanceUrl, username, password) so you don't have to type them out manually.
If a refresh_token is found it is returned immediately (no browser auth needed). If only username + password are found, tells you to call sf_get_token_password_flow.
Returns a ready_for_quickstart block to pass directly to sf_quickstart.
| Name | Required | Description | Default |
|---|---|---|---|
| postman_file | Yes | Absolute or ~-relative path to a .postman_collection.json file. The tool extracts Salesforce credentials and returns them ready for sf_quickstart. | |
| validate | No | Make a live Salesforce API call to confirm the extracted credentials work (default: true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true. The description adds useful behavioral context: it reads a file, returns credentials, and optionally validates with a live API call via the 'validate' parameter. This goes beyond what annotations provide, though the core safety profile is already covered by annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two paragraphs with clear structure: first sentence states primary purpose, then conditional logic, then final outcome. It is concise with no unnecessary words, but could be slightly tighter by merging sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description explains the return value ('ready_for_quickstart' block for sf_quickstart). For a tool with only 2 parameters, the description covers all relevant aspects: input path, validation behavior, and outcome. It is fully complete given the tool's simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and parameter descriptions exist. The description adds context about the 'validate' parameter (makes a live call) and mentions path format for 'postman_file', but this largely overlaps with schema descriptions. Baseline 3 is appropriate as the description adds marginal value beyond detailed schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verbs ('Reads', 'extracts') and clearly identifies the resource (Postman collection) and the extracted credentials. It distinguishes from siblings by mentioning sf_generate_postman_collection as a source and sf_quickstart as the consumer, also referencing sf_get_token_password_flow as an alternative path.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: use this tool to avoid manual credential typing. It explains conditional behavior (refresh token vs username/password) and directs to sf_get_token_password_flow when needed. However, it does not explicitly state when not to use this tool or list other alternatives beyond the one reference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_list_sobjectsList Salesforce SObjectsARead-onlyIdempotent
Lists SObjects (standard and/or custom) available in the org. Supports filtering and pagination.
Returns JSON with: total, count, offset, has_more, next_offset (when more), sobjects[].
| Name | Required | Description | Default |
|---|---|---|---|
| sf_client_id | Yes | Salesforce Connected App Consumer Key (Client ID) | |
| sf_client_secret | Yes | Salesforce Connected App Consumer Secret (Client Secret) | |
| sf_refresh_token | Yes | Salesforce OAuth2 Refresh Token obtained after authorization | |
| sf_base_url | Yes | Salesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname) | |
| include_custom | No | Include custom (__c) objects | |
| filter | No | Substring filter on object name/label | |
| limit | No | Max objects to return | |
| offset | No | Pagination offset |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate read-only, idempotent, and non-destructive behavior. The description adds details on the return JSON structure, including fields like total, count, offset, has_more, next_offset, and sobjects[], providing useful context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences: purpose, features, and return structure. It is front-loaded with the core action and contains no unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's purpose, features, and return format. For a filtered listing tool with full schema coverage and annotations, it is mostly complete, though it could mention error handling or prerequisites (already in schema).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all parameters. The description reiterates filtering and pagination but does not add new semantic meaning beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists SObjects (standard and/or custom) available in the org, with filtering and pagination. This distinguishes it from sibling tools like sf_describe_sobject and sf_add_custom_object.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description mentions filtering and pagination but does not explicitly guide when to use this tool versus alternatives, nor does it mention when not to use it. Usage is implied but not clarified.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_quickstartSalesforce + Ballerina Quickstart (One-Shot Setup)A
End-to-end setup in a single call:
Validates your Salesforce credentials.
Auto-detects sandbox vs. production from sf_base_url hostname.
Scaffolds a Ballerina project in your WSO2 BI workspace.
Standard SObjects use pre-built types from ballerinax/salesforce.types (no describe API calls, no generated boilerplate).
Custom (__c) objects are described and typed automatically.
Optionally runs 'bal build' to verify compilation.
This is the recommended entry point — most users only need to call this tool.
If you don't yet have credentials, call sf_setup_guide first.
All inputs except the 4 credential fields have sensible defaults:
project_name: salesforce_integration
org_name: wso2bi
bi_path: ~/WSO2Integrator (mac/linux) or %USERPROFILE%\WSO2Integrator
target_objects: ["Account", "Contact", "Lead", "Opportunity"]
port: 9090
build: false (set true to compile after scaffolding)
| Name | Required | Description | Default |
|---|---|---|---|
| sf_client_id | Yes | Salesforce Connected App Consumer Key (Client ID) | |
| sf_client_secret | Yes | Salesforce Connected App Consumer Secret (Client Secret) | |
| sf_refresh_token | Yes | Salesforce OAuth2 Refresh Token obtained after authorization | |
| sf_base_url | Yes | Salesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname) | |
| project_name | No | Ballerina package name (default: salesforce_integration) | salesforce_integration |
| org_name | No | Ballerina org name (default: wso2bi) | wso2bi |
| bi_path | No | WSO2 BI workspace path (default: ~/WSO2Integrator) | ~/WSO2Integrator |
| target_objects | No | SObject API names (default: Account, Contact, Lead, Opportunity) | |
| build | No | Run 'bal build' after scaffolding to verify the project compiles. Adds 30-90s but catches credential or version mismatches early. | |
| cdc_listeners | No | Optional CDC / Platform Event listeners to scaffold alongside the REST service. | |
| port | No | HTTP listener port (default: 9090) | |
| sandbox | No | Force sandbox mode (test.salesforce.com). Usually inferred from sf_base_url, set this only to override detection. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses all steps (validation, auto-detection, scaffolding, optional build) with side-effect details (e.g., file creation, compilation time). Annotations already indicate non-read-only and non-destructive, so the description adds context about what the tool does without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with numbered steps and bullet points for defaults. It is concise, front-loading the core purpose, and every sentence serves a purpose without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (12 parameters, no output schema, open world), the description is complete. It explains default behavior, the flow, and when to use this tool versus alternatives, making it fully actionable for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value by listing sensible defaults and explaining the sandbox auto-detection override. It also provides context for the cdc_listeners array structure, going beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it performs an end-to-end setup in a single call, listing step-by-step actions (validate, detect, scaffold, optional build). It distinguishes itself as the recommended entry point among sibling tools, mentioning when to use alternatives like sf_setup_guide.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'most users only need to call this tool' and advises calling sf_setup_guide first if credentials are missing. The description also implies this is the starting point, with other tools for later customization.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_scaffold_projectScaffold Ballerina + Salesforce Project in WSO2 IntegratorA
Creates a Ballerina integration project in your WSO2 Integrator (BI) workspace.
For most users, prefer 'sf_quickstart' — it wraps this plus credential validation and an optional build step.
Standard SObjects use pre-built types from ballerinax/salesforce.types (no describe call needed). Custom (__c) objects are described from your org and typed in types.bal.
Pre-conditions:
'bal' CLI installed (sf_check_prerequisites)
target_objects exist in your org (custom objects fail loudly if missing)
| Name | Required | Description | Default |
|---|---|---|---|
| project_name | No | Ballerina package name (default: salesforce_integration) | salesforce_integration |
| org_name | No | Ballerina org name written to Ballerina.toml (default: wso2bi) | wso2bi |
| bi_path | No | Path to your WSO2 Integrator (BI) workspace. Defaults to ~/WSO2Integrator. | ~/WSO2Integrator |
| sf_client_id | Yes | Salesforce Connected App Consumer Key (Client ID) | |
| sf_client_secret | Yes | Salesforce Connected App Consumer Secret (Client Secret) | |
| sf_refresh_token | Yes | Salesforce OAuth2 Refresh Token obtained after authorization | |
| sf_base_url | Yes | Salesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname) | |
| target_objects | No | SObject API names to scaffold (default: Account, Contact, Lead, Opportunity). Standard SObjects use pre-built types from ballerinax/salesforce.types — no describe call required. | |
| cdc_listeners | No | Optional CDC / Platform Event listeners to scaffold alongside the REST service. Each entry generates a salesforce:Listener bound to a channel, with onCreate/onUpdate/onDelete/onRestore stubs for CDC or onMessage for platform events. | |
| port | No | HTTP listener port baked into the generated service (default: 9090) | |
| sandbox | No | Force sandbox mode (test.salesforce.com). Usually inferred from sf_base_url, set this only to override detection. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations show readOnlyHint=false and destructiveHint=false; description adds that for custom objects it 'describes from your org and typed in types.bal' and 'fail loudly if missing'. This is transparent about behavior beyond annotations, though could detail project file structure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with pre-conditions and clear sections. However, some sentences (e.g., about standard vs custom) could be integrated into parameter descriptions. Still, front-loaded purpose and efficient overall.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 11 parameters and no output schema, description covers purpose, usage guidance, pre-conditions, and parameter hints adequately. Lacks explicit return value documentation but acceptable for a scaffolding action.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 11 parameters thoroughly. Description adds marginal context (e.g., 'custom objects fail loudly'), but does not significantly enhance understanding beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it 'Creates a Ballerina integration project' and distinguishes from sibling 'sf_quickstart' by noting that quickstart wraps this plus credential validation and build step. The verb+resource combination is specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises 'For most users, prefer sf_quickstart' and lists pre-conditions (bal CLI, target objects exist). This provides clear when-to-use guidance and differentiates from alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_setup_guideShow Salesforce + WSO2 BI Setup GuideARead-onlyIdempotent
Returns a step-by-step guide for first-time users: how to create a Salesforce Connected App, where to find the Consumer Key/Secret, how to get a refresh token via sf_get_oauth_auth_url + sf_exchange_oauth_code, and which tool to call next. Call this when the user says "I'm new" / "where do I start" / "how do I get credentials".
| Name | Required | Description | Default |
|---|---|---|---|
| sandbox | No | Generate the sandbox (test.salesforce.com) variant of the guide. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the description adds little beyond stating it returns a guide. No behavioral details beyond content are provided.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences pack purpose, content, and usage triggers with no fluff. Front-loaded with the key fact 'returns a step-by-step guide'.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple guide tool with one optional boolean and no output schema, the description covers when and what. Minor gap: does not specify output format (e.g., text, JSON), but acceptable given simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema fully explains the single 'sandbox' parameter. The description does not add any additional meaning about the parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns a step-by-step guide for first-time users, listing specific content. It distinguishes itself from sibling tools which are actual operational actions (e.g., getting auth URL).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells when to call: when user says 'I'm new' / 'where do I start' / 'how do I get credentials'. Also suggests which tools to call next, aiding workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_stop_projectStop a Running Ballerina ServiceADestructiveIdempotent
Stops a 'bal run' process previously started by sf_deploy_project. Only PIDs tracked by this server (started via sf_deploy_project during the current session) can be stopped — for safety we won't kill arbitrary host PIDs.
| Name | Required | Description | Default |
|---|---|---|---|
| pid | Yes | PID returned by sf_deploy_project. Only processes started by this server can be stopped. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate destructive and idempotent. Description adds that only tracked PIDs from the current session can be stopped, with safety rationale. This provides valuable context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the main action, every sentence adds value. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one param and no output schema, the description covers purpose, usage constraints, safety, and dependency on sf_deploy_project. Completely adequate for correct selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and description adds little new info beyond what is already in the schema's parameter description. The tool description reiterates the PID's origin but does not significantly enhance semantic understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it stops a running Ballerina service started by sf_deploy_project. The verb 'stops' and resource 'bal run process' are specific, and it distinguishes from sibling tools like sf_deploy_project.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description tells when to use (only for PIDs from sf_deploy_project) and explicitly states safety restrictions. It implies not for arbitrary host PIDs, but does not explicitly list alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_validate_connectionValidate Salesforce ConnectionARead-onlyIdempotent
Tests that the provided Salesforce credentials are valid by making a live API call to the org. Use this before scaffolding a project to confirm credentials work.
Returns:
connected: boolean
org_id: Salesforce Org ID
username: Authenticated username
instance_url: Confirmed org URL
| Name | Required | Description | Default |
|---|---|---|---|
| sf_client_id | Yes | Salesforce Connected App Consumer Key (Client ID) | |
| sf_client_secret | Yes | Salesforce Connected App Consumer Secret (Client Secret) | |
| sf_refresh_token | Yes | Salesforce OAuth2 Refresh Token obtained after authorization | |
| sf_base_url | Yes | Salesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, non-destructive, idempotent, and open-world hints. The description adds that it makes a live API call and returns specific fields (connected, org_id, etc.), which enhances transparency. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise: one sentence for purpose and usage, then a bullet list of return values. Every sentence earns its place. No fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given full schema coverage and annotations, the description covers purpose, usage, and return values. It does not address error cases (e.g., what if credentials invalid?), but the return structure implies connected: boolean. Overall, adequate for a validation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 100% coverage with full descriptions for all four parameters. The description does not add any additional parameter-level meaning; it only describes the return values. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool tests Salesforce credentials with a live API call. The title 'Validate Salesforce Connection' and the first sentence specify the verb and resource. Among siblings like sf_get_oauth_auth_url and sf_exchange_oauth_code, this tool is distinct as a validation step.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly recommends using this tool 'before scaffolding a project to confirm credentials work,' providing clear context. It does not elaborate on when not to use it or list alternatives, but the guidance is sufficiently clear for an agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sf_write_config_tomlWrite or Update Config.toml with Salesforce CredentialsAIdempotent
Overwrites Config.toml in an existing Ballerina project with fresh Salesforce OAuth2 credentials. Useful for rotation. Sandbox is auto-detected from sf_base_url. File is written with mode 0600 (owner read/write only).
| Name | Required | Description | Default |
|---|---|---|---|
| project_path | Yes | Path to the Ballerina project directory | |
| sf_client_id | Yes | Salesforce Connected App Consumer Key (Client ID) | |
| sf_client_secret | Yes | Salesforce Connected App Consumer Secret (Client Secret) | |
| sf_refresh_token | Yes | Salesforce OAuth2 Refresh Token obtained after authorization | |
| sf_base_url | Yes | Salesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the idempotentHint and non-destructive annotations, the description adds that the file is written with mode 0600 (security) and that sandbox is auto-detected, giving useful behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise, front-loaded sentences with no unnecessary words; every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a write tool with no output schema, the description covers purpose and key behaviors, but could optionally mention what happens on success or error conditions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers all parameters with descriptions, so the description adds minimal extra semantic value, merely echoing the credentials purpose and sandbox detection.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool overwrites Config.toml with fresh Salesforce OAuth2 credentials, distinguishing it from sibling tools that perform validation, URL generation, or other operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description mentions 'useful for rotation' and notes sandbox auto-detection, providing context for when to use, though it does not explicitly state when not to use or list alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
18 tool updates
v1.1.0- First observed
sf_add_cdc_listener - First observed
sf_add_custom_object - First observed
sf_build_project - First observed
sf_check_prerequisites - First observed
sf_deploy_project - First observed
sf_describe_sobject - First observed
sf_exchange_oauth_code - First observed
sf_generate_postman_collection - First observed
sf_get_oauth_auth_url - First observed
sf_get_token_password_flow - First observed
sf_import_postman_credentials - First observed
sf_list_sobjects - First observed
sf_quickstart - First observed
sf_scaffold_project - First observed
sf_setup_guide - First observed
sf_stop_project - First observed
sf_validate_connection - First observed
sf_write_config_toml
TDQS
Most tools have distinct purposes, but sf_quickstart and sf_scaffold_project overlap somewhat; however, descriptions clarify sf_quickstart as the recommended entry point. Overall, an agent can differentiate well.
All tools use the 'sf_' prefix and follow a verb_noun pattern, except 'sf_quickstart' which is a single word. This minor deviation keeps the score slightly below perfect.
18 tools cover the entire workflow of setting up a Salesforce integration project from prerequisites to deployment, with each tool serving a clear purpose. The count is well-scoped for the domain.
The tool surface covers all major steps for setup: credential flow, project creation, building, deploying, and managing listeners/objects. However, there are no tools for actual record CRUD operations, but that seems out of scope for this server's stated purpose.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Plan Salesforce deploys, open pull requests and trigger pipelines from your AI client.
- mcp-serverOAuthcom.make
Give your AI agents the tools to build, manage, and run automation workflows.
- mcpOAuthcom.vibgrate
Query your team's drift, vulnerability, and upgrade data from any AI assistant. OAuth 2.1, 51 tools.
Connect AI agents to 1000+ apps with managed authentication and tool-calling.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to interact with Salesforce organizations through natural language by exposing Salesforce APIs (REST, Bulk v2, GraphQL, Tooling, Auth) as MCP tools for querying data, managing records, and executing SOQL queries.2519MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to securely interact with Salesforce CRM data through SOQL queries, CRUD operations, and metadata exploration. Supports connecting to Salesforce objects like Accounts, Contacts, and Opportunities via OAuth 2.0 authentication.82MIT
- AlicenseAqualityCmaintenanceEnables AI assistants to interact with Salesforce through a secure interface for performing CRUD operations, executing SOQL queries, and managing schema discovery. It features a smart learning system that analyzes custom objects and fields to provide intelligent assistance tailored to specific Salesforce configurations.141917BSD 2-Clause "Simplified"
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Salesforce CRM by executing SOQL queries and performing CRUD operations on records such as Leads. It supports secure OAuth 2.0 authentication and provides management for both standard and custom Salesforce fields.-
Appeared in Searches
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/PasinduGunarathne/wso2-bi-salesforce-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server