Skip to content

Local Federation Overview

Two Ways to Run Federation Locally

There are two approaches to running federated services on your machine:

  • ./fed CLI (in cred-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 (in cred-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:

  1. Model API (port 3000) -- Docker Compose up, HTTP health check, seed query validation
  2. Filter API (optional, port 8081) -- starts in parallel with model-api
  3. Commercial API codegen -- introspects model-api schema, generates TypeScript client
  4. Commercial API + Apollo Router (ports 8000, 4000) -- docker compose --profile with_federation up -d
  5. Database bootstrap -- FDW setup, build + migrate + seed, file cache clear, credentity bootstrap, custom fields
  6. Commercial Worker -- BullMQ background job processor
  7. GraphQL MCP (optional, port 5000) -- depends on router
  8. 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:

Email 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.