Local Federation Overview
Two Ways to Run Federation Locally
There are two approaches to running federated services on your machine:
./fedCLI (incred-local-workspace) -- orchestrates the full multi-service stack: commercial-api, model-api, filter-api, Apollo Router, MCP, and agent-ai. Use this when you need the complete platform.start-local-model-federation.sh(incred-api-commercial) -- a lighter script that starts only commercial-api + model-api behind a local Apollo Router. Use this when you only need commercial + model and want a faster startup.
This documentation covers the fed CLI. For the per-repo script, see API Development > Full Local Model API.
What Is Local Federation?
CRED's backend is a federated GraphQL system -- multiple API subgraphs compose into a single schema behind an Apollo Router. In production, each subgraph runs as a separate Cloud Run service. Local federation replicates this architecture on your machine so you can develop and test cross-service features without deploying.
The fed CLI automates the entire lifecycle: preflight validation, dependency-ordered startup, health checking, environment injection, database bootstrapping, and log capture.
Architecture
graph TD
Web["Web Frontend :8002"] --> Router
iOS["iOS App"] --> Router
AgentAI["Agent AI :8080"] --> Router
AgentAI --> MCP
Router["Apollo Router :4000"] --> Commercial
Router --> Model
Router --> Filter
Commercial["Commercial API :8000"] --> CommDB["Commercial DB :5432<br/>(Local Docker)"]
Commercial --> CommRedis["Redis :6379"]
Commercial --> CommWorker["Worker (BullMQ)"]
Model["Model API :3000"] --> ModelDB["Model DB<br/>(Remote Dev)"]
Model --> ModelRedis["Redis :6380"]
Filter["Filter API :8081"] --> FilterDB["Filter DB<br/>(Remote Dev)"]
Filter --> FilterRedis["Redis :6382"]
Filter --> ES["Elasticsearch<br/>(Remote Dev)"]
MCP["GraphQL MCP :5000"] --> Router
Port Allocation
| Service | API Port | Debug Port | Redis Port | Notes |
|---|---|---|---|---|
| Commercial API | 8000 | 9222 | 6379 | |
| Commercial DB | 5432 | -- | -- | Local Docker PostgreSQL |
| Model API | 3000 | 9223 | 6380 | Remapped from default 8000/9222/6379 |
| Filter API | 8081 | 9224 | 6382 | Remapped from default 8000/9222/6379 |
| Apollo Router | 4000 | -- | -- | Managed by commercial-api compose |
| Agent AI | 8080 | 9329 | 6379 | |
| GraphQL MCP | 5000 | -- | -- | |
| Web Frontend | 8002 | -- | -- | Not started by fed -- run manually |
Auth Server Port Conflict
cred-auth defaults to port 3000, which conflicts with model-api in local federation. Auth server is not part of the federation stack. If you need to run it simultaneously, override its port: PORT=3001 npm run start:dev.
Service Dependency Graph
Services start in dependency order. Services with no mutual dependencies start in parallel.
graph LR
ModelAPI["Model API"] --> Commercial["Commercial API"]
FilterAPI["Filter API"] -.-> Commercial
Commercial --> Router["Apollo Router"]
Commercial --> Worker["Commercial Worker"]
Commercial --> DB["Commercial DB"]
Router --> MCP["GraphQL MCP"]
Commercial --> AgentAI["Agent AI"]
style FilterAPI stroke-dasharray: 5 5
style MCP stroke-dasharray: 5 5
style AgentAI stroke-dasharray: 5 5
Dashed borders indicate optional services that can be skipped with --skip.
Startup order:
- Model API (port 3000) -- Docker Compose up, HTTP health check, seed query validation
- Filter API (optional, port 8081) -- starts in parallel with model-api
- Commercial API codegen -- introspects model-api schema, generates TypeScript client
- Commercial API + Apollo Router (ports 8000, 4000) --
docker compose --profile with_federation up -d - Database bootstrap -- FDW setup, build + migrate + seed, file cache clear, credentity bootstrap, custom fields
- Commercial Worker -- BullMQ background job processor
- GraphQL MCP (optional, port 5000) -- depends on router
- Agent AI (optional, port 8080) -- depends on commercial-api
Minimum viable stack: Model API + Commercial API (which includes the router). Filter API, MCP, and Agent AI are optional.
Where Data Lives
During local federation, only the commercial API has a local database. All other data sources are remote.
| Data Source | Local or Remote | Details |
|---|---|---|
| Commercial API DB | Local (Docker) | PostgreSQL 17, cred_commercial database, seeded by yarn prep-db |
| Model API DBs (3) | Remote (dev) | Connection strings in .env point to GCP Cloud SQL via PgBouncer |
| Filter API DBs (3) | Remote (dev) | Same remote databases as model-api and commercial-api |
| Elasticsearch | Remote (dev) | Elastic Cloud cluster (ES_CLOUD_ID + ES_API_KEY) |
| Redis | Local (Docker) | Each service starts its own Redis container |
Remote Database Safety
Model-api and filter-api connect to real remote dev databases shared by other developers and CI pipelines. Never run write operations (INSERT, UPDATE, DELETE, DROP) against remote databases without explicit approval. The local commercial-api database is safe to experiment on -- it can be reset with yarn prep-db.
Services
Commercial API
Primary backend -- CRM data, business logic, workers. TypeScript, Express, Apollo Federation, Knex/Objection, BullMQ. Owns contacts, accounts, deals, workspaces, integrations, workflows, custom fields, and outreach sequences.
Model API
Predictions, enrichment, ML model serving. TypeScript, Express, Apollo Federation, Knex. Owns CRED-provided intelligence: predictions, enrichment, companies, persons, market data, and search.
Filter API
Data filtering, dynamic entity schemas, Elasticsearch search. TypeScript, Express, Apollo Federation, Knex/pg, Elasticsearch. Owns filter metadata, filter options, Elasticsearch entity search, and runtime-generated dynamic entity schemas.
Apollo Router
Composes the supergraph from all subgraphs and handles query routing. Runs rover supergraph compose on startup. Managed by the commercial-api Docker Compose stack (not a separate service).
Agent AI
LLM-powered assistant (Claude Sonnet). TypeScript, NestJS 11, LangChain, Anthropic SDK. Processes messages from Slack, Teams, WebSocket, and GraphQL through a LangGraph agent with MCP tool calling.
GraphQL MCP
Exposes 46 predefined GraphQL operations as MCP tools via a Rust binary. Part of the cred-mcp repo. Uses Streamable HTTP transport.
Default Seed Credentials
The database seed runs when NODE_ENV is local or test. It creates these accounts:
| Password | Company | Role | |
|---|---|---|---|
admin@credinvestments.com |
P@ssword01 |
CRED (id: 450931) | ADMIN |
test@credinvestments.com |
P@ssword01 |
Test company | -- |
test2@credinvestments.com |
P@ssword01 |
Test company | -- |
Shared Secrets
These secrets must be coordinated across services. The fed CLI handles injection automatically via env_inject blocks in fed.toml.
| Secret | Commercial API | Model API | Filter API | Agent AI |
|---|---|---|---|---|
| JWT HMAC key | JWT_SECRET |
COMMERCIAL_JWT_SECRET |
COMMERCIAL_JWT_SECRET |
JWT_SECRET |
| Model API token | CRED_MODEL_API_TOKEN |
API_TOKEN |
-- | -- |
| Redis | REDISCLOUD_URL |
REDISCLOUD_URL |
REDISCLOUD_URL |
REDIS_URL |
The JWT HMAC key must be the same value across all services -- it is how they validate each other's tokens. The model API static token (CRED_MODEL_API_TOKEN = API_TOKEN) is how commercial API authenticates to model API.