Authentication Guide
How to authenticate with BuildStability's MCP server and API
Overview
BuildStability uses Supabase Auth for authentication. All API requests require a valid JWT (JSON Web Token) in the Authorization header.
Getting Your Access Token
Method 1: Copy Token (Easiest)
When API access is enabled for your business:
- Go to Business → Business Settings → API & Integrations
- Turn on Enable API/MCP Access if needed
- Click Copy Token — your JWT is copied to the clipboard
Use it as Authorization: Bearer <token> in MCP, PostgREST, or any API client.
Method 2: Browser / Local Storage (Quick Test)
- Log in to BuildStability at https://buildstability.com/login
- Open browser DevTools (F12) → Application → Local Storage
- Find
sb-<project-id>-auth-token - Copy the
access_tokenvalue
Method 3: Supabase Client (For Code)
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_ANON_KEY!
);
// Sign in
const { data: { session }, error } = await supabase.auth.signInWithPassword({
email: 'your@email.com',
password: 'your-password'
});
// Get access token
const accessToken = session?.access_token;Method 4: API Login Endpoint
curl -X POST https://buildstability.com/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "your@email.com",
"password": "your-password"
}'Response includes access_token and refresh_token.
What a JWT Looks Like
A JWT has three base64url-encoded segments separated by dots: header.payload.signature. The header describes the algorithm; the payload holds claims (e.g. sub, email, exp); the signature ensures integrity. Tokens are usually 200–500+ characters.
Example format (always use your own from Copy Token—tokens are user-specific and expire in 1 hour):
eyJhbGciOiJIUzI1NiIsImtpZCI6InV2YkpJdUExNWpQeFBDdXAiLCJ0eXAiOiJKV1QifQ.eyJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTc2ODc5MzM3M31dLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCIsInByb3ZpZGVycyI6WyJlbWFpbCJdfSwiYXVkIjoiYXV0aGVudGljYXRlZCIsImVtYWlsIjoibWF0dGNub3RlcysxMEBnbWFpbC5jb20iLCJleHAiOjE3Njg5MTkzNzAsImlhdCI6MTc2ODkxNTc3MCwiaXNfYW5vbnltb3VzIjpmYWxzZSwiaXNzIjoiaHR0cHM6Ly95eWJvdWlpc2xkcWl6Z2VldnFuYy5zdXBhYmFzZS5jby9hdXRoL3YxIiwicGhvbmUiOiIiLCJyb2xlIjoiYXV0aGVudGljYXRlZCIsInNlc3Npb25faWQiOiIwZGExMWFjZC1iMTA0LTRmNWUtODBhOC1mYmE5NzU0NjVjYzQiLCJzdWIiOiI3OTYzNzUwNS0xMmM4LTQyYzQtOTVmZi1kYTFhNWFlZmNjMmUiLCJ1c2VyX21ldGFkYXRhIjp7ImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJmaXJzdF9uYW1lIjoiTUFyY28iLCJsYXN0X25hbWUiOiJQb2xsbyJ9fQ.y5O4bfebJunfHq3GETKq3c-1R_KhlTkb7rM2QjJJ770
What to do with it: Put it in the Authorization: Bearer <your-token> header for MCP (POST /api/mcp), PostgREST, or any BuildStability API that uses JWT auth.
Using the Token
MCP Requests
curl -X POST https://api.buildstability.com/api/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{ ... }'Supabase PostgREST API Requests
Uses the same JWT tokens - no database credentials exposed. RLS automatically filters to your business data.
curl -X GET "https://your-project.supabase.co/rest/v1/profiles?business_id=eq.{id}" \
-H "apikey: YOUR_ANON_KEY" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json"See PostgREST API Guide for detailed usage.
Token Expiration
Access tokens expire after 1 hour. Refresh tokens are valid for 30 days.
Refreshing a Token
const { data: { session }, error } = await supabase.auth.refreshSession({
refresh_token: storedRefreshToken
});
const newAccessToken = session?.access_token;Automatic Refresh (Supabase Client)
The Supabase client automatically refreshes tokens when they expire. Use the client's onAuthStateChange listener:
supabase.auth.onAuthStateChange((event, session) => {
if (event === 'TOKEN_REFRESHED') {
console.log('Token refreshed:', session?.access_token);
}
});Security Best Practices
1. Never Commit Tokens
# .gitignore .env *.token secrets.json
2. Use Environment Variables
const accessToken = process.env.BUILDSTABILITY_ACCESS_TOKEN;
3. Store Tokens Securely
- Server-side: Use environment variables or secret management (AWS Secrets Manager, etc.)
- Client-side: Use secure storage (not localStorage for sensitive apps)
- Mobile: Use Keychain (iOS) or Keystore (Android)
4. Rotate Tokens Regularly
If a token is compromised, revoke it immediately:
await supabase.auth.signOut();
5. Use HTTPS Only
Always use https:// endpoints. Never send tokens over HTTP.
Multi-Tenancy & API Access
BuildStability uses business-level isolation with explicit API opt-in:
Security Model
- API Access Must Be Enabled: Your business administrator must enable API access before MCP endpoints work.
- Business Isolation: You can only access data for your business. All queries are automatically filtered by
business_id. - Multi-Business Support: If you belong to multiple businesses, use the
X-Business-IDheader to specify which business to access.
Enabling API Access
Business administrators can enable API access:
- Go to Business Settings → API & Integrations
- Toggle Enable API Access and save if needed
- Click Copy Token to copy your JWT to the clipboard
Multi-Business Users
If you belong to multiple businesses with API access enabled:
# Specify which business to access
curl -X POST https://api.buildstability.com/api/mcp \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Business-ID: your-business-uuid" \
-H "Content-Type: application/json" \
-d '{ ... }'Without the X-Business-ID header, the system uses your first API-enabled business.
API Keys vs Access Tokens
- Access Token (JWT): User-specific, expires after 1 hour. Use for MCP and authenticated API calls.
- Anon Key: Public, never expires. Use for unauthenticated Supabase queries (limited access).
For MCP, always use the Access Token.
Troubleshooting
"Business context required" Error
- Your token is missing or invalid
- Token has expired (refresh it)
- You're not authenticated
- API access not enabled for your business
"Invalid Request" Error
- Check your JSON-RPC format
- Verify
jsonrpc: "2.0"is present - Ensure
methodandidare included
"Method not found" Error
- Check the method name spelling
- Verify you're using the correct endpoint (
/api/mcp) - Review available methods with
tools/list