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.
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 Type | Source | Relationships |
|---|---|---|
| User | GitHub, Jira | AUTHORED_BY ← PR, Issue, Page |
| Repository | GitHub | BELONGS_TO ← PR, Deployment |
| Pull Request | GitHub | AUTHORED_BY → User, BELONGS_TO → Repo |
| Issue | Jira | AUTHORED_BY → User, BELONGS_TO → Project |
| Project | Jira | CREATED_BY → User (lead) |
| Page | Confluence | AUTHORED_BY → User, BELONGS_TO → Space |
| Deployment | GitHub Actions | DEPLOYED_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 statisticsGET /graph/me- Personal knowledge graphPOST /graph/semantic-search- Semantic searchPOST /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:
| Service | Capabilities |
|---|---|
DoraMetricsService | Deployment frequency, lead time, CFR, MTTR |
ThroughputMetricsService | Flow metrics, cycle time, throughput |
DeliveryForecastService | Monte Carlo simulation, risk analysis |
EngineeringMetricsService | PR 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 feedPOST /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
| Benefit | How |
|---|---|
| AI-Ready | MCP protocol + semantic ontology + knowledge graph |
| Multi-Tenant | JWT-based auth, no shared state |
| Scalable | Stateless API, Redis caching, horizontal scaling |
| Observable | Activity logging, full audit trail |
| Maintainable | Clear layer separation, ontology-driven routing |
| Resilient | Partial results, retry with backoff, graceful degradation |
Related Documentation
- Getting Started - Quick start guide
- MCP API Reference - Tool discovery and execution
- Ontology Guide - Capability definitions
- Graph Endpoints - Knowledge graph API