Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 47,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here

Works with

Claude CodeClaude DesktopCursorVS CodeClineCodex CLIOpenClaw+ any MCP client

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

Enables Salesforce Agentforce agents to find compatible replacement batteries, check store inventory, and create store visit summaries for battery service handoffs.

README.md

Batteries Plus MCP Demo Server

A production-ready Model Context Protocol (MCP) server for the Batteries Plus Service Workflow demo. This server connects Salesforce Agentforce agents to Batteries Plus product catalog, store inventory, and service handoff capabilities.

What This Server Does

This MCP server enables Salesforce Agentforce agents to:

  1. Find Compatible Replacement Batteries — Match customer vehicles to the right battery using product fit logic
  2. Check Store Availability — Find nearby stores with inventory and service capabilities
  3. Create Store Visit Summaries — Generate service handoffs for in-store battery testing and installation

Demo Story: A customer's car won't start. The agent identifies the right replacement battery, checks local availability, and creates a store visit summary—all without human handoff.

What This Server Does NOT Do

This is a service workflow demo, not a transactional system. It explicitly does NOT:

  • Create orders, reservations, or POS transactions
  • Process payments or checkout flows
  • Take employee-attributed actions

Architecture

  • MCP SDK: @modelcontextprotocol/sdk v1.0.4
  • Transport: Streamable HTTP (recommended for remote MCP servers)
  • Runtime: Node.js 20+ with TypeScript
  • Authentication: OAuth 2.0 Client Credentials OR none mode for fast testing
  • Data Storage: In-memory (optionally persisted to /tmp for handoffs)
  • Deployment: Render.com (free tier)

Project Structure

batteries-plus-mcp/
├── src/
│   ├── server.ts                   # Express + MCP SDK + tool registration
│   ├── auth.ts                     # OAuth 2.0 implementation
│   ├── data/
│   │   ├── batteries.ts            # Vehicle fit database
│   │   └── stores.ts               # Store + inventory database
│   ├── services/
│   │   ├── handoffStore.ts         # In-memory handoff storage
│   │   └── salesforceWriter.ts     # Placeholder for Salesforce integration
│   ├── tools/
│   │   ├── findCompatibleReplacement.ts   # MCP tool 1
│   │   ├── checkStoreAvailability.ts      # MCP tool 2
│   │   └── createStoreHandoff.ts          # MCP tool 3
│   └── utils/
│       ├── ids.ts                  # Handoff ID generation
│       └── validation.ts           # Input validation utilities
├── test/
│   └── smoke.test.js               # Basic health checks
├── package.json
├── tsconfig.json
├── render.yaml                      # Render deployment config
└── .env.example                     # Environment template

Quick Start

Prerequisites

  • Node.js 20+
  • npm 9+

Local Development

  1. Clone and Install
   cd batteries-plus-mcp
   npm install
  1. Configure Environment
   cp .env.example .env

For fast local testing, use MCP_AUTH_MODE=none: ``env PORT=3000 NODE_ENV=development MCP_AUTH_MODE=none WRITE_MODE=memory ``

  1. Start Dev Server
   npm run dev

The server starts at http://localhost:3000 with hot-reload enabled.

  1. Verify Health
   curl http://localhost:3000/health

Expected response: ``json { "status": "healthy", "service": "batteries-plus-service-mcp", "version": "1.0.0", "auth_mode": "none", "write_mode": "memory", "uptime_seconds": 12.4, "handoffs_created": 0 } ``

Production Build

npm run build    # Compile TypeScript to ./dist
npm start        # Run compiled server

Environment Variables

| Variable | Required | Default | Description | |---|---|---|---| | PORT | No | 3000 | Server port | | NODE_ENV | No | development | Runtime environment | | MCP_AUTH_MODE | No | none | Auth mode: none or oauth | | MCP_CLIENT_ID | OAuth only | — | OAuth client ID | | MCP_CLIENT_SECRET | OAuth only | — | OAuth client secret | | MCP_TOKEN_TTL_SECONDS | No | 3600 | Token lifetime (1 hour) | | WRITE_MODE | No | memory | Handoff storage: memory or salesforce |

For Render deployment, set MCP_AUTH_MODE=oauth and configure MCP_CLIENT_ID and MCP_CLIENT_SECRET in the Render dashboard.

API Endpoints

GET /health

Health check endpoint. Returns server status, auth mode, uptime, and handoff count.

POST /oauth/token

OAuth 2.0 token endpoint (only active when MCP_AUTH_MODE=oauth).

Request: ``bash curl -X POST https://your-server.onrender.com/oauth/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials" \ -d "client_id=YOUR_CLIENT_ID" \ -d "client_secret=YOUR_CLIENT_SECRET" ``

Response: ``json { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "expires_in": 3600, "scope": "mcp.tools" } ``

POST /mcp

MCP protocol endpoint. Agentforce sends tool requests here via Streamable HTTP transport.

GET /demo/handoffs

View all store visit summaries created by the agent. Returns HTML in browsers, JSON for API clients.

MCP Tools

1. find_compatible_replacement

Finds a compatible replacement battery for a customer's vehicle.

Input: ``json { "vehicle_year": 2019, "vehicle_make": "Honda", "vehicle_model": "CR-V", "vehicle_engine": "1.5L L4", "postal_code": "53202" } ``

Output: ``json { "fit_status": "compatible", "fit_confidence": "high", "vehicle": { "year": 2019, "make": "Honda", "model": "CR-V", "engine": "1.5L L4" }, "recommended_product": { "sku": "SLI51RAGM", "name": "X2Power Premium AGM Battery - Group 51R", "group_size": "51R", "cold_cranking_amps": 500, "reserve_capacity_minutes": 90, "warranty_months": 36, "install_eligible": true }, "recommendation_reason": "This battery matches the vehicle's group size and cold-cranking amp requirements." } ``

2. check_store_availability

Checks nearby Batteries Plus stores for a specific SKU.

Input: ``json { "sku": "SLI51RAGM", "postal_code": "53202", "radius_miles": 15 } ``

Output: ``json { "sku": "SLI51RAGM", "postal_code": "53202", "availability_status": "available_nearby", "stores": [ { "store_id": "BP-MKE-001", "store_name": "Batteries Plus - Milwaukee East", "address": "2401 S. Kinnickinnic Ave, Milwaukee, WI 53207", "distance_miles": 2.3, "phone": "(414) 555-0101", "today_hours": "8:00 AM - 7:00 PM", "quantity_available": 4, "service_context": { "battery_testing_available": true, "installation_available": true, "estimated_service_time": "20-30 minutes", "note": "Store can test the current battery before installation." } } ] } ``

3. create_store_handoff

Creates a store visit summary after the customer selects a store. This tool will block unless customer_confirmed_store is true.

Input: ``json { "customer_name": "Jane Doe", "customer_issue": "Car will not start", "vehicle_year": 2019, "vehicle_make": "Honda", "vehicle_model": "CR-V", "vehicle_engine": "1.5L L4", "recommended_sku": "SLI51RAGM", "recommended_product_name": "X2Power Premium AGM Battery - Group 51R", "selected_store_id": "BP-MKE-001", "selected_store_name": "Batteries Plus - Milwaukee East", "availability_result": "4 units available", "customer_confirmed_store": true } ``

Output: ``json { "status": "created", "handoff_id": "SVS-20260622-1430", "created_at": "2026-06-22T14:30:12.456Z", "service_workflow": "Store Visit Summary", "summary": { "customer_issue": "Car will not start", "vehicle": "2019 Honda CR-V 1.5L L4", "recommended_sku": "SLI51RAGM", "recommended_product_name": "X2Power Premium AGM Battery - Group 51R", "selected_store": "Batteries Plus - Milwaukee East", "availability_result": "4 units available", "store_note": "Customer may need battery testing before replacement. Store has installation available today." }, "demo_record_url": "https://example.salesforce.com/lightning/r/Store_Visit_Summary__c/SVS-20260622-1430/view" } ``

Testing Locally

Smoke Tests

npm test

Runs basic health checks on /health and /demo/handoffs.

Manual Tool Testing

You can test MCP tools manually using curl (when MCP_AUTH_MODE=none):

Example: List Tools ``bash curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }' ``

Example: Call Tool ``bash curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "find_compatible_replacement", "arguments": { "vehicle_year": 2019, "vehicle_make": "Honda", "vehicle_model": "CR-V" } } }' ``

Deploying to Render

Initial Setup

  1. Create Render Account
  1. Push to GitHub
   git init
   git add .
   git commit -m "Initial commit: Batteries Plus MCP server"
   git remote add origin https://github.com/YOUR_USERNAME/batteries-plus-mcp.git
   git push -u origin main
  1. Create Render Service
  • Dashboard → New +Web Service
  • Connect repository: batteries-plus-mcp
  • Render auto-detects render.yaml
  1. Configure Environment Variables (in Render dashboard)
  • MCP_CLIENT_ID = batteries-plus-agentforce-client (or your custom value)
  • MCP_CLIENT_SECRET = Generate a strong secret (e.g., openssl rand -base64 32)
  1. Deploy
  • Render automatically builds and deploys
  • Wait for "Live" status (2-3 minutes)
  1. Note Your MCP Endpoint URL

Your server URL will be: https://batteries-plus-mcp.onrender.com

Your MCP Endpoint URL for Salesforce registration is: `` https://batteries-plus-mcp.onrender.com/mcp ``

Health Check

curl https://batteries-plus-mcp.onrender.com/health

Render Free Tier Notes

  • Server sleeps after 15 minutes of inactivity
  • First request after sleep takes ~30-60 seconds to wake up
  • Monthly limit: 750 hours (adequate for demos)
  • For production, upgrade to paid tier for always-on service

Salesforce Agentforce Setup

Step 1: Authenticate Salesforce CLI

If you haven't already authenticated to your Salesforce org:

sf org login web --alias batteries-demo

Use your admin credentials (not the Agentforce agent user credentials).

Step 2: Register the MCP Server in Agentforce Registry

Manual steps (you will do this in the Salesforce UI):

  1. Open Salesforce Setup
  • Login to your Salesforce org
  • Setup → Quick Find → "Agentforce"
  1. Register MCP Server
  • Agentforce → Agentforce RegistryMCP Servers tab
  • Click Register MCP Server
  1. Enter Connection Details

| Field | Value | |---|---| | MCP Server Name | Batteries Plus Service | | MCP Endpoint URL | https://batteries-plus-mcp.onrender.com/mcp | | Authorization Token URL | https://batteries-plus-mcp.onrender.com/oauth/token | | Client ID | batteries-plus-agentforce-client | | Client Secret | Your MCP_CLIENT_SECRET from Render | | Scope | mcp.tools |

Click Save & Test Connection. You should see "✅ Connection successful".

  1. Manage Tools
  • After saving, click Manage Tools
  • You should see 3 tools:
  • find_compatible_replacement
  • check_store_availability
  • create_store_handoff
  • Select all 3 and click Allow and Continue
  • Click Save

Step 3: Add Tools to Your Agent

  1. Open Agentforce Builder
  • Setup → Agentforce → Agents
  • Select or create your agent (e.g., "Batteries Plus Agent")
  1. Add Actions
  • In the agent builder, go to Actions & Instructions
  • Click Add Action
  • Search for "batteries" or "compatible"
  • Add all 3 MCP tools:
  • find_compatible_replacement
  • check_store_availability
  • create_store_handoff
  1. Configure Agent Instructions

Add this to your agent instructions:

   You are the Batteries Plus Service Agent. You help customers find the right replacement battery, check local store availability, and create store visit summaries.

   When a customer describes a vehicle issue (e.g., "car won't start"), follow this workflow:

   1. Ask for vehicle details: year, make, model (and engine if possible)
   2. Use find_compatible_replacement to identify the right battery
   3. Ask for customer location (postal code)
   4. Use check_store_availability to find nearby stores with inventory
   5. Present store options with availability, distance, and services
   6. IMPORTANT: Wait for the customer to confirm their store choice
   7. Only after confirmation, use create_store_handoff with customer_confirmed_store=true

   Do not create orders, reservations, or process payments. Your role is to prepare a service handoff for in-store battery testing and installation.
  1. Activate the Agent
  • Click Activate in the agent builder
  • Choose your deployment channel (e.g., Salesforce Experience Cloud, Messaging for In-App and Web)

Step 4: Test the Agent

Test Conversation Script:

Customer: My car won't start and I think I need a new battery. I drive a 2019 Honda CR-V and I'm near 53202. Can you help me find the right one nearby?

Expected Agent Behavior:

  1. Agent calls find_compatible_replacement → identifies SLI51RAGM (X2Power Premium AGM Battery - Group 51R)
  2. Agent calls check_store_availability → finds stores near 53202
  3. Agent presents: "I found the X2Power Premium AGM Battery - Group 51R for your 2019 Honda CR-V. The closest store with availability is Batteries Plus - Milwaukee East (2.3 miles away, 4 units in stock). They offer free battery testing and installation. Would you like me to create a store visit summary?"
  4. Customer confirms: "Yes, that works for me."
  5. Agent calls create_store_handoff with customer_confirmed_store=true
  6. Agent responds: "Great! I've created a store visit summary (ID: SVS-20260622-1430). The store knows you're coming and can test your current battery before replacement. Installation takes 20-30 minutes."

Troubleshooting

Problem: MCP tools don't appear in Agentforce actions picker

  • Switch to legacy Agentforce Builder (toggle at top of screen)
  • Verify that Agentforce MCP Support Pilot permission is enabled on your org

Problem: Connection test fails with "401 Unauthorized"

  • Check that MCP_CLIENT_ID and MCP_CLIENT_SECRET match between Render and Salesforce
  • Verify MCP_AUTH_MODE=oauth is set in Render environment

Problem: Tools return empty or error responses

  • Check Render logs: Dashboard → batteries-plus-mcpLogs
  • Add debug header in Salesforce: Setup → Named Credentials → Custom Headers → x-sfdc-mcp-debug = 0x3f

Problem: Agent doesn't use MCP tools

  • Review agent instructions—ensure tools are mentioned in the workflow
  • Check agent trace logs: Agent Builder → Session History → select test session

Development Notes

Adding New Vehicles

Edit src/data/batteries.ts and add entries to the vehicleFitDatabase array:

{
  vehicle_year: 2022,
  vehicle_make: 'Tesla',
  vehicle_model: 'Model 3',
  vehicle_engine: 'Electric',
  recommended_sku: 'EV12V-AUX',
  product_name: 'Auxiliary 12V Battery for Tesla',
  group_size: 'Tesla OEM',
  cold_cranking_amps: 340,
  reserve_capacity_minutes: 50,
  warranty_months: 24,
  install_eligible: false
}

Adding New Stores

Edit src/data/stores.ts and add entries to the storeDatabase array:

{
  store_id: 'BP-CHI-004',
  store_name: 'Batteries Plus - Chicago Loop',
  postal_codes: ['60601', '60602'],
  address: '123 State St, Chicago, IL 60601',
  distance_miles: 0.5,
  phone: '(312) 555-0200',
  today_hours: '9:00 AM - 6:00 PM',
  services: ['Battery testing', 'Battery installation', 'Curbside pickup'],
  inventory: {
    'SLI51RAGM': 3,
    'SLI24FAGM': 2,
    'SLI35AGM': 5
  }
}

Enabling Salesforce Write Mode

This is for future integration. To write handoffs to Salesforce instead of memory:

  1. Set WRITE_MODE=salesforce in .env
  2. Add Salesforce credentials:
   SF_LOGIN_URL=https://login.salesforce.com
   SF_CLIENT_ID=<connected_app_consumer_key>
   SF_CLIENT_SECRET=<connected_app_consumer_secret>
   SF_USERNAME=<integration_user_username>
   SF_PASSWORD=<integration_user_password>
   SF_INSTANCE_URL=https://yourorg.my.salesforce.com
  1. Implement Salesforce REST API calls in src/services/salesforceWriter.ts

Current implementation throws "not yet implemented" when WRITE_MODE=salesforce.

Technical Details

MCP Protocol

This server implements MCP via Streamable HTTP transport (recommended for remote servers). Agentforce sends JSON-RPC 2.0 requests to the /mcp endpoint using Server-Sent Events (SSE) for streaming responses.

Supported Methods:

  • tools/list — Returns tool schemas
  • tools/call — Executes a tool with provided arguments

Authentication Flow

When MCP_AUTH_MODE=oauth:

  1. Agentforce requests a token from /oauth/token using client credentials grant
  2. Server validates client_id and client_secret
  3. Server issues a JWT signed with MCP_CLIENT_SECRET
  4. Agentforce includes Authorization: Bearer <token> on subsequent /mcp requests
  5. Server validates JWT signature and checks issued token set

Tokens expire after MCP_TOKEN_TTL_SECONDS (default: 1 hour).

Data Storage

  • Batteries Fit Database: In-memory array in src/data/batteries.ts
  • Store Database: In-memory array in src/data/stores.ts
  • Handoff Storage: In-memory Map with optional persistence to /tmp/batteries-plus-handoffs.json

For production, replace with:

  • PostgreSQL or Snowflake for product/store data
  • Redis for token management
  • Salesforce REST API for handoff records

License

MIT

Support

For issues or questions about this demo server, contact:

  • Alisha Christy (alishachisty@outlook.com)
  • Open an issue in the GitHub repository

---

Built with Model Context Protocol SDK v1.0.4

See related servers & alternatives →

Related MCP servers

Browse all →

Related guides

Hand-picked reading to help you choose and use CRM & Sales servers.