Skip to main content

Graph API

The Graph API provides access to the Sagittarius knowledge graph - a persistent model of entities and relationships built automatically as you use the API.

Base URL

/graph

Endpoints

Get Entity

Retrieve a single entity by type and ID.

POST /graph/entity

Request Body:

{
"entity_type": "user",
"entity_id": "alice"
}

Response:

{
"success": true,
"data": {
"node_type": "user",
"node_id": "alice",
"properties": {
"login": "alice",
"name": "Alice Chen",
"email": "alice@example.com",
"avatar_url": "https://..."
},
"source": "github",
"created_at": "2024-12-30T10:00:00Z",
"updated_at": "2024-12-30T15:30:00Z"
}
}

Traverse Graph

Explore connected entities starting from a node.

POST /graph/traverse

Request Body:

{
"entity_type": "user",
"entity_id": "alice",
"depth": 2,
"edge_types": ["AUTHORED_BY", "BELONGS_TO"],
"direction": "both"
}
ParameterTypeRequiredDescription
entity_typestringYesStarting node type
entity_idstringYesStarting node ID
depthintegerNoMax hops (1-5, default: 2)
edge_typesarrayNoFilter by edge types
directionstringNo"out", "in", or "both" (default: "both")

Response:

{
"success": true,
"data": {
"nodes": [
{
"node_type": "user",
"node_id": "alice",
"properties": {"name": "Alice Chen", "login": "alice"}
},
{
"node_type": "pull_request",
"node_id": "org/repo/123",
"properties": {"title": "Add feature", "state": "open"}
},
{
"node_type": "repository",
"node_id": "org/repo",
"properties": {"full_name": "org/repo", "language": "TypeScript"}
}
],
"edges": [
{
"from_node": "pull_request:org/repo/123",
"to_node": "user:alice",
"edge_type": "AUTHORED_BY"
},
{
"from_node": "pull_request:org/repo/123",
"to_node": "repository:org/repo",
"edge_type": "BELONGS_TO"
}
]
},
"metadata": {
"node_count": 3,
"edge_count": 2
}
}

Search Entities

Search for entities by type with optional filters.

POST /graph/search

Request Body:

{
"entity_type": "issue",
"filters": {
"status": "In Progress"
},
"limit": 50
}
ParameterTypeRequiredDescription
entity_typestringYesNode type to search
filtersobjectNoProperty filters (exact match)
limitintegerNoMax results (1-100, default: 50)

Response:

{
"success": true,
"data": [
{
"node_type": "issue",
"node_id": "PROJ-123",
"properties": {
"key": "PROJ-123",
"summary": "Implement SSO",
"status": "In Progress",
"priority": "High"
}
}
],
"metadata": {
"count": 1
}
}

Find Path

Find the shortest path between two entities.

POST /graph/find-path

Request Body:

{
"from_type": "user",
"from_id": "alice",
"to_type": "repository",
"to_id": "org/api",
"max_depth": 5
}

Response:

{
"success": true,
"data": {
"nodes": [
"user:alice",
"pull_request:org/api/45",
"repository:org/api"
],
"edges": [
{
"from_node": "pull_request:org/api/45",
"to_node": "user:alice",
"edge_type": "AUTHORED_BY"
},
{
"from_node": "pull_request:org/api/45",
"to_node": "repository:org/api",
"edge_type": "BELONGS_TO"
}
],
"length": 2
},
"metadata": {
"path_found": true
}
}

Get Relationships

Get edges for a specific entity.

POST /graph/relationships

Request Body:

{
"entity_type": "pull_request",
"entity_id": "org/repo/123"
}

Query Parameters:

  • edge_type (optional): Filter by edge type
  • direction: "out", "in", or "both" (default: "both")
  • limit: Max edges to return (default: 100)

Response:

{
"success": true,
"data": [
{
"edge_type": "AUTHORED_BY",
"from_node": {"node_type": "pull_request", "node_id": "org/repo/123"},
"to_node": {"node_type": "user", "node_id": "alice"}
},
{
"edge_type": "BELONGS_TO",
"from_node": {"node_type": "pull_request", "node_id": "org/repo/123"},
"to_node": {"node_type": "repository", "node_id": "org/repo"}
}
],
"metadata": {
"count": 2
}
}

Get Activity Feed

Get the global activity feed.

GET /graph/feed?limit=50

Response:

{
"success": true,
"data": [
{
"action": "mcp.create_issue",
"actor_type": "user",
"actor_id": "alice@example.com",
"target_type": "issue",
"target_id": "PROJ-124",
"timestamp": "2024-12-30T15:45:00Z",
"properties": {
"system": "jira",
"success": true
}
}
],
"metadata": {
"count": 1
}
}

Get Entity Activity

Get activity timeline for a specific entity.

POST /graph/activity

Request Body:

{
"entity_type": "user",
"entity_id": "alice",
"limit": 20
}

Get Unified Context

Get comprehensive context for an entity including relationships, connected entities, and activity.

POST /graph/context

Request Body:

{
"entity_type": "user",
"entity_id": "alice"
}

Response:

{
"success": true,
"data": {
"entity": {
"node_type": "user",
"node_id": "alice",
"properties": {...}
},
"outgoing_relationships": [...],
"incoming_relationships": [...],
"connected_entities": [...],
"recent_activity": [...]
},
"metadata": {
"outgoing_count": 5,
"incoming_count": 12,
"connected_count": 15,
"activity_count": 8
}
}

Get Graph Statistics

Get overall graph statistics.

GET /graph/stats

Response:

{
"success": true,
"data": {
"total_nodes": 156,
"total_edges": 423,
"global_feed_size": 89,
"nodes_by_type": {
"user": 15,
"repository": 8,
"pull_request": 45,
"issue": 67,
"project": 5,
"page": 12,
"deployment": 4
}
}
}

Graph Visualizer

Interactive web UI for exploring the graph.

GET /graph/visualizer

Returns an HTML page with:

  • Force-directed graph visualization
  • Entity type filtering
  • Multi-select capabilities
  • Cypher-like query interface
  • Real-time stats

Context Injection

Inject user-specific contextual data into the knowledge graph. Context nodes are linked to Users and can reference other entities.

Inject Context

POST /graph/context/inject

Headers:

  • X-JWT-Token: Required - User identity extracted from token

Request Body:

{
"context_type": "focus",
"key": "current_project",
"value": "ACME",
"metadata": {"priority": "high"},
"ttl_seconds": 3600,
"references": [
{"entity_type": "project", "entity_id": "ACME"}
]
}
ParameterTypeRequiredDescription
context_typestringYesType: focus, preference, session, activity
valueanyYesAny JSON-serializable value
keystringNoOptional identifier key
metadataobjectNoAdditional metadata
ttl_secondsintegerNoTime-to-live in seconds
referencesarrayNoEntity references to link

Response:

{
"success": true,
"data": {
"context_id": "ctx_abc123def456",
"user_id": "alice@example.com",
"context_type": "focus"
}
}

Query User Context

POST /graph/context/query

Request Body:

{
"user_id": "alice@example.com",
"context_type": "focus"
}

Response:

{
"success": true,
"data": [
{
"node_type": "context",
"node_id": "ctx_abc123def456",
"properties": {
"context_type": "focus",
"key": "current_project",
"value": "ACME",
"user_id": "alice@example.com",
"expires_at": "2024-12-30T17:00:00Z"
}
}
],
"metadata": {
"count": 1
}
}

Get User Context (by path)

GET /graph/context/user/{user_id}?context_type=focus

Same response as Query User Context.


Delete Context

DELETE /graph/context/{context_id}

Response:

{
"success": true,
"data": {
"message": "Context ctx_abc123def456 deleted successfully"
}
}

Entity Types

TypeDescriptionKey Properties
userPersonlogin, name, email, account_id
repositoryGitHub repofull_name, language, description
pull_requestGitHub PRnumber, title, state, author
issueJira issuekey, summary, status, priority
projectJira projectkey, name, lead
pageConfluence pageid, title, space_key
spaceConfluence spacekey, name
deploymentDeploymentid, environment, status
notion_pageNotion pageid, title
notion_databaseNotion DBid, title
contextUser contextcontext_type, key, value, user_id, expires_at

Edge Types

TypeFrom → ToDescription
AUTHORED_BYPR, Issue, Page → UserCreator relationship
ASSIGNED_TOIssue → UserAssignment
BELONGS_TOPR → Repo, Issue → ProjectContainment
DEPLOYED_TODeployment → RepositoryTarget
CREATED_BYProject → UserLead/owner
CONTRIBUTES_TOUser → Repo, ProjectContribution
LINKED_TOIssue ↔ PR, Page ↔ IssueCross-reference
REVIEWED_BYPR → UserCode review
HAS_CONTEXTUser → ContextUser's contextual data
REFERENCESContext → AnyContext entity reference

Development Endpoints

These endpoints are only available in development mode (localhost):

Clear Graph

POST /graph/clear

Deletes all nodes, edges, and activity from the graph.

Seed Demo Data

POST /graph/seed

Seeds the graph with sample data for testing.

Error Responses

{
"success": false,
"error": "Entity not found: user:unknown",
"metadata": null
}

Common errors:

  • Entity not found - The requested node doesn't exist
  • Invalid entity type - Unknown node type
  • Traversal limit exceeded - Too many nodes in traversal