Salesforce REST/SOQL/Bulk API 2.0 connector + MCP Server + A2A Server for Agentic AI!
Project description
Salesforce Agent
CLI or API | MCP | Agent
Version: 0.2.0
Documentation — Installation, deployment, usage across the API, CLI, and MCP server live on the docs site: https://knuckles-team.github.io/salesforce-agent/
Table of Contents
- Overview
- Architecture
- Installation
- MCP Tools
- Auth Flows
- Environment Variables
- Quick Start
- Deployment
- Development
- License
Overview
The Salesforce connector for the agent-utilities fleet — an owned thin httpx wrapper over the Salesforce REST API exposed as a FastMCP server and an A2A agent. REST + SOQL/SOSL + Bulk API 2.0 + metadata describe, with safety gates designed for autonomous agents.
No simple-salesforce: every endpoint is a documented thin call with its
Salesforce API doc URL cited in the docstring.
Architecture
graph TD
User([User/A2A]) --> Server[A2A Server / salesforce-agent]
Server --> Agent[Pydantic AI Agent]
Agent --> MCP[MCP Server / salesforce-mcp]
MCP --> Client[Api facade / httpx]
Client --> ExternalAPI([Salesforce REST API])
Installation
pip install salesforce-agent # core client only
pip install salesforce-agent[mcp] # + FastMCP server
pip install salesforce-agent[agent] # + Pydantic AI A2A agent server
pip install salesforce-agent[jwt] # + cryptography for the JWT bearer flow
pip install salesforce-agent[all] # everything
Prebuilt Docker image: knucklessg1/salesforce-agent:latest.
MCP Tools
Five consolidated, action-routed tools. Each takes action and params_json.
| Tool | Actions | Toggle |
|---|---|---|
salesforce_soql |
query (auto-pagination via nextRecordsUrl, capped), query_all (deleted/archived), explain, search (SOSL) |
SOQLTOOL |
salesforce_records |
get (field selection), create, update, upsert (external id), delete, composite (≤25 subrequests), collections_create/collections_update (≤200 records), collections_delete |
RECORDSTOOL |
salesforce_describe |
global, sobject (fields/relationships/picklists), record_counts, limits (API usage) |
DESCRIBETOOL |
salesforce_bulk |
create_job (insert/update/upsert/delete/hardDelete), upload (CSV), close, abort, status, list_jobs, delete_job, results (successful/failed/unprocessed, size-capped) |
BULKTOOL |
salesforce_admin |
user_info, org_info, list_reports, run_report (sync, capped). Listing/running Flows is out of scope for v1. |
ADMINTOOL |
* Destructive — blocked unless SALESFORCE_ALLOW_DESTRUCTIVE=true.
Auth Flows
| Flow | Credentials | Notes |
|---|---|---|
| OAuth2 client-credentials | consumer key + secret + My Domain URL | default server-to-server flow |
| OAuth2 refresh-token | refresh token + consumer key | instance URL from token response |
| OAuth2 JWT bearer | consumer key + username + RSA key | pip install salesforce-agent[jwt] |
| Static access token | token + instance URL | testing / externally managed sessions |
Sandbox orgs: SALESFORCE_SANDBOX=true (test.salesforce.com). Tokens are
cached with expiry tracking and refreshed transparently (plus one retry on
401); secrets are redacted from all errors and logs.
Environment Variables
| Variable | Default | Purpose |
|---|---|---|
SALESFORCE_INSTANCE_URL |
— | My Domain instance URL (required for client-credentials and static tokens) |
SALESFORCE_LOGIN_URL |
derived | Override the OAuth login host |
SALESFORCE_SANDBOX |
False |
Sandbox org (test.salesforce.com) |
SALESFORCE_API_VERSION |
v62.0 |
REST API version |
SALESFORCE_AUTH_FLOW |
auto | client_credentials / refresh_token / jwt_bearer / access_token |
SALESFORCE_CLIENT_ID / SALESFORCE_CLIENT_SECRET |
— | Connected App consumer key/secret |
SALESFORCE_REFRESH_TOKEN |
— | Refresh-token flow credential |
SALESFORCE_JWT_SUBJECT / SALESFORCE_JWT_PRIVATE_KEY[_PATH] / SALESFORCE_JWT_AUDIENCE |
— | JWT bearer flow |
SALESFORCE_ACCESS_TOKEN |
— | Static access token (testing) |
SALESFORCE_TOKEN_TTL_SECONDS |
1800 |
Cached-token TTL fallback |
SALESFORCE_SSL_VERIFY |
True |
TLS verification |
SALESFORCE_TIMEOUT |
30 |
HTTP timeout (seconds) |
SALESFORCE_ALLOW_DESTRUCTIVE |
False |
Gate for all delete paths |
SALESFORCE_MAX_QUERY_RECORDS |
2000 |
Per-call SOQL pagination cap |
SALESFORCE_BULK_RESULTS_MAX_BYTES |
5000000 |
Bulk result download cap |
SALESFORCE_REPORT_MAX_ROWS |
2000 |
Sync report detail-row note (platform cap) |
HOST / PORT / TRANSPORT |
0.0.0.0 / 8000 / stdio |
MCP server bind + transport |
SOQLTOOL / RECORDSTOOL / DESCRIBETOOL / BULKTOOL / ADMINTOOL |
True |
Per-domain tool toggles |
ENABLE_OTEL / OTEL_EXPORTER_OTLP_* |
— | Telemetry (OTEL / Langfuse) |
EUNOMIA_TYPE / EUNOMIA_POLICY_FILE / EUNOMIA_REMOTE_URL |
none |
MCP authorization middleware |
AUTH_TYPE |
none |
MCP server auth mode (Docker) |
See .env.example for the full annotated list.
Quick Start
pip install salesforce-agent[all]
cp .env.example .env # fill in one auth flow
salesforce-mcp # stdio MCP server
from salesforce_agent import Api
api = Api() # configured from SALESFORCE_* env vars
rows = api.soql.query("SELECT Id, Name FROM Account", max_records=200)
api.records.upsert("Account", "External_Id__c", "X-1", {"Name": "Acme"})
Typed tool-input contracts live in
salesforce_agent.salesforce_input_models; typed error envelopes in
salesforce_agent.salesforce_response_models.
Deployment
# MCP server only (port 8000, streamable-http, /health)
docker compose -f docker/mcp.compose.yml up -d
# MCP server + A2A agent server (agent on port 9020, AG-UI web interface)
docker compose -f docker/agent.compose.yml up -d
The A2A agent server (salesforce-agent console script, agent_server.py)
reads MCP_URL, PROVIDER, and MODEL_ID from the environment. See
docs/deployment.md for transports, reverse proxy, and
DNS guidance.
See docs/ for the full overview, installation, usage, and
deployment guides; concept registry in docs/concepts.md
(CONCEPT:SFDC-1.x).
Additional Deployment Options
salesforce-agent can also run as a local container (Docker / Podman / uv) or be
consumed from a remote deployment. The
Deployment guide has full, copy-paste
mcp_config.json for all four transports — stdio, streamable-http,
local container / uv, and remote URL:
- Local container / uv — launch the server from
mcp_config.jsonviauvx,docker run, orpodman run, or point at a local streamable-http container byurl. - Remote URL — connect to a server deployed behind Caddy at
http://salesforce-mcp.arpa/mcpusing the"url"key.
Development
pip install -e .[all,test]
pytest # mocked httpx suite — no live org required
pre-commit run --all-files # must be fully green before committing
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file salesforce_agent-0.2.0.tar.gz.
File metadata
- Download URL: salesforce_agent-0.2.0.tar.gz
- Upload date:
- Size: 38.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
03c0424da534df4dac204b290a8edbca04096dc998363264752902a00dde03bc
|
|
| MD5 |
1bfffde5fbb9f18ab380716cfbcbd6fd
|
|
| BLAKE2b-256 |
3ed2b5ca70ababf255aa9d7b71e0d69d730f405e4084afc1e1dea7fa5694fdb4
|
File details
Details for the file salesforce_agent-0.2.0-py3-none-any.whl.
File metadata
- Download URL: salesforce_agent-0.2.0-py3-none-any.whl
- Upload date:
- Size: 31.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0424f10c2af4be55bf92a58bde275c8e787d8b13607a2f790d63ef5d76b7d28f
|
|
| MD5 |
32776a5d5a37c5ad9d6c00ee8640aa51
|
|
| BLAKE2b-256 |
8ac8d324908d4737be9a9dc4374e51d98d39a0f45008820a2dc59516e35ff4ea
|