Skip to main content
Glama
89himanshu-dwivedi

Salesforce MCP Server

README.md
# Salesforce MCP Server — Headless 360

![Python](https://img.shields.io/badge/Python-3.11+-blue) ![MCP](https://img.shields.io/badge/MCP-server-8A2BE2) ![Salesforce](https://img.shields.io/badge/Salesforce-tools-00A1E0)

A **Model Context Protocol** server that exposes Salesforce as tools for any MCP client
(Claude Desktop, VS Code, custom agents). Ask your AI *"which accounts have stale
opportunities?"* and it queries your org directly — no login, no tab-switching.

**What this demonstrates:** the N×M integration problem MCP solves (N clients × M systems
→ N+M), tool design with least-privilege guardrails, and prompt templates as a first-class
server capability.

## Tools exposed

| Tool | What it does | Guardrail |
|------|--------------|-----------|
| `run_soql` | Read-only SOQL queries | SELECT-only + forbidden-keyword guard (tested) |
| `describe_object` | Field names/types/labels for any SObject | read-only |
| `create_contact` | Create a Contact | deliberately narrow — no generic DML tool |
| `org_limits` | API/storage limits snapshot | read-only |

Plus an MCP **prompt**: `account_health_review` — a reusable analysis template clients
can invoke by name.

## Setup

```bash
pip install -r requirements.txt
cp .env.example .env   # add your credentials
mcp dev server.py      # inspector UI for local testing
```

### Claude Desktop config

```json
{
  "mcpServers": {
    "salesforce": {
      "command": "python",
      "args": ["C:/path/to/salesforce-mcp-server/server.py"],
      "env": {
        "SF_USERNAME": "you@example.com",
        "SF_PASSWORD": "...",
        "SF_SECURITY_TOKEN": "..."
      }
    }
  }
}
```

## Security notes (the part that matters)

- **Least privilege**: one narrow write tool instead of generic DML — an AI that can
  "do anything" is an incident waiting to happen.
- **SOQL guard**: model-composed queries are validated before execution (`tests/test_guard.py`).
- **Prompt injection**: treat records' field values as untrusted input — a Contact
  Description saying "ignore previous instructions" must never steer the agent.
  Keep write tools narrow and confirm destructive intents client-side.
- Use a dedicated Integration User profile with minimal object permissions.

## Tests

```bash
pytest -q   # guard tests run offline, no org needed
```