How HTTP Routes and Cross-Service Links Are Detected and Validated in codebase-memory-mcp

The codebase-memory-mcp engine discovers HTTP routes by parsing framework-specific AST patterns and canonicalizing paths, while cross-service links are identified through import analysis and qualified name resolution, with both undergoing strict validation for completeness, uniqueness, and reachability.

codebase-memory-mcp builds a graph-based memory of a codebase by analyzing source files and extracting semantic entities as nodes and edges. Understanding how it detects and validates HTTP routes and cross-service links is essential for navigating microservice architectures and ensuring API consistency. The pipeline uses language-specific extractors and a central graph store to maintain these relationships across JavaScript, TypeScript, Go, Python, Rust, and other supported languages.

Detecting HTTP Routes in the Pipeline

The detection of HTTP routes begins with AST extraction, where language-specific parsers walk the abstract syntax tree looking for framework-specific patterns.

AST Extraction and Framework Pattern Matching

In src/pipeline/pass_route_nodes.c, the pipeline walks the AST to identify route declarations such as app.get('/path', handler), router.post("/path", fn), or http.HandleFunc("/path", fn). These patterns are matched regardless of the specific web framework being used, allowing the system to extract the HTTP method, path string, and handler function reference from the source code.

Route Canonicalization

Before storage, raw route strings are normalized by cbm_route_canon_path() in src/pipeline/route_canon.c. This function converts parameter placeholders into a uniform {} token, transforming variations like "/users/:id", "/users/{id}", or "/users/<int:id>" into a standardized "/users/{}" format. This canonicalization removes framework-specific syntax differences and enables reliable duplicate detection across the codebase. The logic is thoroughly tested in tests/test_route_canon.c.

For each discovered route, the system creates a node with the aspect routes via cbm_store_upsert_node() in src/store.c. Each node stores:

  • method (GET, POST, etc.)
  • path (canonicalized)
  • handler (qualified function name)
  • service (the package or module containing the handler)

The route node is then linked to its handler function node via an edge of type defines, and the handler is linked to its containing service node, creating a complete trace from service → handler → route.

Validating HTTP Routes

The validation phase in src/pipeline/pass_route_validate.c ensures route integrity before the graph is considered stable.

Validation checks include:

  • Every route node must have a non-empty method and path
  • The referenced handler node must exist (otherwise the route is flagged as dangling)
  • No two route nodes within the same service may share the same canonical path and method (duplicate route detection)

When validation fails, the store flags the node with a validation_error aspect, making it queryable through the LSP and CLI interfaces.

Cross-service dependencies are discovered through import analysis and qualified name resolution.

In src/pipeline/pass_link_nodes.c, the pipeline parses import statements (import X from "serviceB", require('serviceB'), Go import "serviceB", etc.) to identify dependencies between modules. When a symbol is imported from a different service, the system records a link edge from the importing module to the imported symbol's defining module.

Qualified Name Resolution

Symbol resolution builds a qualified name string of the form <service>.<package>.<symbol> using cbm_fqn_resolve() in src/fqn.c. This fully qualified name is stored as the node's qualified_name field, enabling precise cross-reference tracking. An edge of type depends_on (or calls) is then inserted between the caller and callee nodes via cbm_store_upsert_edge() in src/store.c.

Validating Cross-Service Dependencies

After the graph is fully constructed, src/pipeline/pass_link_validate.c performs cross-service validation by walking all depends_on edges. The validation ensures that:

  • The target node exists and is reachable
  • The dependency actually crosses a service boundary (both nodes belong to different services)
  • Missing targets are marked with missing_link
  • Cycles that span multiple services are flagged as potential architectural violations

Accessing Validation Results

The pipeline exposes validation results through multiple interfaces for developer tooling integration.

LSP Diagnostics and CLI Queries

LSP diagnostics query the store for nodes with a validation_error aspect and surface them as diagnostics in the editor. Via the CLI, you can retrieve specific validation states:

/* Query all valid routes */
cbm_store_t *store = cbm_store_open(".");
cbm_node_t *routes = cbm_store_query(store,
    "aspect == 'routes' && !validation_error");
for (size_t i = 0; i < routes->len; ++i) {
    printf("%s %s -> %s\n",
        routes[i].method,
        routes[i].path,
        routes[i].handler);
}
cbm_store_close(store);

To inspect cross-service boundaries:

/* List all edges that cross service boundaries */
for (edge in store->edges) {
    if (edge.type == DEPENDS_ON &&
        edge.src.service != edge.dst.service) {
        printf("%s (%s) → %s (%s)\n",
            edge.src.name, edge.src.service,
            edge.dst.name, edge.dst.service);
    }
}

The test suite in tests/test_store_arch.c validates this entire workflow by creating fake route nodes, running cbm_store_validate(), and asserting the expected route_count and error flags, ensuring the detection and validation pipeline remains consistent across releases.

Summary

  • HTTP route detection occurs in src/pipeline/pass_route_nodes.c through AST pattern matching, followed by path canonicalization in src/pipeline/route_canon.c to normalize framework-specific syntax.
  • Route validation in src/pipeline/pass_route_validate.c checks for complete metadata, existing handlers, and duplicate paths within services.
  • Cross-service links are identified in src/pipeline/pass_link_nodes.c via import/require analysis and qualified name resolution using cbm_fqn_resolve().
  • Link validation in src/pipeline/pass_link_validate.c verifies that dependencies exist, cross service boundaries, and flags architectural cycles.
  • All validation results are stored as node aspects (validation_error, missing_link) and exposed through LSP diagnostics, CLI queries, and the C API.

Frequently Asked Questions

How does codebase-memory-mcp handle different web framework syntaxes?

The system uses framework-agnostic AST patterns in src/pipeline/pass_route_nodes.c to recognize common routing idioms across Express.js, Fastify, Gorilla Mux, Flask, and other frameworks. The cbm_route_canon_path() function in src/pipeline/route_canon.c then normalizes parameter syntax variations (such as :id, {id}, or <int:id>) into a uniform {} format, allowing the graph to treat routes from different frameworks as comparable entities.

What happens when a route references a non-existent handler?

During the validation phase in src/pipeline/pass_route_validate.c, the system verifies that each route's handler references an existing function node in the graph. If the handler cannot be resolved, the route node is flagged with a validation_error aspect and reported as a dangling route through LSP diagnostics or CLI queries, allowing developers to identify broken API endpoints immediately.

How are circular dependencies between services detected?

The src/pipeline/pass_link_validate.c validation pass analyzes all depends_on edges that cross service boundaries. When it detects cycles where service A depends on service B, which transitively depends back on service A, it flags these as potential architectural violations. This helps maintain clean service boundaries in microservice architectures.

Can I query the graph store directly for validation errors?

Yes. The store exposes a query interface via cbm_store_query() in src/store.c. You can filter specifically for problematic nodes using aspect queries such as "aspect == 'routes' && validation_error" to retrieve only routes with validation failures, or query for missing_link aspects to find broken cross-service dependencies.

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 →