Get Project Map
curl --request GET \
--url https://api.example.com/api/v1/memory/project-mapimport requests
url = "https://api.example.com/api/v1/memory/project-map"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/api/v1/memory/project-map', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/memory/project-map",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/memory/project-map"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/api/v1/memory/project-map")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/memory/project-map")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"memories": [
{}
],
"memories[].id": "<string>",
"memories[].memory": "<string>",
"memories[].metadata": {},
"memories[].metadata.memory_type": "<string>",
"memories[].metadata.path": "<string>",
"memories[].metadata.component_type": "<string>",
"count": 123
}Memory
Get Project Map
Retrieve comprehensive project structure and codebase overview
GET
/
api
/
v1
/
memory
/
project-map
Get Project Map
curl --request GET \
--url https://api.example.com/api/v1/memory/project-mapimport requests
url = "https://api.example.com/api/v1/memory/project-map"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/api/v1/memory/project-map', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/memory/project-map",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/memory/project-map"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/api/v1/memory/project-map")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/memory/project-map")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"memories": [
{}
],
"memories[].id": "<string>",
"memories[].memory": "<string>",
"memories[].metadata": {},
"memories[].metadata.memory_type": "<string>",
"memories[].metadata.path": "<string>",
"memories[].metadata.component_type": "<string>",
"count": 123
}Overview
Get a structured map of the projectβs codebase, including directory organization, module descriptions, and architectural overview. This endpoint is optimized for onboarding new developers and providing context to AI code reviewers.Authentication
Requires a valid JWT token in theAuthorization header:
Authorization: Bearer YOUR_JWT_TOKEN
Query Parameters
string
required
Repository to query in
owner/repo format (e.g., βacme/api-serverβ)Response
array
Array of project map memory objects describing codebase structure
string
Unique memory ID
string
Description of a specific part of the codebase (directory, module, or file)
object
Metadata about the memory
string
Always βproject_mapβ for this endpoint
string
File or directory path being described
string
Type of component: βdirectoryβ, βmoduleβ, βserviceβ, βapiβ, βmodelβ, etc.
integer
Total number of project map entries
Example Request
curl -X GET "https://api.nectr.ai/api/v1/memory/project-map?repo=acme/api-server" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
import requests
response = requests.get(
"https://api.nectr.ai/api/v1/memory/project-map",
headers={"Authorization": f"Bearer {token}"},
params={"repo": "acme/api-server"}
)
data = response.json()
print(f"Project has {data['count']} documented components\n")
for memory in data['memories'][:10]:
path = memory['metadata'].get('path', 'Unknown')
print(f"π {path}")
print(f" {memory['memory']}\n")
const response = await fetch(
'https://api.nectr.ai/api/v1/memory/project-map?repo=acme/api-server',
{
headers: {
'Authorization': `Bearer ${token}`
}
}
);
const data = await response.json();
console.log(`Project has ${data.count} documented components`);
data.memories.slice(0, 10).forEach(memory => {
console.log(`π ${memory.metadata.path}`);
console.log(` ${memory.memory}`);
});
Example Response
{
"memories": [
{
"id": "mem_proj_001",
"memory": "Main application module containing FastAPI app initialization, middleware configuration, and route registration.",
"metadata": {
"memory_type": "project_map",
"path": "app/main.py",
"component_type": "module",
"repo": "acme/api-server"
}
},
{
"id": "mem_proj_002",
"memory": "API v1 endpoints organized by resource type. Contains routes for users, reviews, analytics, and memory management.",
"metadata": {
"memory_type": "project_map",
"path": "app/api/v1/",
"component_type": "directory",
"repo": "acme/api-server"
}
},
{
"id": "mem_proj_003",
"memory": "SQLAlchemy models defining database schema. Includes Event, WorkflowRun, Installation, and User models.",
"metadata": {
"memory_type": "project_map",
"path": "app/models/",
"component_type": "directory",
"repo": "acme/api-server"
}
},
{
"id": "mem_proj_004",
"memory": "Database configuration and session management. Implements async SQLAlchemy engine with connection pooling.",
"metadata": {
"memory_type": "project_map",
"path": "app/core/database.py",
"component_type": "module",
"repo": "acme/api-server"
}
},
{
"id": "mem_proj_005",
"memory": "GitHub API client wrapper providing methods for PR data retrieval, repository stats, and webhook processing.",
"metadata": {
"memory_type": "project_map",
"path": "app/integrations/github/",
"component_type": "service",
"repo": "acme/api-server"
}
},
{
"id": "mem_proj_006",
"memory": "Mem0 memory adapter service for storing and retrieving AI-learned context about the codebase and contributors.",
"metadata": {
"memory_type": "project_map",
"path": "app/services/memory_adapter.py",
"component_type": "service",
"repo": "acme/api-server"
}
}
],
"count": 6
}
Use Cases
Generate Documentation
def generate_architecture_docs(repo):
"""Generate markdown documentation from project map."""
data = get_project_map(repo=repo)
# Group by directory
by_path = {}
for memory in data['memories']:
path = memory['metadata'].get('path', 'Unknown')
by_path[path] = memory
# Generate markdown
docs = f"# {repo} - Architecture Overview\n\n"
docs += f"This project has {data['count']} documented components.\n\n"
# Sort by path for logical organization
for path in sorted(by_path.keys()):
memory = by_path[path]
component_type = memory['metadata'].get('component_type', 'component')
icon = 'π' if component_type == 'directory' else 'π'
docs += f"## {icon} `{path}`\n\n"
docs += f"{memory['memory']}\n\n"
return docs
# Save to file
with open('ARCHITECTURE.md', 'w') as f:
f.write(generate_architecture_docs('acme/api-server'))
Developer Onboarding
def generate_onboarding_guide(repo):
"""Create an interactive onboarding guide for new developers."""
project_map = get_project_map(repo=repo)
print(f"Welcome to {repo}! Let's explore the codebase.\n")
# Core modules first
core_components = [m for m in project_map['memories']
if 'main' in m['metadata'].get('path', '').lower()
or 'core' in m['metadata'].get('path', '').lower()]
print("π Core Components:")
for comp in core_components:
print(f" β’ {comp['metadata'].get('path')}")
print(f" {comp['memory']}\n")
# API endpoints
api_components = [m for m in project_map['memories']
if 'api' in m['metadata'].get('path', '').lower()]
print("π API Endpoints:")
for comp in api_components:
print(f" β’ {comp['metadata'].get('path')}")
print(f" {comp['memory']}\n")
# Services
services = [m for m in project_map['memories']
if 'service' in m['metadata'].get('component_type', '')]
print("βοΈ Services:")
for svc in services:
print(f" β’ {svc['metadata'].get('path')}")
print(f" {svc['memory']}\n")
AI Code Review Context
def build_review_context(repo, changed_files):
"""
Build relevant context for AI reviewer based on changed files.
Args:
repo: Repository name
changed_files: List of file paths modified in the PR
"""
project_map = get_project_map(repo=repo)
# Find relevant project map entries
relevant_context = []
for memory in project_map['memories']:
path = memory['metadata'].get('path', '')
# Check if any changed file is in this path
if any(path in changed_file or changed_file.startswith(path)
for changed_file in changed_files):
relevant_context.append(memory)
# Build context string
context = "## Relevant Project Context\n\n"
for memory in relevant_context:
context += f"**{memory['metadata'].get('path')}**: {memory['memory']}\n\n"
return context
# Example usage
changed_files = ['app/api/v1/reviews.py', 'app/models/event.py']
context = build_review_context('acme/api-server', changed_files)
print(context)
Search Project Structure
def search_project_map(repo, query):
"""Search project map for specific components or functionality."""
data = get_project_map(repo=repo)
results = []
query_lower = query.lower()
for memory in data['memories']:
path = memory['metadata'].get('path', '').lower()
description = memory['memory'].lower()
if query_lower in path or query_lower in description:
results.append(memory)
return results
# Find all authentication-related components
auth_components = search_project_map('acme/api-server', 'auth')
print(f"Found {len(auth_components)} authentication-related components:\n")
for comp in auth_components:
print(f"π {comp['metadata'].get('path')}")
print(f" {comp['memory']}\n")
Generate Codebase Graph
import networkx as nx
import matplotlib.pyplot as plt
def visualize_codebase_structure(repo):
"""Create a visual graph of the codebase structure."""
data = get_project_map(repo=repo)
G = nx.DiGraph()
for memory in data['memories']:
path = memory['metadata'].get('path', '')
component_type = memory['metadata'].get('component_type', 'module')
# Add node
G.add_node(path, type=component_type)
# Add edge from parent directory
if '/' in path:
parent = path.rsplit('/', 1)[0] + '/'
if parent != path:
G.add_edge(parent, path)
# Draw graph
plt.figure(figsize=(16, 12))
pos = nx.spring_layout(G, k=2, iterations=50)
# Color by component type
colors = {
'directory': 'lightblue',
'module': 'lightgreen',
'service': 'orange',
'api': 'pink'
}
node_colors = [colors.get(G.nodes[n].get('type', 'module'), 'gray')
for n in G.nodes()]
nx.draw(G, pos, node_color=node_colors, with_labels=True,
node_size=3000, font_size=8, arrows=True)
plt.title(f"{repo} - Codebase Structure")
plt.savefig('codebase_structure.png', dpi=300, bbox_inches='tight')
print("β
Saved visualization to codebase_structure.png")
Triggering Project Map Generation
The project map is automatically generated when you connect a repository. To update it:# Trigger a rescan to update the project map
response = requests.post(
"https://api.nectr.ai/api/v1/memory/rescan",
headers={"Authorization": f"Bearer {token}"},
params={"repo": "acme/api-server"}
)
print(f"Status: {response.json()['status']}")
# Output: Status: rescan_started
# Wait a few minutes, then fetch the updated project map
time.sleep(180)
project_map = get_project_map(repo="acme/api-server")
Error Responses
Repository Not Connected
{
"detail": "Repo not connected or access denied"
}
403 Forbidden
Notes
- The project map is built by analyzing repository structure, README files, and code patterns
- Itβs automatically updated when significant changes are detected through PR reviews
- Use the
/memory/rescanendpoint to manually trigger a full project scan - Empty repositories or those without PR activity may have limited project map data
βI