# How Cross-Repo Intelligence Works with CROSS_* Edges in Codebase-Memory-MCP

> Discover how cross-repo intelligence works with CROSS_* edges in Codebase-Memory-MCP. This article explains how inter-service relationships are found and linked across projects.

- Repository: [Martin Vogel/codebase-memory-mcp](https://github.com/DeusData/codebase-memory-mcp)
- Tags: how-to-guide
- Published: 2026-07-30

---

**Cross-repo intelligence discovers inter-service relationships across separate indexed projects by scanning for `HTTP_CALLS`, `ASYNC_CALLS`, and channel edges, then inserting bidirectional `CROSS_*` edges into both source and target SQLite stores.**

The DeusData/codebase-memory-mcp project (internally referred to as Instagit) implements cross-repo intelligence to map dependencies between independent codebases. This system analyzes internal edge types within a source project, locates matching counterparts in target projects, and materializes these relationships as `CROSS_HTTP_CALLS`, `CROSS_ASYNC_CALLS`, and `CROSS_CHANNEL` edges. These bidirectional links enable unified visibility across repository boundaries, allowing the architecture graph to reflect inter-service communication that spans multiple repositories.

## The Three-Phase Edge Detection Pipeline

The core implementation in [`src/pipeline/pass_cross_repo.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/pipeline/pass_cross_repo.c) executes three distinct matching phases to identify cross-repo relationships. Each phase scans for specific edge types in the source project and attempts to resolve them against nodes in target projects.

### Phase A – HTTP Route Matching (CROSS_HTTP_CALLS)

For every `HTTP_CALLS` edge discovered in the source project, the pipeline constructs a canonical qualified name (QN) using the format `__route__<METHOD>__<PATH>`. The system then searches target project databases for a `Route` node with a matching QN using the `find_route_handler` function. If exact matching fails, `find_route_handler_fuzzy` attempts template-based fuzzy matching. When a match is found, `emit_cross_route_bidirectional` creates `CROSS_HTTP_CALLS` edges in both the source and target stores, establishing a bidirectional link between the service caller and the route handler.

### Phase B – Async Topic Matching (CROSS_ASYNC_CALLS)

The `match_async_routes` function handles `ASYNC_CALLS` edges similarly to HTTP routes. It incorporates the broker name (or the string "async") into the QN construction to identify matching async topic handlers across project boundaries. This phase generates `CROSS_ASYNC_CALLS` edges when publishers and consumers of async messages are found in different repositories.

### Phase C – Channel Matching (CROSS_CHANNEL)

Channel matching operates on event-driven communication patterns. The `try_match_channel_listener` function examines `EMITS` edges that point to `Channel` nodes in the source project. It then searches target projects for corresponding `LISTENS_ON` edges attached to matching channel identifiers. When both sides of a channel communication pattern are identified across projects, the system inserts `CROSS_CHANNEL` edges to represent the inter-repository event flow.

## Shared Pipeline Infrastructure and Edge Persistence

All three matching phases rely on a common helper pipeline defined in [`src/pipeline/pass_cross_repo.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/pipeline/pass_cross_repo.c) and [`src/pipeline/pass_cross_repo.h`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/pipeline/pass_cross_repo.h) to manage project discovery, cancellation support, and atomic edge insertion.

### Project Discovery

File-system helpers `cr_db_path`, `cr_open_existing_project`, and `cr_project_exists` locate the SQLite database for each target project. These functions enable the pipeline to traverse the indexed project graph without requiring all repositories to be loaded into memory simultaneously.

### Cancellation Support

The pipeline supports cooperative cancellation through a `cr_run_context_t` object that tracks an atomic cancel flag. Long-running cross-repo scans can be interrupted by setting this flag, causing early exit without rolling back already-committed writes. This pattern is exposed through the `cbm_cross_repo_match_cancellable` API.

### Edge Creation and Idempotency

The `insert_cross_edge` function constructs a JSON property blob via `build_cross_props` and upserts the edge into the store using `cbm_store_insert_edge` (defined in [`src/store/store.h`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/store/store.h)). The underlying edge table enforces a unique constraint on the tuple `(source_id, target_id, type)`, ensuring that repeated runs are idempotent and do not create duplicate relationships.

### Cleanup of Stale Relationships

Before initiating a new cross-repo run, `delete_cross_edges` removes existing `CROSS_*` edges for the source project. This cleanup respects cancellation checkpoints and ensures that the graph only reflects current, valid cross-repository relationships.

## API Entry Points for Cross-Repo Matching

The public API is defined in [`src/pipeline/pass_cross_repo.h`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/pipeline/pass_cross_repo.h) and centers on the `cbm_cross_repo_match` function and its cancellable variant.

### Synchronous Matching

`cbm_cross_repo_match` accepts a source project name, an array of target project names (or `"*"` to scan all indexed projects), and returns a `cbm_cross_repo_result_t` struct reporting the count of HTTP, async, and channel edges created, along with elapsed time.

```c
#include "pipeline/pass_cross_repo.h"

int main(void) {
    const char *src = "my-service";
    const char *targets[] = {"auth-service", "payment-service"};
    cbm_cross_repo_result_t res = cbm_cross_repo_match(src, targets, 2);
    printf("HTTP edges: %d, Async edges: %d, Channel edges: %d\n",
           res.http_edges, res.async_edges, res.channel_edges);
    return 0;
}

```

### Cancellable Execution

For UI integration or long-running background tasks, `cbm_cross_repo_match_cancellable` accepts an additional atomic integer pointer that acts as a cancellation flag.

```c
#include "pipeline/pass_cross_repo.h"
#include <stdatomic.h>

atomic_int cancel_flag = ATOMIC_VAR_INIT(0);
/* User clicks "Cancel" → atomic_store(&cancel_flag, 1); */
cbm_cross_repo_result_t res = cbm_cross_repo_match_cancellable(
        "frontend", (const char *[]){"backend"}, 1, &cancel_flag);
if (res.cancelled) {
    puts("Cross-repo scan was cancelled");
}

```

## Querying CROSS_* Edges via the HTTP API

Once created, cross-repo edges are exposed through the HTTP server implemented in [`src/ui/http_server.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/ui/http_server.c). The MCP aggregation layer in [`src/mcp/mcp.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/mcp/mcp.c) processes the `cbm_cross_repo_result_t` structure and, if any `CROSS_*` edges exist, appends a summary to the exported architecture JSON.

### HTTP Endpoint Example

```http
GET /api/v1/projects/my-service/cross-edges?type=CROSS_HTTP_CALLS

```

The server handler constructs the underlying SQL query using a `LIKE` pattern to filter for cross-repo edge types:

```c
sqlite3_prepare_v2(db,
    "SELECT e.* FROM edges e WHERE e.project = ?1 AND e.type LIKE 'CROSS_%'",
    -1, &stmt, NULL);

```

This query pattern allows the frontend to visualize cross-repo links by retrieving all edges prefixed with `CROSS_`, then grouping by `target_project` to display inter-service dependencies across the entire indexed codebase.

## Summary

- **Cross-repo intelligence** bridges separate repositories by creating bidirectional `CROSS_*` edges that mirror existing intra-project relationships.
- **Three matching phases** handle HTTP routes (`CROSS_HTTP_CALLS`), async topics (`CROSS_ASYNC_CALLS`), and event channels (`CROSS_CHANNEL`) via `match_http_routes`, `match_async_routes`, and `try_match_channel_listener`.
- **Idempotent insertion** is enforced through unique database constraints on `(source_id, target_id, type)` tuples, with stale edge cleanup performed by `delete_cross_edges`.
- **Cancellation support** allows graceful interruption of long scans via `cbm_cross_repo_match_cancellable` without corrupting the graph state.
- **Query interface** exposes these edges through standard SQL patterns like `LIKE 'CROSS_%'` in [`src/ui/http_server.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/ui/http_server.c) and aggregates results in [`src/mcp/mcp.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/mcp/mcp.c).

## Frequently Asked Questions

### What triggers the creation of CROSS_* edges?

The `cbm_cross_repo_match` function (or its cancellable variant) initiates the process. It scans a source project's graph for `HTTP_CALLS`, `ASYNC_CALLS`, and `CHANNEL` edges, then attempts to locate matching nodes in specified target projects. When matches are found, the system inserts bidirectional edges prefixed with `CROSS_` into both projects' SQLite stores.

### How does the system handle HTTP route ambiguity?

If exact QN matching fails, the pipeline falls back to `find_route_handler_fuzzy`, which performs template-based fuzzy matching on route patterns. This allows cross-repo links to be established even when path parameters or minor formatting differences exist between the service consumer and the route definition.

### Are cross-repo edges persisted idempotently?

Yes. The `insert_cross_edge` function uses an upsert operation that respects the unique constraint on `(source_id, target_id, type)` in the edge table. Additionally, `delete_cross_edges` removes existing `CROSS_*` edges for a project before new matching begins, ensuring the graph reflects only current relationships.

### How can I cancel a running cross-repo scan?

Use the `cbm_cross_repo_match_cancellable` API and pass a pointer to an `atomic_int` cancellation flag. Setting this flag to a non-zero value causes the pipeline to exit early at the next cancellation checkpoint. Already-committed edges remain in the database, but no further edges are created, and the returned `cbm_cross_repo_result_t` indicates the run was cancelled.