Synapse AI Execution Server
Allows sending emails via Gmail.
Provides tools for interacting with Salesforce CRM, including loading agent definitions, performing CRUD operations on records, and writing audit logs.
Allows sending emails via SendGrid.
Allows sending messages to Slack channels.
Allows sending SMS messages via Twilio.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Synapse AI Execution ServerRun the lead nurturing agent graph for the last 24 hours."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Synapse AI — Execution Server
Node.js + TypeScript server that runs Synapse AI agent graphs. Salesforce stores config and audit; this server does all AI inference and MCP tool execution so Apex stays inside governor limits.
Architecture
Salesforce org Synapse AI server (this repo)
┌───────────────────┐ JWT-signed HTTPS ┌─────────────────────────────┐
│ AgentBuilder UI │ ────────────────────▶ │ POST /agent/execute │
│ AgentRunner.cls │ Named Credential │ ├ verify JWT │
│ Trigger handlers │ "Agent_Platform" │ ├ load AgentDefinition │
│ │ ◀── Platform Event ─── │ ├ walk graph │
│ AgentExecution__c │ AgentExecutionResult │ ├ exec nodes │
└───────────────────┘ │ │ ├ claude (ai-models) │
│ │ ├ get/update record │
│ │ └ if/else, loop ... │
│ └ publish result event │
└─────────────────────────────┘Related MCP server: MCP Salesforce Connector
Prerequisites
Node.js ≥ 20 (the SDK and
tsxneed modern Node)A Salesforce dev/sandbox org with the Synapse AI metadata deployed
An Anthropic API key (
sk-ant-...)ngrok (or any tunneling tool) for local dev, OR a public host (Heroku, Fly.io, AWS Lambda + API Gateway, etc.) for production
opensslfor generating the JWT secret and SF Connected App cert
1. Install
cd server
npm install2. Configure environment
cp .env.example .envGenerate a JWT secret:
openssl rand -hex 32
# paste the output as JWT_SECRET in .envSet ANTHROPIC_API_KEY to your key from https://console.anthropic.com/.
The Salesforce values (SF_CLIENT_ID, SF_USERNAME, SF_PRIVATE_KEY_PATH) come from step 4.
3. Run the server
Dev mode (auto-reload):
npm run devProduction:
npm run build
npm startYou should see synapse_ai_server_started in the log and GET /health returning {"status":"ok"}.
4. Wire Salesforce → server
4a. Expose the server publicly (dev)
ngrok http 3000
# → https://abc123.ngrok-free.appIn Setup → Named Credentials → Agent Platform:
Endpoint: paste the ngrok URL (no trailing slash)
Save
4b. Make Salesforce sign requests with your JWT secret
Salesforce's Named Credential alone can send an unsigned bearer header. To get HMAC-signed JWTs that this server can verify, customers usually:
Option A — Use an External Credential (recommended for production)
Setup → External Credentials → New
Authentication Protocol: Custom
Authentication Parameters: add
JwtSecret= the same hex string inJWT_SECRETLink the External Credential to the
Agent_PlatformNamed CredentialWrite a small
HttpCalloutActionApex class (or use Flow HTTP Callouts) that mints a JWT in Apex usingCrypto.generateMac('HmacSHA256', ...)and setsAuthorization: Bearer <jwt>on the request
Option B — Quick dev shortcut
In AgentBuilderController.executeAgent and AgentRunner.callExternalEngine, sign the JWT inline before the callout:
String jwt = mintHs256Jwt(new Map<String,Object>{
'orgId' => UserInfo.getOrganizationId(),
'userId' => UserInfo.getUserId(),
'agentApiName' => agentApiName,
'iat' => DateTime.now().getTime()/1000,
'exp' => (DateTime.now().getTime()/1000) + 300 // 5 min
}, jwtSecretFromCustomMetadata());
req.setHeader('Authorization', 'Bearer ' + jwt);Where mintHs256Jwt does the base64url(header) + base64url(payload) + HMAC-SHA256 signature. We can add this helper in a follow-up commit.
4c. Configure the server's own SF connection (for callbacks + MCP)
The server logs in to Salesforce as itself (a System Integration user) to load agent definitions and write audit logs back. Use JWT Bearer Token Flow:
openssl req -x509 -nodes -newkey rsa:2048 -keyout keys/server.key -out keys/server.crt -days 365 -subj "/CN=SynapseAIServer"Setup → App Manager → New Connected App:
Enable OAuth Settings
Check Use digital signatures, upload
server.crtOAuth Scopes:
api,refresh_token,offline_accessSave
Copy the Consumer Key into
SF_CLIENT_IDIn Setup → Manage Apps → the new app → Manage → Permitted Users: Admin approved, then pre-authorize a System Integration user via a permission set
Set
SF_USERNAMEto that user's usernameSF_PRIVATE_KEY_PATH=./keys/server.key
5. End-to-end test
Deploy SF metadata:
sf project deploy start --target-org <your-org>Assign the permission set:
sf org assign permset --name AgentBuilderUserOpen the Synapse AI app from the App Launcher
Click + New Agent, drag a Record trigger → Claude AI → End, save with name "Lead Qualifier" and ApiName
lead_qualifier, set Status to ActiveFrom the Test Runner: enter a Lead ID, click Run agent
Watch the server log — you should see
claude_call_completewithcache_creationon the first call, thencache_read > 0on subsequent calls (proving the knowledge-base prompt cache is working)
Project layout
src/
├── index.ts Express entry, mounts routers, error handler
├── config.ts Typed env config
├── logger.ts pino logger
├── types.ts Shared types (AgentDefinition, NodeResult, ...)
├── auth/jwt.ts JWT verify middleware
├── routes/
│ ├── agent.routes.ts POST /agent/execute, GET /agent/status/:id
│ └── health.routes.ts GET /health
├── orchestrator/
│ ├── engine.ts runAgent() — BFS walks the graph
│ ├── context.ts ExecutionContext + {!var} interpolation
│ └── graph.ts Builds adjacency map from CanvasJson__c
├── nodes/
│ ├── registry.ts subType → executor lookup
│ ├── trigger.ts record / schedule / webhook / platform_event
│ ├── ai.ts claude (real), gpt4 / einstein / sentiment (stubs)
│ ├── action.ts get/update/create/query record, create_task, post_chatter
│ ├── channel.ts outlook / gmail / sendgrid / twilio / slack / teams (stubs)
│ ├── logic.ts if_else (real), loop / wait / approval
│ └── end.ts
├── mcp/
│ ├── registry.ts MCP server name lookup
│ └── servers/
│ ├── ai-models.ts Claude integration (Opus 4.7 + adaptive thinking + prompt caching)
│ └── salesforce-crm.ts jsforce-backed CRUD + SOQL
└── salesforce/
├── client.ts jsforce JWT-bearer login, loadAgentDefinition()
└── callback.ts Publishes AgentExecutionResult__e eventsAdding a new node type
Create or pick an MCP server under
src/mcp/servers/Write the executor in
src/nodes/<category>.tsand callregister('your_subtype', execFn)Import the file in
src/orchestrator/engine.ts(side-effect import — runs theregister()call)Add the field schema to
agentPropertiesPanel.jsso the canvas UI shows config inputsAdd an entry to
NODE_PALETTEinagentCanvas.jsso the node appears in the palette
Adding a new MCP server
Create
src/mcp/servers/<name>.tsand export typed functions (callX,queryY, ...)Add
<name>to theMCP_SERVERSconst insrc/mcp/registry.tsReference the server from node executors via direct function imports
When the official MCP wire protocol stabilizes, swap the direct imports for an MCP client that dispatches by node.mcpServer + node.mcpTool — the registry is already shaped for this.
Deploying to production
Heroku/Fly.io: works out of the box. Set the same env vars in the dashboard. Use
npm run build && npm startas the start command.AWS Lambda + API Gateway: wrap the express app with
serverless-http— note that JWT-bearer SF logins should be cached in a warm container or pulled from Secrets Manager.Containerized: a 2-stage Dockerfile (build with full deps, run with
node:20-alpine) is the standard path.
Cost considerations
The first call to a given agent writes the knowledge-base prompt cache (~1.25× input cost)
Every call after that reads it (~0.1× input cost) — this is why we put the KB at the top of
systemwithcache_controlAdaptive thinking +
effort: "high"on Opus 4.7 gives the best quality; drop tomediumif you need lower per-call costFor latency-sensitive use cases, swap
claude-opus-4-7→claude-haiku-4-5per node — the UI exposes this in the properties panel
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/SfdcAnnu/Archon-Server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server