How codebase-memory-mcp Extracts HTTP Route Nodes and Matches Call Sites for Cross-Service Linking

codebase-memory-mcp extracts HTTP route nodes by scanning HTTP_CALLS edges in src/pipeline/pass_route_nodes.c, canonicalizing URL paths into deterministic qualified names (QNs), and matching them to call sites through identical QN lookups to enable cross-service dependency analysis.

codebase-memory-mcp constructs a comprehensive graph representation of repository entities to enable deep cross-service analysis. The system extracts HTTP Route nodes from call edges and links them to call sites using canonicalized qualified names, creating a unified dependency graph that maps inter-service HTTP interactions across the entire codebase.

Extracting HTTP Route Nodes from Graph Edges

The extraction process begins in src/pipeline/pipeline.c within the cbm_pipeline_create_route_nodes() function. This orchestration pass invokes the route_edge_visitor() callback in src/pipeline/pass_route_nodes.c to iterate over the graph edge list and identify HTTP endpoints.

Filtering HTTP_CALLS and ASYNC_CALLS Edges

The visitor function filters edges by type, processing only HTTP_CALLS and ASYNC_CALLS relationships. For each matching edge, it extracts the url_path and callee properties from the edge's JSON metadata using json_extract():

if (strcmp(edge->type, "HTTP_CALLS") != 0 &&
    strcmp(edge->type, "ASYNC_CALLS") != 0) {
    return;
}

const char *url = json_extract(edge->properties_json, "url_path",
                               url_buf, sizeof(url_buf));
const char *callee = json_extract(edge->properties_json, "callee",
                                  callee_buf, sizeof(callee_buf));

Guarding for Literal Routes

For HTTP_CALLS edges, the system applies a literal route guard using cbm_service_pattern_is_http_route_literal(). This ensures that only endpoints with literal URL paths (not dynamically constructed strings) are processed as route definitions, preventing false positives from variable interpolation.

if (strcmp(edge->type, "HTTP_CALLS") == 0 &&
    !cbm_service_pattern_is_http_route_literal(url, callee))
    return;

Canonicalizing URL Paths

The cbm_route_canon_path() function transforms URL paths into a canonical form by replacing path parameters (e.g., :id) with uniform placeholders ({}). This normalization ensures that /user/:id and /user/123 resolve to the same route identity, enabling accurate cross-service matching regardless of specific argument values.

Matching Routes to Call Sites via Qualified Names

Route nodes are matched to call sites through a deterministic qualified name (QN) strategy that guarantees identity across the graph.

Generating Deterministic Qualified Names

The system constructs a stable QN by combining the HTTP method (or "ANY" for generic routes) with the canonicalized path:

char route_qn[CBM_ROUTE_QN_SIZE];
snprintf(route_qn, sizeof(route_qn), "__route__%s__%s",
         method ? method : "ANY",
         cbm_route_canon_path(url, cpath, sizeof(cpath)));

For ASYNC_CALLS edges, the QN incorporates the broker identifier instead of the HTTP method.

Upserting Route Nodes

The cbm_gbuf_upsert_node() function in the graph buffer (gb) creates or updates Route nodes using the QN as the deduplication key. This guarantees a single node per unique endpoint/method combination:

cbm_gbuf_upsert_node(ctx->gb, "Route", url, route_qn,
                     "", 0, 0, route_props);

Cross-Service Linking Passes

After route creation, several specialized passes complete the cross-service linking:

  • ensure_decorator_routes: Scans Function nodes for @route decorators in src/pipeline/pass_semantic.c and creates corresponding Route nodes with HANDLES edges.
  • connect_prefix_to_decorators: Links prefix routes (e.g., /api) to decorator-defined handlers.
  • match_infra_routes: Joins infrastructure Route nodes (from external configurations) to handler Routes by comparing canonicalized paths.
  • create_data_flows: Establishes DATA_FLOWS edges from callers through Route nodes to handlers, enabling end-to-end flow analysis.

The matching succeeds because both the Route node and the call-site edge share the identical QN derived from the same canonicalization logic.

End-to-End Pipeline Flow

The complete extraction and linking lifecycle follows five distinct phases:

  1. Discovery Phase: src/pipeline/pass_calls.c parses source files to create File → Function → HTTP_CALLS edges.
  2. Route Extraction: cbm_pipeline_create_route_nodes() scans edges, extracts URLs, and upserts Route nodes with deterministic QNs.
  3. Decorator Resolution: ensure_decorator_routes() validates that annotated functions have matching Route nodes.
  4. Route Matching: connect_prefix_to_decorators() and match_infra_routes() link Route nodes to their callers and infrastructure definitions.
  5. Data Flow Construction: create_data_flows() adds DATA_FLOWS edges, finalizing the cross-service call graph for downstream LSP and security analysis.

Implementation Details

The following C implementation from src/pipeline/pass_route_nodes.c demonstrates the core extraction logic:

static void route_edge_visitor(const cbm_gbuf_edge_t *edge, void *userdata) {
    route_ctx_t *ctx = (route_ctx_t *)userdata;

    if (strcmp(edge->type, "HTTP_CALLS") != 0 &&
        strcmp(edge->type, "ASYNC_CALLS") != 0) {
        return;
    }

    char url_buf[CBM_SZ_512];
    const char *url = json_extract(edge->properties_json, "url_path",
                                   url_buf, sizeof(url_buf));
    if (!url || !url[0]) return;

    char callee_buf[CBM_SZ_256];
    const char *callee = json_extract(edge->properties_json, "callee",
                                      callee_buf, sizeof(callee_buf));
    if (strcmp(edge->type, "HTTP_CALLS") == 0 &&
        !cbm_service_pattern_is_http_route_literal(url, callee))
        return;

    char route_qn[CBM_ROUTE_QN_SIZE];
    char cpath[CBM_SZ_256];
    snprintf(route_qn, sizeof(route_qn), "__route__%s__%s",
             method ? method : "ANY",
             cbm_route_canon_path(url, cpath, sizeof(cpath)));

    cbm_gbuf_upsert_node(ctx->gb, "Route", url, route_qn,
                         "", 0, 0, route_props);
    ctx->created++;
}

The pipeline entry point in src/pipeline/pipeline.c orchestrates the sequential execution:

void cbm_pipeline_create_route_nodes(cbm_gbuf_t *gb) {
    route_ctx_t ctx = {.gb = gb, .created = 0};
    cbm_gbuf_foreach_edge(gb, route_edge_visitor, &ctx);

    ensure_decorator_routes(gb);
    connect_prefix_to_decorators(gb);
    match_infra_routes(gb);
    create_data_flows(gb);
    create_grpc_routes(gb);
    create_sveltekit_routes(gb);
}

Summary

  • HTTP Route extraction occurs in src/pipeline/pass_route_nodes.c via the route_edge_visitor() callback, filtering for HTTP_CALLS and ASYNC_CALLS edges.
  • Canonicalization via cbm_route_canon_path() normalizes path parameters to {}, ensuring that /user/:id and /user/123 map to identical route identities.
  • Qualified names (QNs) provide deterministic deduplication keys using the pattern __route__METHOD__canonicalized_path.
  • Cross-service linking relies on matching QNs between Route nodes and call-site edges, with subsequent passes creating HANDLES and DATA_FLOWS relationships.
  • The graph buffer (cbm_gbuf_t) persists nodes to src/store/store.c for consumption by downstream analysis tools.

Frequently Asked Questions

How does codebase-memory-mcp handle path parameters in HTTP routes?

The system canonicalizes path parameters using cbm_route_canon_path() in src/pipeline/pass_route_nodes.c, which replaces dynamic segments like :id or {userId} with uniform {} placeholders. This ensures that different call sites referencing the same endpoint with varying arguments resolve to a single Route node.

What is the purpose of the qualified name (QN) in route matching?

The QN serves as a deterministic, stable identifier that combines the HTTP method and canonicalized path (e.g., __route__GET__/api/users). Both Route nodes and call-site edges generate identical QNs, enabling the graph query engine to stitch together cross-service dependencies without ambiguity.

Which edge types trigger route node extraction?

The route_edge_visitor() function processes edges of type HTTP_CALLS and ASYNC_CALLS. HTTP calls undergo additional literal validation via cbm_service_pattern_is_http_route_literal(), while async calls proceed directly to QN generation using their broker identifier.

How are decorator-based routes linked to HTTP handlers?

The ensure_decorator_routes() pass scans Function nodes annotated with @route attributes (identified by src/pipeline/pass_semantic.c) and creates corresponding Route nodes if missing. The connect_prefix_to_decorators() pass then establishes HANDLES edges between prefix routes (e.g., /api) and specific handler functions, completing the linkage between infrastructure definitions and implementation code.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →