Skip to main content
Glama
PasinduGunarathne

wso2-bi-salesforce-mcp-server

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

Node.js

18+

Run the MCP server

Ballerina

2201.12.0 (Swan Lake)

Build and run the generated projects. Exact match recommended — scaffolded projects pin this distribution, and sf_check_prerequisites warns on a mismatch.

Git

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

2. One-time Salesforce setup (in your org → Setup)

  1. Create a Connected App — App Manager → New Connected App → enable OAuth:

    • Callback URL: https://<your-domain>.my.salesforce.com/services/oauth2/success

    • Scopes: api and refresh_token (offline_access)

    • Save, wait 2–10 min, then copy the Consumer Key and Consumer Secret.

  2. 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).

  3. 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 build

4. 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

TARGET_OBJECTS

Objects exposed as REST CRUD — the publisher flow (default Account,Contact,Lead,Opportunity).

CDC_OBJECTS

Objects you receive change events for — the consumer flow. One object = one listener.

REST_API

true (default) builds the REST publisher API; false builds a CDC-only project.

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/reauth once 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-server

2. Install dependencies

npm install

3. Build the server

npm run build

This 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.js

You 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 bi_path

macOS / Linux

~/WSO2Integrator

Windows

%USERPROFILE%\WSO2Integrator

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

  1. 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.json
  2. Add the server under mcpServers:

    {
      "mcpServers": {
        "ballerina-salesforce": {
          "command": "node",
          "args": [
            "/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js"
          ]
        }
      }
    }
  3. 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.

# 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.js

Verify:

claude mcp list

Manual — 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.json is not a valid path. User-scope MCP config lives in ~/.claude.json (top-level key). Project-scope config lives in .mcp.json at the project root, not inside .claude/.


Cursor

  1. Open Cursor → Settings → Features → MCP (or Cursor Settings > MCP).

  2. Click Add new MCP server.

  3. Fill in:

    • Name: ballerina-salesforce

    • Type: stdio

    • Command: node

    • Args: /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 uses mcpServers (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 ServersConfigure 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 configureAdd ExtensionCommand-line Extension):

extensions:
  ballerina-salesforce:
    type: stdio
    cmd: node
    args:
      - /absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js
    enabled: true

For 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.js
  • MCP endpoint: http://127.0.0.1:3001/mcp

  • Auth header: Authorization: Bearer your-secret-token

  • Health check: http://127.0.0.1:3001/healthz

⚠️ Always set SF_MCP_HTTP_TOKEN in 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: node

  • Args: ["/absolute/path/to/wso2-bi-salesforce-mcp-server/dist/index.js"]

  • Transport: stdio

  • Protocol: 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:

  1. SF_REFRESH_TOKEN in .env — used directly, fully non-interactive.

  2. SF_USERNAME + SF_PASSWORD — password flow (needs the org toggle); if it fails, the script automatically falls back to browser OAuth.

  3. 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 + writes SF_REFRESH_TOKEN into .env so 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

SF_CLIENT_ID / SF_CLIENT_SECRET

Connected App Consumer Key / Secret

SF_BASE_URL

e.g. https://myorg.my.salesforce.com

SF_REFRESH_TOKEN

one of these

Pre-obtained refresh token (works on any org)

SF_USERNAME + SF_PASSWORD

one of these

Used to auto-obtain a token via the password flow (needs the org toggle)

PROJECT_NAME, ORG_NAME, BI_PATH, TARGET_OBJECTS, PORT, SANDBOX, BUILD

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, skip bal 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:

  1. Validates your credentials with a live Salesforce API call

  2. Auto-detects sandbox vs production from the URL

  3. Scaffolds a complete Ballerina project at ~/WSO2Integrator/salesforce_integration/

  4. Writes Config.toml with mode 0600 (owner read/write only)

  5. 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_guide gives you the exact steps. In short:

  1. Salesforce → Setup → App Manager → New Connected App

  2. Enable OAuth: scopes api + refresh_token (offline_access), callback https://login.salesforce.com/services/oauth2/success

  3. Save → copy Consumer Key and Consumer Secret

  4. 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.json file. 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 service

Step-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 done

Fastest 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 done

Starting 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 done

Starting 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 done

Or 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 done

Tool 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

sandbox

boolean

false

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_access

Pass 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

sf_client_id

string

required

Consumer Key from your Connected App

sf_base_url

string

Recommended. Org / My Domain URL. When set, the authorize URL (and the default redirect) use this host.

redirect_uri

string

https://login.salesforce.com/services/oauth2/success

Must match a callback registered in your Connected App. When sf_base_url is set and this is left at the default, it auto-aligns to <your-host>/services/oauth2/success.

sandbox

boolean

false

Use test.salesforce.com instead of login.salesforce.com. Ignored when sf_base_url is set.

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_token is intentionally masked in output — it's shown as access_token_preview only. 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

sf_client_id

string

required

Consumer Key

sf_client_secret

string

required

Consumer Secret

code

string

required

The ?code= value from the redirect URL

redirect_uri

string

success URL

Same URI used in sf_get_oauth_auth_url

sandbox

boolean

false

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-run sf_get_oauth_auth_url

  • AUTH_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

sf_client_id

string

Consumer Key

sf_client_secret

string

Consumer Secret

sf_refresh_token

string

Refresh token

sf_base_url

string

e.g. https://myorg.my.salesforce.com

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

include_custom

boolean

true

Include __c objects

filter

string

Substring filter on name or label

limit

integer

50

Max results (1–200)

offset

integer

0

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

object_name

string

SObject API name, e.g. Account or My_Custom__c

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

sf_client_id

string

required

Consumer Key

sf_client_secret

string

required

Consumer Secret

sf_refresh_token

string

required

Refresh token

sf_base_url

string

required

e.g. https://myorg.my.salesforce.com

project_name

string

salesforce_integration

Ballerina package name

org_name

string

wso2bi

Ballerina org name in Ballerina.toml

bi_path

string

~/WSO2Integrator

WSO2 BI workspace root

target_objects

string[]

["Account","Contact","Lead","Opportunity"]

SObject API names to scaffold CRUD for

cdc_listeners

array

CDC / Platform Event listeners to add (see below)

build

boolean

false

Run bal build after scaffolding

sandbox

boolean

auto-detected

Override sandbox detection (detected from URL by default)

cdc_listeners entry — specify exactly one of:

Field

Type

Channel generated

sobject

string

/data/<SObject>ChangeEvent

all_changes

boolean true

/data/ChangeEvents

platform_event

string (ends __e)

/event/<Name>__e

events

string[]

Which callbacks: onCreate, onUpdate, onDelete, onRestore (default: all four)

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

project_path

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>.bal referencing the pre-built type from ballerinax/salesforce.types — no describe API call needed.

  • Custom (__c) objects: describes the schema live, appends a typed record to types.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

project_path

string

Path to the existing project

credentials

Required only for custom (__c) objects

object_name

string

SObject API name, e.g. Invoice__c


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

project_path

string

Path to the existing project

listener.sobject

string

SObject name → channel /data/<SObject>ChangeEvent

listener.all_changes

boolean

All objects → channel /data/ChangeEvents

listener.platform_event

string (ends __e)

Platform event → channel /event/<Name>__e

listener.events

string[]

CDC callbacks to scaffold (default: all four)

Specify exactly one of sobject, all_changes, or platform_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

project_path

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

project_path

string

required

Path to the project

port

integer

9090

HTTP listener port

Returns: pid (save this for sf_stop_project), started, service_url, health_check, output, message.

Endpoints once running:

Method

Path

Description

GET

/health

Health check — returns { status: "UP" }

GET

/<object>s

Query all records (SOQL, LIMIT 200)

GET

/<object>/{id}

Get a single record by Salesforce ID

POST

/<object>

Create a record

PUT

/<object>/{id}

Update a record

DELETE

/<object>/{id}

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

pid

integer

PID returned by sf_deploy_project


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_credentials in 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

sf_client_id

string

required

Consumer Key from the Connected App

sf_client_secret

string

required

Consumer Secret

sf_base_url

string

required

e.g. https://myorg.my.salesforce.com

username

string

required

Salesforce username (email)

password

string

required

Password (append security token if required: myPasswordABC123)

redirect_uri

string

https://login.salesforce.com/services/oauth2/success

Redirect URI registered in your Connected App

collection_name

string

Salesforce Integration

Display name for the Postman collection

output_path

string

~/WSO2Integrator/<collection_name>.postman_collection.json

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

postman_file

string

required

Absolute or ~-relative path to the .postman_collection.json file

validate

boolean

true

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 auth.oauth2

clientId, clientSecret, username, password, instanceUrl, redirectUri

Request body (urlencoded)

refresh_token, client_id, client_secret

Request URL (query params)

client_id, client_secret, redirect_uri


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

sf_client_id

string

Consumer Key from the Connected App

sf_client_secret

string

Consumer Secret

username

string

Salesforce username (email)

password

string

Password. If your org uses a security token, append it directly: myPassword + ABC123myPasswordABC123

sf_base_url

string

e.g. https://myorg.my.salesforce.com

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

authentication failure

Wrong password or missing security token

Append security token to password

invalid_client_credentials

Wrong client_id or client_secret

Check the Connected App's Consumer Key/Secret

unsupported_grant_type

Username-password flow not enabled

Enable it in Setup → Identity → OAuth and OpenID Connect Settings

No refresh_token returned

Connected App missing offline_access scope

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 docs

Standard vs custom SObjects

SObject type

Record type source

Describe API call?

Entry in types.bal?

Standard (Account, Contact, …)

ballerinax/salesforce.types pre-built

❌ No

❌ No

Custom (My_Object__c)

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, troubleshooting

Publishing flowPOST /accountssfClient->create(), GET /accounts/{id}sfClient->getById(), etc.

Consuming flowsalesforce: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 run

MCP 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.md

Configuration

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

stdio

Transport mode: stdio (local clients) or http (remote/containers).

PORT

3001

HTTP listener port — HTTP mode only.

SF_MCP_HTTP_TOKEN

Bearer token required on all /mcp requests in HTTP mode. The server warns on startup if unset. Strongly recommended for any non-localhost use.

BAL_BIN

bal

Absolute path to the bal binary — useful when Ballerina is installed but not on PATH (e.g. via bvm).

SF_MCP_ALLOWED_ROOTS

$HOME, $TMPDIR

Colon-separated extra directories that project_path / bi_path are permitted to resolve under. Add a path here to scaffold outside your home directory.

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

clientId

string

"3MVG9..."

Connected App Consumer Key.

clientSecret

string

"ABCD..."

Connected App Consumer Secret.

refreshToken

string

"5Aep861..."

Long-lived OAuth2 refresh token. The connector mints short-lived access tokens from this at runtime.

refreshUrl

string

"https://login.salesforce.com/services/oauth2/token"

Token endpoint. Auto-set to login. (production) or test. (sandbox) based on sf_base_url.

baseUrl

string

"https://myorg.my.salesforce.com"

Your org instance URL.

apiVersion

string

"62.0"

Salesforce REST API version the connector targets.

servicePort

int

9090

HTTP listener port for the generated service.

To rotate credentials without re-scaffolding, prefer the sf_write_config_toml tool — it re-writes the file with mode 0600 and 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

Config.toml in the project root

Docker / WSO2 BI runtime

Env vars: SF_CLIENT_ID, SF_CLIENT_SECRET, SF_REFRESH_TOKEN, SF_REFRESH_URL, SF_BASE_URL

CI

Either — Config.toml takes precedence when present

The port can also be overridden at launch without editing the file: bal run -CservicePort=8080 (this is exactly what sf_deploy_project does with its port parameter).


Development

# Rebuild after changes
npm run build

# Watch mode (recompiles on save)
npm run dev

# Clean and rebuild
rm -rf dist && npm run build

To add a new tool:

  1. Add the Zod schema to src/schemas/tools.ts

  2. Add the handler in the appropriate file under src/tools/

  3. Register it with server.registerTool(...) in that file's register function

  4. Run npm run build


Security

Credential protection

  • Hostname allow-list: sf_base_url is validated against *.salesforce.com, *.force.com, *.cloudforce.com, and *.salesforce-setup.com before any credential is sent. Arbitrary URLs are rejected — prevents SSRF and credential exfiltration.

  • Config.toml written with mode 0600: Only the owning user can read it. Enforced on every write including credential rotation.

  • Token masking: sf_exchange_oauth_code masks the short-lived access_token in its output. Only the refresh_token is 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 $HOME or $TMPDIR. Path traversal attempts (../../etc/passwd) throw PATH_TRAVERSAL immediately.

Process safety

  • sf_deploy_project registers spawned PIDs in-process. sf_stop_project only terminates PIDs it started — it refuses to kill arbitrary system processes.

HTTP transport

  • Binds to 127.0.0.1 only — no external exposure by default.

  • Set SF_MCP_HTTP_TOKEN to require Authorization: Bearer <token> on every /mcp request.

  • /healthz is 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

AUTH_INVALID_GRANT

Refresh token revoked or wrong endpoint (production vs sandbox)

AUTH_CONNECTED_APP_NOT_READY

New Connected App still activating — wait 2–10 min

AUTH_INVALID_CLIENT

Wrong Consumer Key or Secret

INVALID_URL

sf_base_url failed hostname allow-list check

PATH_TRAVERSAL

Path resolves outside allowed roots

NOT_FOUND

Project directory or file not found

ALREADY_EXISTS

Project or module file already exists

BAL_CLI_MISSING

bal not on PATH — check BAL_BIN env var

BAL_BUILD_FAILED

Compilation failed — see output field

PRECONDITION_FAILED

Required file missing (e.g. Config.toml before deploy)

TRANSIENT

Network error — check connectivity and retry

INVALID_INPUT

Validation error (e.g. invalid SObject name format)

UNKNOWN

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.js

First 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

  1. Enable CDC for the object: Salesforce Setup → Integrations → Change Data Capture → select your object → Save.

  2. CDC requires Enterprise, Unlimited, Performance, or Developer Edition.

  3. Ensure OAuth scopes include api and refresh_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.js

Token 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 tools
sf_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
project_pathYesPath to the existing Ballerina project
listenerYes

TDQS

A4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
project_pathYesPath to the existing Ballerina project
sf_client_idYesSalesforce Connected App Consumer Key (Client ID)
sf_client_secretYesSalesforce Connected App Consumer Secret (Client Secret)
sf_refresh_tokenYesSalesforce OAuth2 Refresh Token obtained after authorization
sf_base_urlYesSalesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname)
object_nameYesSObject API name to add, e.g. 'My_Custom__c'

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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 ProjectA
Idempotent

Runs 'bal build' inside the project directory and reports the result.

ParametersJSON Schema
NameRequiredDescriptionDefault
project_pathYesPath to the Ballerina project to build

TDQS

A3.5/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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)A
Read-onlyIdempotent

Verifies that the 'bal' CLI is installed and reports its version. Run this first to catch missing prerequisites before scaffolding.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
project_pathYesPath to the Ballerina project to deploy
portNoHTTP listener port (default: 9090)

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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 SObjectA
Read-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

ParametersJSON Schema
NameRequiredDescriptionDefault
sf_client_idYesSalesforce Connected App Consumer Key (Client ID)
sf_client_secretYesSalesforce Connected App Consumer Secret (Client Secret)
sf_refresh_tokenYesSalesforce OAuth2 Refresh Token obtained after authorization
sf_base_urlYesSalesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname)
object_nameYesSObject API name to describe, e.g. 'Account' or 'My_Custom__c'

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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)

ParametersJSON Schema
NameRequiredDescriptionDefault
sf_client_idYesSalesforce Connected App Consumer Key (Client ID)
sf_client_secretYesSalesforce Connected App Consumer Secret (Client Secret)
codeYesAuthorization code from the OAuth redirect
redirect_uriNoSame redirect URI used when generating the auth URLhttps://login.salesforce.com/services/oauth2/success
sandboxNoExchange against test.salesforce.com (sandbox) instead of login.salesforce.com

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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:

  1. Auto-obtains a refresh token using the username+password flow (no browser).

  2. Bakes ALL credentials into the collection (collection variables + OAuth2 config).

  3. Saves the .postman_collection.json to disk.

  4. 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
sf_client_idYesSalesforce Connected App Consumer Key (Client ID)
sf_client_secretYesSalesforce Connected App Consumer Secret (Client Secret)
sf_base_urlYesSalesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname)
usernameYesSalesforce username (email). Used to auto-obtain a refresh token via the password flow.
passwordYesSalesforce password. Append your security token if required: myPassword + ABC123 → myPasswordABC123
redirect_uriNoRedirect URI registered in your Connected App (also written into the collection).https://login.salesforce.com/services/oauth2/success
collection_nameNoDisplay name for the Postman collection (default: 'Salesforce Integration').Salesforce Integration
output_pathNoWhere to save the .postman_collection.json. Defaults to ~/WSO2Integrator/<collection_name>.postman_collection.json

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 URLA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
sf_client_idYesSalesforce Connected App Consumer Key (Client ID)
redirect_uriNoRedirect URI registered in your Connected Apphttps://login.salesforce.com/services/oauth2/success
sandboxNoUse sandbox login server (test.salesforce.com) instead of login.salesforce.com

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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):

  1. Scope: "Perform requests at any time (refresh_token, offline_access)"

  2. 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
sf_client_idYesSalesforce Connected App Consumer Key (Client ID)
sf_client_secretYesSalesforce Connected App Consumer Secret (Client Secret)
usernameYesSalesforce username (email), e.g. me@myorg.com
passwordYesSalesforce password. If your org uses a security token, append it directly: password+securitytoken
sf_base_urlYesSalesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname)

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 CollectionA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
postman_fileYesAbsolute or ~-relative path to a .postman_collection.json file. The tool extracts Salesforce credentials and returns them ready for sf_quickstart.
validateNoMake a live Salesforce API call to confirm the extracted credentials work (default: true).

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 SObjectsA
Read-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[].

ParametersJSON Schema
NameRequiredDescriptionDefault
sf_client_idYesSalesforce Connected App Consumer Key (Client ID)
sf_client_secretYesSalesforce Connected App Consumer Secret (Client Secret)
sf_refresh_tokenYesSalesforce OAuth2 Refresh Token obtained after authorization
sf_base_urlYesSalesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname)
include_customNoInclude custom (__c) objects
filterNoSubstring filter on object name/label
limitNoMax objects to return
offsetNoPagination offset

TDQS

A4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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:

  1. Validates your Salesforce credentials.

  2. Auto-detects sandbox vs. production from sf_base_url hostname.

  3. 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.

  4. 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)

ParametersJSON Schema
NameRequiredDescriptionDefault
sf_client_idYesSalesforce Connected App Consumer Key (Client ID)
sf_client_secretYesSalesforce Connected App Consumer Secret (Client Secret)
sf_refresh_tokenYesSalesforce OAuth2 Refresh Token obtained after authorization
sf_base_urlYesSalesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname)
project_nameNoBallerina package name (default: salesforce_integration)salesforce_integration
org_nameNoBallerina org name (default: wso2bi)wso2bi
bi_pathNoWSO2 BI workspace path (default: ~/WSO2Integrator)~/WSO2Integrator
target_objectsNoSObject API names (default: Account, Contact, Lead, Opportunity)
buildNoRun 'bal build' after scaffolding to verify the project compiles. Adds 30-90s but catches credential or version mismatches early.
cdc_listenersNoOptional CDC / Platform Event listeners to scaffold alongside the REST service.
portNoHTTP listener port (default: 9090)
sandboxNoForce sandbox mode (test.salesforce.com). Usually inferred from sf_base_url, set this only to override detection.

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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)

ParametersJSON Schema
NameRequiredDescriptionDefault
project_nameNoBallerina package name (default: salesforce_integration)salesforce_integration
org_nameNoBallerina org name written to Ballerina.toml (default: wso2bi)wso2bi
bi_pathNoPath to your WSO2 Integrator (BI) workspace. Defaults to ~/WSO2Integrator.~/WSO2Integrator
sf_client_idYesSalesforce Connected App Consumer Key (Client ID)
sf_client_secretYesSalesforce Connected App Consumer Secret (Client Secret)
sf_refresh_tokenYesSalesforce OAuth2 Refresh Token obtained after authorization
sf_base_urlYesSalesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname)
target_objectsNoSObject API names to scaffold (default: Account, Contact, Lead, Opportunity). Standard SObjects use pre-built types from ballerinax/salesforce.types — no describe call required.
cdc_listenersNoOptional 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.
portNoHTTP listener port baked into the generated service (default: 9090)
sandboxNoForce sandbox mode (test.salesforce.com). Usually inferred from sf_base_url, set this only to override detection.

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 GuideA
Read-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".

ParametersJSON Schema
NameRequiredDescriptionDefault
sandboxNoGenerate the sandbox (test.salesforce.com) variant of the guide.

TDQS

A4.2/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 ServiceA
DestructiveIdempotent

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pidYesPID returned by sf_deploy_project. Only processes started by this server can be stopped.

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 ConnectionA
Read-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

ParametersJSON Schema
NameRequiredDescriptionDefault
sf_client_idYesSalesforce Connected App Consumer Key (Client ID)
sf_client_secretYesSalesforce Connected App Consumer Secret (Client Secret)
sf_refresh_tokenYesSalesforce OAuth2 Refresh Token obtained after authorization
sf_base_urlYesSalesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname)

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 CredentialsA
Idempotent

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
project_pathYesPath to the Ballerina project directory
sf_client_idYesSalesforce Connected App Consumer Key (Client ID)
sf_client_secretYesSalesforce Connected App Consumer Secret (Client Secret)
sf_refresh_tokenYesSalesforce OAuth2 Refresh Token obtained after authorization
sf_base_urlYesSalesforce org instance URL, e.g. https://myorg.my.salesforce.com (sandbox auto-detected from hostname)

TDQS

A4.4/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

  1. 18 tool updatesv1.1.0
    • First observedsf_add_cdc_listener
    • First observedsf_add_custom_object
    • First observedsf_build_project
    • First observedsf_check_prerequisites
    • First observedsf_deploy_project
    • First observedsf_describe_sobject
    • First observedsf_exchange_oauth_code
    • First observedsf_generate_postman_collection
    • First observedsf_get_oauth_auth_url
    • First observedsf_get_token_password_flow
    • First observedsf_import_postman_credentials
    • First observedsf_list_sobjects
    • First observedsf_quickstart
    • First observedsf_scaffold_project
    • First observedsf_setup_guide
    • First observedsf_stop_project
    • First observedsf_validate_connection
    • First observedsf_write_config_toml

TDQS

A4.1/5.0
Disambiguation4/5

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.

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness4/5

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

ActivityStale
ResponsivenessUnresponsive

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

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables 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.
    25
    19
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables 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.
    8
    2
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables 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.
    14
    19
    17
    BSD 2-Clause "Simplified"
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables 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

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