Jake Shore f3c4cd817b Add all MCP servers + factory infra to MCPEngine — 2026-02-06
=== NEW SERVERS ADDED (7) ===
- servers/closebot — 119 tools, 14 modules, 4,656 lines TS (Stage 7)
- servers/google-console — Google Search Console MCP (Stage 7)
- servers/meta-ads — Meta/Facebook Ads MCP (Stage 8)
- servers/twilio — Twilio communications MCP (Stage 8)
- servers/competitor-research — Competitive intel MCP (Stage 6)
- servers/n8n-apps — n8n workflow MCP apps (Stage 6)
- servers/reonomy — Commercial real estate MCP (Stage 1)

=== FACTORY INFRASTRUCTURE ADDED ===
- infra/factory-tools — mcp-jest, mcp-validator, mcp-add, MCP Inspector
  - 60 test configs, 702 auto-generated test cases
  - All 30 servers score 100/100 protocol compliance
- infra/command-center — Pipeline state, operator playbook, dashboard config
- infra/factory-reviews — Automated eval reports

=== DOCS ADDED ===
- docs/MCP-FACTORY.md — Factory overview
- docs/reports/ — 5 pipeline evaluation reports
- docs/research/ — Browser MCP research

=== RULES ESTABLISHED ===
- CONTRIBUTING.md — All MCP work MUST go in this repo
- README.md — Full inventory of 37 servers + infra docs
- .gitignore — Updated for Python venvs

TOTAL: 37 MCP servers + full factory pipeline in one repo.
This is now the single source of truth for all MCP work.
2026-02-06 06:32:29 -05:00

279 lines
7.8 KiB
Markdown

# Meta Ads MCP Server
A production-grade Model Context Protocol (MCP) server for the Meta Marketing API with intelligent lazy-loading architecture.
## 🌟 Key Features
- **Lazy Loading Architecture**: Core tools load immediately, advanced features load on-demand
- **Production-Ready**: Comprehensive rate limiting, caching, and error handling
- **Type-Safe**: Full TypeScript with strict mode and Zod validation
- **MCP Annotations**: All tools include proper metadata (readOnly, destructive, idempotent hints)
- **Smart Rate Limiting**: Tracks Meta's three-tier rate limits with exponential backoff
- **Token Management**: Automatic validation, expiry tracking, and refresh support
## 📦 Installation
```bash
npm install
npm run build
```
## ⚙️ Configuration
Create a `.env` file from the example:
```bash
cp .env.example .env
```
Required environment variables:
- `META_ACCESS_TOKEN`: Your Meta Marketing API access token
- `META_APP_ID`: (Optional) Your Facebook App ID for enhanced security
- `META_APP_SECRET`: (Optional) Your App Secret for appsecret_proof
- `META_API_VERSION`: (Optional) API version, defaults to v21.0
### Getting Access Tokens
1. **User Access Token**: Via [Facebook Graph API Explorer](https://developers.facebook.com/tools/explorer/)
- Select your app
- Request permissions: `ads_read`, `ads_management`, `business_management`
- Generate token
2. **Long-Lived Token**: Exchange short-lived for long-lived (60 days)
- Requires App ID and App Secret
- Server can auto-refresh using `AuthManager.refreshToLongLivedToken()`
3. **System User Token**: Recommended for production
- Created in Business Manager
- Never expires (until revoked)
- Most secure option
## 🚀 Usage
### Development Mode
```bash
npm run dev
```
### Production Mode
```bash
npm run build
npm start
```
### As MCP Server
Add to your MCP client configuration (e.g., Claude Desktop):
```json
{
"mcpServers": {
"meta-ads": {
"command": "node",
"args": ["/path/to/meta-ads-mcp/dist/index.js"],
"env": {
"META_ACCESS_TOKEN": "your_token_here"
}
}
}
}
```
## 🏗️ Architecture
### Lazy Loading System
The server uses a two-tier module loading strategy:
#### Tier 1: Core Modules (Load on Startup)
- **Account**: `list_ad_accounts`, `get_account_info`, `get_account_pages`, `get_business_info`, `get_pixel_list`
- **Campaigns**: `list_campaigns`, `get_campaign`, `create_campaign`, `update_campaign`, `toggle_campaign`, `duplicate_campaign`, `delete_campaign`
- **Ad Sets**: `list_ad_sets`, `get_ad_set`, `create_ad_set`, `update_targeting`, `update_ad_set_budget`, `update_schedule`, `toggle_ad_set`
- **Ads**: `list_ads`, `get_ad`, `create_image_ad`, `create_video_ad`, `create_carousel_ad`, `create_dynamic_ad`, `preview_creative`, `upload_media`, `list_creatives`
#### Tier 2: Advanced Modules (Lazy Loaded)
- **Analytics**: Gateway tool `analytics_tools` loads full insights and reporting suite
- **Audiences**: Gateway tool `audiences_tools` loads custom audience management
- **Budget**: Gateway tool `budget_tools` loads optimization and recommendation tools
**How Lazy Loading Works:**
1. Tier 2 modules register a single gateway tool (e.g., `audience_tools`)
2. When called, the gateway loads the full module and re-registers all its tools
3. Client sees: "Module loaded, please retry with specific tool"
4. Subsequent calls use the now-loaded tools directly
### Infrastructure Components
#### `AuthManager` (`src/auth/oauth.ts`)
- Token validation via `debug_token` endpoint
- HMAC-SHA256 `appsecret_proof` generation
- Token expiry tracking
- Long-lived token refresh
#### `RateLimiter` (`src/client/rate-limiter.ts`)
- Parses Meta's three rate limit headers:
- `x-app-usage`: App-level limits
- `x-business-use-case-usage`: Business-level limits
- `x-ad-account-usage`: Account-level limits (200 calls/hour)
- Exponential backoff at 75% and 90% thresholds
- Request queue with priority system
- Configurable concurrency (default: 5)
#### `MetaApiClient` (`src/client/meta-client.ts`)
- Generic `get<T>()`, `post<T>()`, `delete<T>()` methods
- Automatic `appsecret_proof` injection
- Cursor-based pagination: `getAllPages<T>()`
- Typed error handling with `MetaApiError`
- Media upload support (images and videos)
#### `SimpleCache` (`src/client/cache.ts`)
- In-memory TTL-based caching
- Prefix-based invalidation
- `getOrCompute()` for cache-aside pattern
- Max entries enforcement (LRU-style)
## 🛠️ Tool Annotations
Every tool includes MCP annotations:
```typescript
annotations: {
title: "Human-readable name",
readOnlyHint: true, // No state changes
destructiveHint: false, // Can't be undone
idempotentHint: true, // Safe to retry
openWorldHint: false, // Doesn't access external data
}
```
### Tool Categories
**Read-Only Tools**: All list/get operations
**Idempotent Tools**: Updates, toggles (safe to retry)
**Non-Destructive Creates**: Campaign/ad set/ad creation
**Destructive Tools**: Delete operations (require confirmation)
## 📊 Rate Limiting
Meta enforces three types of rate limits:
1. **App-Level**: Calls per hour across all users
2. **Business Use Case**: Per business, per hour
3. **Ad Account**: 200 calls/hour per account ⚠️ Most restrictive
The `RateLimiter` automatically:
- Monitors all three metrics
- Throttles at 75% usage
- Pauses at 90% usage
- Applies exponential backoff
- Respects `estimatedTimeToRegainAccess` headers
## 🔒 Security
- **appsecret_proof**: HMAC signature on every request (when app secret provided)
- **Token Validation**: Checks token validity on startup
- **No Token Logging**: Credentials never logged
- **.env Support**: Secrets in environment, not code
## 📝 TypeScript
Strict mode enabled with:
- No implicit `any`
- Strict null checks
- Unused variable detection
- Comprehensive type definitions in `src/types/meta-api.ts`
## 🧪 Example Workflows
### Create a Campaign with Ad Set and Image Ad
```typescript
// 1. List accounts
list_ad_accounts()
// 2. Create campaign
create_campaign({
account_id: "act_123456",
name: "Q1 2025 Campaign",
objective: "OUTCOME_TRAFFIC",
daily_budget: "5000", // $50
status: "PAUSED"
})
// 3. Create ad set
create_ad_set({
campaign_id: "123456789",
name: "US Desktop Traffic",
optimization_goal: "LINK_CLICKS",
billing_event: "IMPRESSIONS",
daily_budget: "2000", // $20
targeting: {
age_min: 25,
age_max: 55,
genders: [1, 2],
geo_locations: { countries: ["US"] },
publisher_platforms: ["facebook"],
device_platforms: ["desktop"]
}
})
// 4. Upload image (stub - needs file handling)
upload_media({
account_id: "act_123456",
file_path: "/path/to/image.jpg",
media_type: "image"
})
// 5. Create ad
create_image_ad({
account_id: "act_123456",
adset_id: "987654321",
name: "Homepage Ad",
page_id: "111222333",
image_hash: "abc123hash",
link: "https://example.com",
headline: "Shop Now",
message: "Limited time offer!",
call_to_action_type: "SHOP_NOW",
status: "ACTIVE"
})
```
## 🐛 Debugging
Set `NODE_ENV=development` for verbose logging:
```bash
NODE_ENV=development npm run dev
```
Logs go to stderr (MCP convention):
- `[MCP] Module loaded: campaigns`
- `[MCP] Registered tool: create_campaign`
- Rate limit warnings appear automatically
## 📚 API Documentation
- [Meta Marketing API Reference](https://developers.facebook.com/docs/marketing-apis/)
- [MCP Protocol Specification](https://modelcontextprotocol.io/)
- [Campaign Structure Guide](https://developers.facebook.com/docs/marketing-api/campaign-structure/)
## 🤝 Contributing
1. Follow existing patterns for tool registration
2. Use Zod schemas with `.describe()` on every field
3. Include comprehensive MCP annotations
4. Handle errors gracefully with typed responses
5. Add JSDoc comments for complex logic
## 📄 License
MIT
## 🙏 Credits
Built for Clawdbot by the Meta Ads MCP team.