How HTTP Route Detection and HTTP-Calls Edge Linking Work in codebase-memory-mcp
HTTP route detection and HTTP-calls edge linking in codebase-memory-mcp work through a two-pass analysis pipeline that canonicalizes URL paths to match outgoing HTTP calls to their target route definitions, storing the results as graph edges in SQLite.
The codebase-memory-mcp repository constructs a graph-like memory model of your codebase, where symbols such as functions, files, and HTTP endpoints become nodes and their relationships become queryable edges. Understanding how HTTP route detection and HTTP-calls edge linking function is essential for mapping request flows across service boundaries and identifying which client code calls which server endpoints.
The Two-Pass Pipeline Architecture
The system processes source code in two distinct passes to build a complete picture of HTTP traffic within your application.
The first pass scans the abstract syntax tree (AST) of each file to identify route definitions using framework-specific patterns. These definitions are normalized and stored as route nodes linked to their handler functions via route edges.
The second pass examines the same AST to detect outgoing HTTP calls (fetch, axios, requests.get, etc.). Each call site is canonicalized and matched against the route index built during the first pass, creating httpcalls edges when paths align.
This separation ensures that all routes are indexed before the system attempts to link call sites, preventing false negatives from declaration ordering.
Route Detection and Canonicalization
Route discovery occurs in src/pipeline/pass_route_nodes.c, which walks the AST looking for framework-specific constructs like app.get('/api/orders', handler), router.post('/users', …), or @GetMapping("/items").
For each route declaration found, the system:
- Extracts the HTTP method and raw path string
- Invokes
cbm_route_canon_path()to normalize the path - Creates a
cbm_node_twith kindROUTEstoring the method, canonical path, and handler name - Establishes a
routeedge connecting the route node to its handler function node
The canonicalization logic transforms placeholder syntax into a standard format. Paths like "/users/:id", "/users/{id}", or "/users/<int:id>" all normalize to "/users/{}", stripping specific parameter names while preserving the structural pattern.
HTTP-Calls Edge Linking
The HTTP call linking implementation resides in src/pipeline/pass_httpcalls.c, specifically within the cbm_link_httpcalls() function. This pass executes after route indexing completes.
When the walker encounters an HTTP call expression, it performs the following sequence:
- Extracts the URL string from static literals or simple template-string interpolations
- Strips query strings and fragments to isolate the path component
- Canonicalizes the path using the same routine applied to route definitions
- Queries the route index for a matching canonical path
- Creates the edge if found: a
cbm_node_twith kindHTTPCALLis instantiated and linked to the target route node via anEDGE_HTTP_CALLSedge
Calls that fail to match any known route are preserved as orphan HTTP-call nodes for later manual analysis or fuzzy matching.
/* Simplified logic from src/pipeline/pass_httpcalls.c */
if (is_http_call(node)) {
const char *raw_url = extract_url_literal(node);
char canon_path[256];
canonicalise_path(raw_url, canon_path);
cbm_node_t *call_node = cbm_node_new(HTTPCALL, ...);
cbm_node_t *target_route = route_index_lookup(canon_path);
if (target_route) {
cbm_edge_new(call_node, target_route, EDGE_HTTP_CALLS);
}
}
Why Path Canonicalization Matters
Frameworks allow multiple syntaxes for path parameters. Without normalization, a route defined as /users/:id would never match a client call to /users/{userId} despite representing the same endpoint.
The cbm_route_canon_path() function solves this by converting all parameter patterns to the uniform {} token. This enables reliable matching across language boundaries—whether your backend uses Express-style colons and your client uses template literals, the structural equivalence is preserved.
The test suite in tests/test_route_canon.c validates this behavior across colon, brace, angle-bracket, and template-string forms, ensuring consistent canonicalization regardless of source language.
Working with the Graph Programmatically
After the pipeline completes, the resulting graph persists to an on-disk SQLite3 database via src/store/arch.c. You can query this structure using the Go API or directly via the store interface.
Example: Querying routes and their callers in Go:
package main
import (
"fmt"
"github.com/DeusData/codebase-memory-mcp/pkg/go/cmd"
)
func main() {
// Extract memory graph from current directory
mem, err := cmd.Extract("./", cmd.Options{
Languages: []string{"javascript", "python", "go"},
})
if err != nil {
panic(err)
}
// Find specific route by handler name
route, _ := mem.NodeByQualifiedName("myapp.handler.GetOrders")
// Retrieve all HTTP call sites targeting this route
calls := mem.Edges(route, "httpcalls")
fmt.Printf("Found %d call sites for %s\n", len(calls), route.QualifiedName())
}
Example: Low-level C API for custom analysis:
#include "cbm_store.h"
#include "pass_httpcalls.h"
void custom_analysis(cbm_store_t *store) {
// Create HTTP call node manually
cbm_node_t *call = cbm_node_new(
HTTPCALL,
"fetch('/api/orders')",
"src/client.js:12"
);
// Look up target route in the store
cbm_node_t *route = cbm_store_lookup_route(store, "/api/orders");
if (route) {
cbm_edge_new(call, route, EDGE_HTTP_CALLS);
}
cbm_store_add_node(store, call);
}
Integration tests in tests/test_store_arch.c verify that route_count and httpcalls_count metrics reflect the expected graph structure after processing.
Summary
- HTTP route detection occurs in
src/pipeline/pass_route_nodes.c, scanning ASTs for framework-specific route declarations and creatingROUTEnodes linked to handlers. - HTTP-calls edge linking happens in
src/pipeline/pass_httpcalls.cviacbm_link_httpcalls(), matching canonicalized call URLs against the route index to createhttpcallsedges. - Path canonicalization via
cbm_route_canon_path()normalizes parameter syntax (:id,{id},<id>) to{}, enabling cross-language route matching. - Unmatched calls persist as orphan nodes rather than being discarded, supporting analysis of external or dynamic endpoints.
- All nodes and edges persist to SQLite through
src/store/arch.c, queryable via Go or C APIs.
Frequently Asked Questions
How does the system handle different framework syntaxes for route definitions?
The parser recognizes multiple framework patterns—including Express-style app.get(), Flask decorators, Spring Boot annotations, and Go HTTP handlers—extracting the method and path regardless of syntactic differences. All paths are immediately canonicalized using cbm_route_canon_path() in src/pipeline/pass_route_nodes.c, which strips framework-specific parameter syntax down to uniform {} tokens.
What happens when an HTTP call doesn't match any known route?
When cbm_link_httpcalls() fails to find a matching canonical path in the route index, it still creates a HTTPCALL node for the call site but leaves it unattached (orphan). These orphan nodes remain available in the SQLite store via src/store/arch.c for later analysis, enabling identification of calls to external services or routes defined in configuration files outside the scanned source.
Which programming languages does the HTTP route detection support?
The pipeline supports JavaScript, TypeScript, Python, and Go according to the CLI entry point in pkg/go/cmd/codebase-memory-mcp/main.go. Each language frontend produces a language-agnostic AST that pass_route_nodes.c and pass_httpcalls.c traverse uniformly, allowing the canonicalization and edge-linking logic to remain language-agnostic while the parsers handle syntax specifics.
How is the graph data persisted and queried?
All nodes and edges write to an on-disk SQLite3 database managed by src/store/arch.c. The store provides APIs for inserting nodes (cbm_store_add_node), looking up routes by canonical path (cbm_store_lookup_route), and querying edge relationships. Higher-level Go bindings in pkg/go/cmd/ wrap these primitives, enabling queries like retrieving all HTTP calls targeting a specific route node through the Edges() method.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →