# 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** (when API access is enabled), or see the [Authentication Guide](/auth-guide).
## 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",
"limit": 50
}
}'
```
### Get Available Booking 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
}
}'
```
### Send Client Message
```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": 6,
"method": "buildstability/send_client_message",
"params": {
"client_id": "uuid-here",
"message": "Just checking in - how are you feeling after yesterday'\''s session?",
"message_type": "motivation"
}
}'
```
### Create Client Note
```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": 7,
"method": "buildstability/create_client_note",
"params": {
"client_id": "uuid-here",
"title": "Session Notes - Jan 18",
"content": "Great progress on squats. Increased weight by 5kg. Focus on form next session.",
"document_type": "note"
}
}'
```
## 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)
| Plan | Rate Limit | Daily Cap |
|------|------------|-----------|
| **Free Trial** | 25 req/15min | 500/day |
| **Essential** | 50 req/15min | 1,000/day |
| **Starter** | 100 req/15min | 5,000/day |
| **Pro** | 200 req/15min | 15,000/day |
| **Studio** | 500 req/15min | 50,000/day |
### Query Complexity Limits (per request)
| Plan | Max Clients | Max Programs |
|------|-------------|--------------|
| **Essential** | 10 | 5 |
| **Starter** | 25 | 10 |
| **Pro** | 50 | 20 |
| **Studio** | 100 | 50 |
### Response Headers
All API responses include usage headers:
- `X-RateLimit-Limit` - Your rate limit
- `X-RateLimit-Remaining` - Requests remaining in window
- `X-DailyLimit-Limit` - Your daily cap
- `X-DailyLimit-Remaining` - Requests remaining today
- `X-DailyLimit-Reset` - When daily cap resets (midnight UTC)
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
- Read the [Quick Start Guide](/quickstart-mcp.md)
- Review the [Authentication Guide](/auth-guide.md)
- Check the [OpenAPI Specification](/buildstability-openapi.json)