Back to Developers
Code Snippets

Code Examples

Ready-to-use code snippets for integrating with BuildStability's MCP server and API. Get your token: Business Settings → API & Integrations → Copy Token — or see the Auth Guide.

View Raw Markdown

TypeScript/Node.js

Basic MCP Client

typescript
interface JsonRpcRequest {
  jsonrpc: '2.0';
  id: string | number;
  method: string;
  params?: Record<string, unknown>;
}

interface JsonRpcResponse {
  jsonrpc: '2.0';
  id: string | number | null;
  result?: unknown;
  error?: {
    code: number;
    message: string;
    data?: unknown;
  };
}

class BuildStabilityMCP {
  private baseUrl = 'https://api.buildstability.com/api/mcp';
  private accessToken: string;

  constructor(accessToken: string) {
    this.accessToken = accessToken;
  }

  async call(method: string, params?: Record<string, unknown>): Promise<unknown> {
    const request: JsonRpcRequest = {
      jsonrpc: '2.0',
      id: Date.now(),
      method,
      params
    };

    const response = await fetch(this.baseUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.accessToken}`
      },
      body: JSON.stringify(request)
    });

    const data: JsonRpcResponse = await response.json();

    if (data.error) {
      throw new Error(`MCP Error ${data.error.code}: ${data.error.message}`);
    }

    return data.result;
  }

  async checkChurnRisk(threshold = 40) {
    return this.call('buildstability/check_churn_risk', { threshold });
  }

  async getClientSummary(clientId: string) {
    return this.call('buildstability/get_client_summary', { client_id: clientId });
  }

  async listActivePrograms(limit = 10) {
    return this.call('buildstability/list_active_programs', { limit });
  }

  async getBusinessStats() {
    return this.call('buildstability/get_business_stats');
  }
}

// Usage
const mcp = new BuildStabilityMCP('your-access-token');
const atRiskClients = await mcp.checkChurnRisk(40);
console.log(atRiskClients);

Python

Python MCP Client

python
import requests
import json
from typing import Optional, Dict, Any

class BuildStabilityMCP:
    def __init__(self, access_token: str):
        self.base_url = "https://api.buildstability.com/api/mcp"
        self.access_token = access_token
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {access_token}"
        }

    def call(self, method: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        request = {
            "jsonrpc": "2.0",
            "id": 1,
            "method": method,
            "params": params or {}
        }

        response = requests.post(
            self.base_url,
            headers=self.headers,
            json=request
        )
        response.raise_for_status()
        data = response.json()

        if "error" in data:
            error = data["error"]
            raise Exception(f"MCP Error {error['code']}: {error['message']}")

        return data.get("result")

    def check_churn_risk(self, threshold: int = 40) -> Dict[str, Any]:
        return self.call("buildstability/check_churn_risk", {"threshold": threshold})

    def get_client_summary(self, client_id: str) -> Dict[str, Any]:
        return self.call("buildstability/get_client_summary", {"client_id": client_id})

    def list_active_programs(self, limit: int = 10) -> Dict[str, Any]:
        return self.call("buildstability/list_active_programs", {"limit": limit})

    def get_business_stats(self) -> Dict[str, Any]:
        return self.call("buildstability/get_business_stats")

# Usage
mcp = BuildStabilityMCP("your-access-token")
at_risk = mcp.check_churn_risk(threshold=40)
print(f"Found {at_risk['at_risk_count']} clients at risk")

JavaScript (Browser)

Browser MCP Client

javascript
class BuildStabilityMCP {
  constructor(accessToken) {
    this.baseUrl = 'https://api.buildstability.com/api/mcp';
    this.accessToken = accessToken;
  }

  async call(method, params = {}) {
    const request = {
      jsonrpc: '2.0',
      id: Date.now(),
      method,
      params
    };

    const response = await fetch(this.baseUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.accessToken}`
      },
      body: JSON.stringify(request)
    });

    const data = await response.json();

    if (data.error) {
      throw new Error(`MCP Error ${data.error.code}: ${data.error.message}`);
    }

    return data.result;
  }

  async checkChurnRisk(threshold = 40) {
    return this.call('buildstability/check_churn_risk', { threshold });
  }

  async getClientSummary(clientId) {
    return this.call('buildstability/get_client_summary', { client_id: clientId });
  }
}

// Usage
const mcp = new BuildStabilityMCP('your-access-token');
mcp.checkChurnRisk(40).then(result => {
  console.log(`Found ${result.at_risk_count} clients at risk`);
});

cURL Examples

List Available Tools

bash
curl -X POST https://api.buildstability.com/api/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list"
  }'

Check Churn Risk

bash
curl -X POST https://api.buildstability.com/api/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "buildstability/check_churn_risk",
    "params": {
      "threshold": 40
    }
  }'

Get Today's Schedule

bash
curl -X POST https://api.buildstability.com/api/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "buildstability/get_schedule",
    "params": {
      "date": "today"
    }
  }'

List All Clients

bash
curl -X POST https://api.buildstability.com/api/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "jsonrpc": "2.0",
    "id": 4,
    "method": "buildstability/list_clients",
    "params": {
      "status": "active"
    }
  }'

Get Available Slots

bash
curl -X POST https://api.buildstability.com/api/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "jsonrpc": "2.0",
    "id": 5,
    "method": "buildstability/get_available_slots",
    "params": {
      "date": "2025-01-20",
      "duration_minutes": 60
    }
  }'

REST API (OAuth 2.0)

For integrations and server-side apps. Auth: OAuth 2.0 Client Credentials. REST API Guide · OAuth 2.0

Get access token

bash
curl -X POST https://buildstability.com/api/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET"

List clients

bash
curl -X GET "https://buildstability.com/api/v1/clients?status=active&limit=20" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Revenue summary

bash
curl -X GET "https://buildstability.com/api/v1/revenue?period=month" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

OpenAPI: /buildstability-rest-api.json

Error Handling Example

typescript
try {
  const result = await mcp.getClientSummary('invalid-id');
} catch (error) {
  if (error.message.includes('-32602')) {
    console.error('Invalid parameters provided');
  } else if (error.message.includes('-32001')) {
    console.error('Authentication required');
  } else {
    console.error('Unexpected error:', error);
  }
}

Rate Limiting

BuildStability enforces rate limits to ensure fair usage and cost protection:

Rate Limits (per 15-minute window)

  • Free Trial: 25 requests per 15 minutes
  • Essential: 50 requests per 15 minutes
  • Starter: 100 requests per 15 minutes
  • Pro: 200 requests per 15 minutes
  • Pro+: 500 requests per 15 minutes

Daily Caps

  • Free Trial: 500 requests per day
  • Essential: 1,000 requests per day
  • Starter: 5,000 requests per day
  • Pro: 15,000 requests per day
  • Pro+: 50,000 requests per day

Query Limits (per request)

  • Essential: 10 clients, 5 programs per query
  • Starter: 25 clients, 10 programs per query
  • Pro: 50 clients, 20 programs per query
  • Pro+: 100 clients, 50 programs per query

Handle rate limits gracefully with exponential backoff:

typescript
async function callWithRetry(mcp: BuildStabilityMCP, method: string, params: any, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await mcp.call(method, params);
    } catch (error: any) {
      if (error.message.includes('429') && i < maxRetries - 1) {
        const waitTime = Math.pow(2, i) * 1000; // Exponential backoff
        await new Promise(resolve => setTimeout(resolve, waitTime));
        continue;
      }
      throw error;
    }
  }
}

Next Steps