# How to Use the `search_graph` MCP Tool: Query Your Codebase Knowledge Graph

> Learn to use the search_graph MCP tool to query your codebase knowledge graph. Discover functions, classes, and routes via full-text, regex, or semantic search.

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

---

**The `search_graph` tool queries a SQLite-backed knowledge graph to return functions, classes, routes, and their relationships using full-text, regex, or semantic search.**

The `search_graph` tool is a core capability of the **Codebase Memory MCP** server (`DeusData/codebase-memory-mcp`). It exposes the indexed symbol graph—built from your repository’s AST and relationships—through a JSON-RPC interface, allowing precise retrieval of code elements by name, type, or semantic meaning.

## What Is the `search_graph` MCP Tool?

The `search_graph` tool searches the knowledge graph maintained by the MCP server binary (`codebase-memory-mcp`). According to the source code in [`src/mcp/mcp.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/mcp/mcp.c) (lines 339–374), the tool is registered in a definition table using a `tool_def_t` struct that specifies its JSON Schema input. When invoked, the tool queries the SQLite graph database and returns a paginated list of nodes (symbols) and optionally their connected edges.

The server supports multiple invocation paths:
- **CLI wrapper** (`cbm_cli_build_args_json` in [`src/cli/cli.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cli/cli.c)) that converts kebab-case flags to JSON
- **HTTP JSON-RPC** endpoint at `/jsonrpc`
- **In-process C API** (`cbm_mcp_handle_tool` in [`src/mcp/mcp.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/mcp/mcp.c), lines 3894–4004)

## Understanding the Input Schema

The `search_graph` tool accepts a structured argument object. The `project` field is **required**; all others are optional.

| Parameter | Type | Description |
|-----------|------|-------------|
| `project` | string | **Required.** The indexed project name to search. |
| `query` | string | Natural-language full-text search (BM25 ranking). When provided, `name_pattern` is ignored. |
| `label` | string | Filter by node type: `Function`, `Class`, `Route`, `Variable`, etc. |
| `name_pattern` | string | Regex matching the node's `qualified_name`. |
| `qn_pattern` | string | Regex applied to `qualified_name` plus surrounding context (e.g., imports). |
| `file_pattern` | string | Glob pattern restricting results to matching file paths (e.g., `*.go`). |
| `relationship` | string | Edge type filter (e.g., `CALLS`, `IMPORTS`). |
| `min_degree` / `max_degree` | integer | Filter by node degree (number of incident edges). |
| `exclude_entry_points` | boolean | Exclude nodes marked as entry points (e.g., `main` functions). |
| `semantic_query` | array[string] | Keywords for vector-cosine similarity search (requires semantic index). |
| `limit` | integer | Maximum results per call (default: 200). |
| `offset` | integer | Skip first N results for pagination (default: 0). |

**Pagination behavior:** The response includes `total` (total matches) and `has_more` (boolean). To paginate, increment `offset` by `limit` until `has_more` is false.

## How to Call `search_graph`

### Using the CLI Wrapper

The CLI helper `cbm_cli_build_args_json` (defined in [`src/cli/cli.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cli/cli.c)) translates command-line flags into the JSON payload expected by the server. It handles kebab-case to snake_case conversion, boolean flags, and repeated flags (arrays).

```bash

# Search for top 10 functions in project "myapp"

codebase-memory-mcp \
    --tool search_graph \
    --project myapp \
    --label Function \
    --limit 10

```

The CLI expands this into the following JSON structure internally:

```json
{
  "name": "search_graph",
  "arguments": {
    "project": "myapp",
    "label": "Function",
    "limit": 10
  }
}

```

The conversion logic is validated in [`tests/test_cli.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/tests/test_cli.c) (lines 2840–2860), which covers integer parsing, array accumulation, and kebab-case handling.

### Direct HTTP JSON-RPC Call

Send a POST request to the server's `/jsonrpc` endpoint. The method is `call`, and the params contain the tool name and arguments.

```bash
curl -s -X POST http://localhost:8000/jsonrpc \
  -d '{
        "jsonrpc":"2.0",
        "id":1,
        "method":"call",
        "params":{
          "name":"search_graph",
          "arguments":{
            "project":"myapp",
            "label":"Function",
            "query":"update settings",
            "limit":5
          }
        }
      }' | jq .

```

The response envelope contains a `content` array with a `text` field holding the JSON result:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"results\":[...],\"total\":42,\"has_more\":false}"
      }
    ]
  }
}

```

### Using the C API

For in-process integration, call `cbm_mcp_handle_tool` directly. This function is implemented in [`src/mcp/mcp.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/mcp/mcp.c) (lines 3894–4004).

```c
#include "mcp.h"

const char *args = "{\"project\":\"myapp\",\"label\":\"Function\",\"limit\":10}";
char *resp = cbm_mcp_handle_tool(srv, "search_graph", args);
if (resp) {
    printf("Response: %s\n", resp);
    free(resp);
}

```

The test suite in [`tests/test_mcp.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/tests/test_mcp.c) (lines 706–714) demonstrates this pattern, verifying that the response contains the expected tool name and result structure.

### Python Script Example

Construct the JSON-RPC payload manually for custom tooling:

```python
import json
import requests

payload = {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "call",
    "params": {
        "name": "search_graph",
        "arguments": {
            "project": "myapp",
            "label": "Function",
            "semantic_query": ["send", "publish"],
            "limit": 20
        }
    }
}

response = requests.post("http://localhost:8000/jsonrpc", json=payload)
data = response.json()
result = json.loads(data["result"]["content"][0]["text"])
print(f"Found {result['total']} matches")

```

## Key Implementation Files

- **[`src/mcp/mcp.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/mcp/mcp.c)** (lines 339–374): Tool definition table where `search_graph` is registered with its JSON Schema.
- **[`src/mcp/mcp.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/mcp/mcp.c)** (lines 3894–4004): Implementation of `cbm_mcp_handle_tool`, the C entry point.
- **[`src/cli/cli.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cli/cli.c)**: Implementation of `cbm_cli_build_args_json` for CLI-to-JSON conversion.
- **[`tests/test_mcp.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/tests/test_mcp.c)** (lines 706–714): End-to-end test calling `search_graph` via the C API.
- **[`tests/test_cli.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/tests/test_cli.c)** (lines 2840–2860): Unit tests for CLI argument parsing and type coercion.

## Summary

- **The `search_graph` tool** queries the MCP server's SQLite knowledge graph to retrieve code symbols and relationships.
- **Invocation methods** include the CLI wrapper (`codebase-memory-mcp`), HTTP JSON-RPC, and the in-process C API (`cbm_mcp_handle_tool`).
- **Required parameter** is `project`; optional filters include `label`, `name_pattern`, `semantic_query`, and degree constraints.
- **Pagination** uses `limit` (default 200) and `offset`; check `has_more` in the response to determine if additional pages exist.
- **Source references** are found in [`src/mcp/mcp.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/mcp/mcp.c) for tool definitions and [`src/cli/cli.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cli/cli.c) for argument building logic.

## Frequently Asked Questions

### How do I perform a semantic search with `search_graph`?

Pass the `semantic_query` parameter as an array of keywords. This triggers a vector-cosine similarity search against the embedded symbol representations. **Note:** This requires the project to be indexed with a full or moderate semantic index enabled.

### What is the difference between `name_pattern` and `qn_pattern`?

The `name_pattern` parameter applies a regex only to the symbol's `qualified_name` (e.g., `package.Class.method`). The `qn_pattern` parameter extends the regex to include surrounding context, such as import statements or module declarations, allowing you to match symbols by their usage context rather than just their identifier.

### How do I handle large result sets and pagination?

Set the `limit` parameter (default 200) to control page size. The response includes `total` and `has_more` fields. To retrieve the next page, increment the `offset` parameter by the `limit` value and re-query until `has_more` returns false.

### Can I filter by relationships between symbols?

Yes. Use the `relationship` parameter with edge type names like `CALLS` or `IMPORTS` to filter nodes that participate in specific relationship types. Combine this with `include_connected: true` to return both the matching nodes and their directly connected neighbors.