A TypeScript API for UA Managers to query, aggregate, and export campaign performance data. Built with Express.js and designed for deployment on Railway.com.
- Campaign Listing: Paginated campaign data with comprehensive filtering
- Individual Campaign Details: Get specific campaign information by ID
- Metrics Aggregation: Group and aggregate campaign metrics by various dimensions
- Data Export: Export filtered campaign data as CSV or JSON
- Authentication: API key-based authentication
- Type Safety: Full TypeScript implementation with comprehensive type definitions
- MCP Server: Model Context Protocol server for LLM integration (Claude, ChatGPT, Cursor, etc.)
- WebSocket Support: Real-time connections for MCP clients
- JWT Authentication: Secure token-based authentication for MCP clients
Based on the OpenAPI specification in Documentation/ua_openapi.yml:
GET /api/v1/campaigns- List campaigns with filters and paginationGET /api/v1/campaigns/:id- Get single campaign by IDGET /api/v1/metrics/aggregate- Get aggregated metricsGET /api/v1/exports- Export campaigns as CSV or JSONGET /api/v1/health- Health check endpoint
For LLM integration via Model Context Protocol:
WebSocket /mcp- MCP WebSocket connectionPOST /api/v1/mcp/auth/token- Generate MCP access tokenPOST /api/v1/mcp/auth/validate- Validate MCP tokenGET /api/v1/mcp/tools- List available MCP toolsGET /api/v1/mcp/info- MCP server informationGET /api/v1/mcp/health- MCP server health check
-
Install dependencies:
npm install
-
Set up environment:
cp .env.example .env # Edit .env with your configuration -
Add your campaign data:
mkdir -p data # Place your campaigns.json file in the data directory -
Start development server:
npm run dev
The API will be available at http://localhost:3000
npm run build
npm startPlace your campaign data in data/campaigns.json. The expected format is an array of campaign objects:
[
{
"id": "unique-campaign-id",
"game": "Game Name",
"campaign_name": "Campaign Name",
"network": "Network Name",
"store": "ios",
"month": "2024-01",
"acquired_users": 1000,
"cpi": 2.50,
"roas": {
"ROAS d0": "0.15",
"ROAS d7": "0.45",
"ROAS d30": "1.20",
"ROAS d365": "3.50"
},
"retention": {
"Retention d0": "100%",
"Retention d7": "25%",
"Retention d30": "12%",
"Retention d365": "5%"
}
}
]- Railway Account: Sign up at railway.app
- GitHub Repository: Push your code to GitHub
- Environment Variables: Prepare your production environment variables
-
Connect Repository:
- Go to Railway dashboard
- Click "New Project"
- Select "Deploy from GitHub repo"
- Choose your repository
-
Configure Environment Variables:
NODE_ENV=production API_KEY=your-production-api-key CORS_ORIGIN=https://your-domain.railway.app DATA_FILE_PATH=./data/campaigns.json BASE_URL=https://your-domain.railway.app -
Upload Data File:
- Use Railway's file upload feature or
- Include the data file in your repository (not recommended for sensitive data)
-
Deploy:
- Railway will automatically build and deploy your application
- The build process uses the
railway.jsonconfiguration
The project includes:
railway.json- Railway-specific deployment configurationDockerfile- Container configuration (optional)- Health check endpoint at
/api/v1/health
- Go to your Railway project settings
- Navigate to "Domains"
- Add your custom domain
- Update the
BASE_URLenvironment variable
| Variable | Description | Default | Required |
|---|---|---|---|
PORT |
Server port | 3000 |
No |
NODE_ENV |
Environment | development |
No |
API_KEY |
API authentication key | - | Yes (production) |
CORS_ORIGIN |
CORS allowed origins | * |
No |
DATA_FILE_PATH |
Path to campaigns JSON file | ./data/campaigns.json |
No |
BASE_URL |
Base URL for export links | http://localhost:3000 |
No |
MCP_JWT_SECRET |
JWT secret for MCP authentication | - | Yes (production) |
MCP_AUTH_ENABLED |
Enable MCP authentication | true |
No |
MCP_ALLOWED_CLIENTS |
Allowed MCP client IDs | claude,chatgpt,cursor,vscode,continue |
No |
MCP_CORS_ORIGIN |
CORS origins for MCP | https://claude.ai,https://chat.openai.com,https://cursor.sh |
No |
curl "https://your-api.railway.app/api/v1/campaigns?game=MyGame&store=ios&page=1&page_size=10" \
-H "X-API-Key: your-api-key"curl "https://your-api.railway.app/api/v1/metrics/aggregate?group_by=network&metric=cpi&aggregation=avg" \
-H "X-API-Key: your-api-key"curl "https://your-api.railway.app/api/v1/exports?format=csv" \
-H "X-API-Key: your-api-key"This API includes a Model Context Protocol (MCP) server that allows LLM applications to directly access campaign data.
-
Generate Access Token:
curl -X POST "https://your-app.up.railway.app/api/v1/mcp/auth/token" \ -H "Content-Type: application/json" \ -d '{"client_id": "claude"}'
-
Connect from Claude Desktop:
{ "mcpServers": { "campaign-performance": { "url": "wss://your-app.up.railway.app/mcp", "auth": "Bearer YOUR_ACCESS_TOKEN" } } } -
Available Tools:
list_campaigns- Query campaign data with filtersget_campaign- Get specific campaign detailsaggregate_metrics- Aggregate metrics by dimensionsexport_campaigns- Export data as CSV/JSONhealth_check- Check API health
For detailed MCP setup instructions, see Documentation/MCP_CLIENT_GUIDE.md.
- Connect Repository: Link your GitHub repository to Railway
- Set Environment Variables: Configure
API_KEY,MCP_JWT_SECRET, and other required variables - Deploy: Railway will automatically build and deploy your application
The application will be available at https://your-app-name.up.railway.app
# Build the image
docker build -t campaign-performance-api .
# Run the container
docker run -p 3000:3000 \
-e API_KEY=your-api-key \
-e MCP_JWT_SECRET=your-mcp-secret \
-e NODE_ENV=production \
campaign-performance-apisrc/
├── types/ # TypeScript type definitions
├── routes/ # Express route handlers
├── services/ # Business logic services
├── middleware/ # Express middleware
├── utils/ # Utility functions
└── index.ts # Application entry point
npm run dev- Start development server with hot reloadnpm run build- Build TypeScript to JavaScriptnpm start- Start production servernpm test- Run tests (placeholder)
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
ISC