Skip to main content

Architecture Overview

ConstellationAPI is an ontology-driven, multi-tenant REST API that unifies Jira, GitHub, Confluence, and Notion behind a single interface. It combines real-time data access with a knowledge graph (Sagittarius) that builds a persistent, queryable model of your organization's operations.

The Big Picture

┌─────────────────────────────────────────────────────────────────────────────┐
│ AI Agents / LLMs / UI │
│ (Discover, Execute, Query, Visualize) │
└─────────────────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────────────┐
│ MCP Layer │
│ Model Context Protocol - AI-friendly tool discovery │
│ │
│ GET /mcp/{system}/tools → Discover available operations │
│ POST /mcp/{system}/execute → Execute any operation │
│ POST /documents/upload → Upload documents for GraphRAG │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────┴─────────────────┐
▼ ▼
┌──────────────────────────────────┐ ┌──────────────────────────────────────┐
│ Executor Engine │ │ Sagittarius Bridge │
│ Routes by capability type │ │ Injects data into knowledge graph │
│ │ │ │
│ ┌────────────┐ ┌─────────────┐ │ │ • on_user_fetched() │
│ │ Action │ │ Analytics │ │ │ • on_repository_fetched() │
│ │ Executor │ │ Executor │ │ │ • on_issue_fetched() │
│ │ │ │ │ │ │ • on_project_fetched() │
│ │ Side-effect│ │ Aggregation │ │ │ • record_activity() │
│ └─────┬──────┘ └──────┬──────┘ │ │ │
└────────┼───────────────┼─────────┘ └───────────────┬───────────────────────┘
│ │ │
▼ ▼ ▼
┌──────────────────────────────────┐ ┌──────────────────────────────────────┐
│ Analytics Layer │ │ Sagittarius Knowledge Graph │
│ │ │ (FalkorDB-backed) │
│ • DORA Metrics │ │ │
│ • Delivery Forecasting │ │ Nodes: Users, Repos, Issues, PRs, │
│ • Throughput Analytics │ │ Projects, Pages, Deployments │
│ • Engineering Productivity │ │ │
│ │ │ Edges: AUTHORED_BY, BELONGS_TO, │
│ Cross-integration correlation │ │ ASSIGNED_TO, DEPLOYED_TO │
│ Monte Carlo simulation │ │ │
│ Trend analysis │ │ Activity: User action timeline │
└──────────────────────────────────┘ └──────────────────────────────────────┘
│ │
▼ ▼
┌──────────────────────────────────────────────────────────────────────────────┐
│ Adapters Layer │
│ Raw API access - stateless, credential-driven │
│ │
│ ┌──────────┐ ┌──────────┐ ┌────────────┐ ┌──────────┐ │
│ │ GitHub │ │ Jira │ │ Confluence │ │ Notion │ │
│ │ Adapter │ │ Adapter │ │ Adapter │ │ Adapter │ │
│ └────┬─────┘ └────┬─────┘ └─────┬──────┘ └────┬─────┘ │
└────────┼──────────────┼───────────────┼───────────────┼─────────────────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌──────────────────────────────────────────────────────────────────────┐
│ External APIs │
│ GitHub API · Jira API · Confluence API · Notion API │
└──────────────────────────────────────────────────────────────────────┘

Core Design Principles

1. Stateless Multi-Tenancy

  • No database required for the API itself
  • All tenant credentials come from JWT tokens
  • Each request is self-contained with all necessary auth
  • Horizontal scaling is trivial - any instance can serve any tenant

2. Ontology-Driven Execution

  • Every capability is classified by type in the ontology
  • The executor engine routes automatically based on type
  • Adding new capabilities = adding YAML, not code changes

3. Dual Data Model

  • Transactional: Real-time API calls to external systems
  • Analytical: Persistent knowledge graph for relationships and history

4. AI-First Interface

  • MCP protocol for tool discovery and execution
  • Semantic capability descriptions
  • Graph queries for context retrieval

The Knowledge Graph (Sagittarius)

Sagittarius is a FalkorDB-backed knowledge graph that builds a persistent model of your organization as you use the API. Every API operation automatically enriches the graph.

Storage Backend

Sagittarius uses FalkorDB as its storage backend (the only supported backend). FalkorDB provides native graph queries and integrated vector search for GraphRAG.

What Gets Stored

Node TypeSourceRelationships
UserGitHub, JiraAUTHORED_BY ← PR, Issue, Page
RepositoryGitHubBELONGS_TO ← PR, Deployment
Pull RequestGitHubAUTHORED_BY → User, BELONGS_TO → Repo
IssueJiraAUTHORED_BY → User, BELONGS_TO → Project
ProjectJiraCREATED_BY → User (lead)
PageConfluenceAUTHORED_BY → User, BELONGS_TO → Space
DeploymentGitHub ActionsDEPLOYED_TO → Repository

How Data Flows In

API Call: GET /mcp/jira/execute?tool=list_issues


┌───────────────┐
│ Jira Adapter │
│ Fetches │
│ issues │
└───────┬───────┘

┌───────────┴───────────┐
▼ ▼
┌───────────────┐ ┌────────────────────┐
│ Return to │ │ Sagittarius Bridge │
│ API caller │ │ │
└───────────────┘ │ on_issue_fetched() │
│ ↓ │
│ Creates: │
│ • Issue node │
│ • Reporter user │
│ • Assignee user │
│ • Edges │
└────────────────────┘

Querying the Graph

# Get entity with all relationships
POST /graph/traverse
{
"entity_type": "user",
"entity_id": "alice",
"depth": 2
}

# Search by type
POST /graph/search
{
"entity_type": "pull_request",
"filters": {"state": "open"}
}

# Activity feed
GET /graph/feed?limit=50

Graph Visualization

Use the Constellation API endpoints to explore graph data:

  • GET /graph/stats - Graph statistics
  • GET /graph/me - Personal knowledge graph
  • POST /graph/semantic-search - Semantic search
  • POST /graph/traverse - Graph traversal

The graph is stored in FalkorDB and accessed via the Sagittarius SDK.


Capability Types

Every tool is classified in the ontology by its behavior:

Action Capabilities

Operations that change state in external systems.

github.issues.create:
type: action
side_effects: true
idempotent: false

Execution: Validate → Plan → Execute → Verify → Retry on failure

Examples: Create issue, merge PR, update ticket, delete page

Analytical Capabilities

Operations that compute metrics from one or more sources.

analytics.dora_metrics:
type: analytical
read_only: true
requires: [github]
outputs: [deployment_frequency, lead_time, change_failure_rate, mttr]

Execution: Parallel fetch → Aggregate → Correlate → Return (partial on failure)

Examples: DORA metrics, throughput analysis, delivery forecasting

Read Capabilities

Simple data retrieval operations.

github.repositories.list:
type: read
read_only: true
graph_node: repository # ← Automatically ingested to Sagittarius

Execution: Fetch → Transform → Return (+ async graph injection)

Examples: List repos, get issue, search pages


Layer Details

MCP Layer (/app/routes/mcp.py)

The thin, stable interface for AI agents:

  • Discovery: GET /mcp/{system}/tools - Returns all tools with JSON schemas
  • Execution: POST /mcp/{system}/execute - Routes to executor engine
  • Capabilities: GET /mcp/capabilities/analytics - Filter by type

The MCP layer is intentionally dumb:

  • Doesn't know execution strategies
  • Doesn't know about analytics vs actions
  • Just routes requests and returns responses

Executor Engine (/app/executor/)

The brain that routes by capability type:

# Simplified flow
capability = ontology.resolve(system, tool_name)

if capability.type == "action":
return await action_executor.execute(...)
elif capability.type == "analytical":
return await analytics_executor.execute(...)
else: # read
return await adapter.call(...)

Action Executor

  • Input validation against ontology constraints
  • Retry with exponential backoff (idempotent ops only)
  • Result verification
  • Recovery workflow on failure

Analytics Executor

  • Routes to dedicated analytics services
  • Parallel multi-source fetching
  • Graceful partial results on failure
  • Never retries aggressively

Analytics Layer (/app/analytics/)

Domain-level metrics services:

ServiceCapabilities
DoraMetricsServiceDeployment frequency, lead time, CFR, MTTR
ThroughputMetricsServiceFlow metrics, cycle time, throughput
DeliveryForecastServiceMonte Carlo simulation, risk analysis
EngineeringMetricsServicePR velocity, code review metrics

Key principle: Analytics services are integration-aware but API-agnostic. They call adapters but never see raw HTTP.

Adapter Layer (/app/adapters/)

"Dumb" adapters for raw API access:

  • Handle authentication and headers
  • Make HTTP requests
  • Parse responses
  • No business logic

Each adapter follows the same pattern:

class JiraAdapter(BaseAdapter):
async def get_issue(self, key: str) -> Dict
async def create_issue(self, data: Dict) -> Dict
async def search_issues(self, jql: str) -> List[Dict]

Data Persistence

FalkorDB (Knowledge Graph + GraphRAG)

FalkorDB stores:

  • Knowledge Graph: Nodes, edges, activities, temporal facts
  • Document Chunks: Text with embeddings for GraphRAG
  • Vector Indexes: Cosine similarity search

FalkorDB is accessed via the Redis protocol and managed through the Sagittarius SDK.

Redis (Caching Only)

Redis is used solely for API response caching:

  • DB 0: Response cache (24h TTL)
redis:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- ./data/redis:/data

Cache Strategy

GET request → Check Redis cache (DB 0)

┌───────────┴───────────┐
│ HIT │ MISS
▼ ▼
Return cached Call adapter
response │

Cache response
(24h TTL)


Return response

Activity Logging

Every MCP execution is recorded in Sagittarius:

await bridge.record_activity(
action="mcp.create_issue",
actor_type="user",
actor_id="alice@example.com", # From JWT
target_type="issue",
target_id="PROJ-123",
properties={
"system": "jira",
"success": True,
"tenant_id": "tenant-abc"
}
)

This creates a full audit trail queryable via:

  • GET /graph/feed - Global activity feed
  • POST /graph/activity - Entity-specific timeline

Directory Structure

/app
├── adapters/ # Raw API access
│ ├── github.py
│ ├── jira.py
│ ├── confluence.py
│ └── notion.py

├── analytics/ # Metrics computation
│ └── engineering/
│ ├── dora_metrics.py
│ ├── forecasting.py
│ └── throughput.py

├── executor/ # Execution routing
│ ├── engine.py
│ ├── action_executor.py
│ ├── analytics_executor.py
│ └── ontology/
│ ├── loader.py
│ └── resolver.py

├── integrations/ # Cross-cutting
│ └── sagittarius_bridge.py

├── routes/ # HTTP endpoints
│ ├── mcp.py
│ ├── graph.py
│ └── analytics.py

└── mcp/ # Configuration
├── ontology.yaml
└── tools.yaml

/sagittarius # Knowledge Graph (standalone)
├── core/
│ ├── models.py # Node, Edge, Activity
│ └── schema.py # NodeType, EdgeType
├── storage/
│ ├── redis_storage.py
│ └── memory_storage.py
├── ingest/
│ ├── handlers.py
│ └── event_types.py
└── service/
└── graph_service.py

Deployment

Development

docker-compose up -d
# API: http://localhost:3007
# Docs: http://localhost:3008
# Graph: FalkorDB via Sagittarius SDK

Production

  • Stateless API containers behind load balancer
  • FalkorDB for knowledge graph + GraphRAG
  • Redis for caching only
  • EFS volume mounts for FalkorDB data persistence

Benefits

BenefitHow
AI-ReadyMCP protocol + semantic ontology + knowledge graph
Multi-TenantJWT-based auth, no shared state
ScalableStateless API, Redis caching, horizontal scaling
ObservableActivity logging, full audit trail
MaintainableClear layer separation, ontology-driven routing
ResilientPartial results, retry with backoff, graceful degradation