Navegador

navegador / docs / api / mcp.md
1
# MCP Server API
2
3
Navegador exposes all context-loading commands as an MCP server. The server is created with `create_mcp_server()` and speaks the [Model Context Protocol](https://modelcontextprotocol.io) over stdio.
4
5
```python
6
from navegador.mcp import create_mcp_server
7
```
8
9
---
10
11
## create_mcp_server
12
13
```python
14
def create_mcp_server(
15
store: GraphStore | None = None,
16
db_path: str = "",
17
read_only: bool = False,
18
max_query_complexity: int = 0,
19
) -> MCPServer: ...
20
```
21
22
Creates and returns an MCP server instance. If `store` is not provided, opens a `GraphStore.sqlite()` at `db_path` (or `NAVEGADOR_DB` env var, or `./navegador.db`).
23
24
- `read_only`: when `True`, disables the `ingest` tool and restricts the `query` tool to `MATCH`/`RETURN` only. Corresponds to `navegador mcp --read-only`.
25
- `max_query_complexity`: if non-zero, rejects Cypher queries whose estimated complexity exceeds this value. Prevents runaway traversals in multi-agent environments.
26
27
The CLI command `navegador mcp [--db path] [--read-only]` calls this function and runs the server loop.
28
29
### Usage
30
31
```python
32
from navegador.graph import GraphStore
33
from navegador.mcp import create_mcp_server
34
35
store = GraphStore.sqlite(".navegador/navegador.db")
36
server = create_mcp_server(store=store)
37
server.run() # blocks; serves over stdio
38
```
39
40
To embed in a larger MCP server:
41
42
```python
43
server = create_mcp_server(db_path=".navegador/navegador.db")
44
# register additional tools on server before running
45
server.run()
46
```
47
48
---
49
50
## Available MCP tools
51
52
All tools accept JSON input and return JSON output. There are 11 tools in total.
53
54
---
55
56
### `ingest`
57
58
Ingest a repository or file into the graph.
59
60
**Input schema:**
61
```json
62
{
63
"type": "object",
64
"properties": {
65
"path": {
66
"type": "string",
67
"description": "Path to the repo or file to ingest"
68
},
69
"clear": {
70
"type": "boolean",
71
"description": "Wipe the graph before ingesting",
72
"default": false
73
}
74
},
75
"required": ["path"]
76
}
77
```
78
79
**Output:** `IngestionResult` serialized to JSON.
80
81
---
82
83
### `context`
84
85
Return the full context bundle for a source file.
86
87
**Input schema:**
88
```json
89
{
90
"type": "object",
91
"properties": {
92
"file": {
93
"type": "string",
94
"description": "Path to the source file"
95
},
96
"format": {
97
"type": "string",
98
"enum": ["json", "markdown"],
99
"default": "json"
100
}
101
},
102
"required": ["file"]
103
}
104
```
105
106
**Output:** `ContextBundle` as JSON or markdown string.
107
108
---
109
110
### `function`
111
112
Return a function's context bundle including callers, callees, and decorators.
113
114
**Input schema:**
115
```json
116
{
117
"type": "object",
118
"properties": {
119
"name": {
120
"type": "string",
121
"description": "Function name"
122
},
123
"file": {
124
"type": "string",
125
"description": "Optional file path to disambiguate"
126
},
127
"depth": {
128
"type": "integer",
129
"description": "Call graph traversal depth",
130
"default": 1
131
}
132
},
133
"required": ["name"]
134
}
135
```
136
137
**Output:** `ContextBundle` as JSON.
138
139
---
140
141
### `class`
142
143
Return a class context bundle including hierarchy, methods, and references.
144
145
**Input schema:**
146
```json
147
{
148
"type": "object",
149
"properties": {
150
"name": {
151
"type": "string",
152
"description": "Class name"
153
},
154
"file": {
155
"type": "string",
156
"description": "Optional file path to disambiguate"
157
}
158
},
159
"required": ["name"]
160
}
161
```
162
163
**Output:** `ContextBundle` as JSON.
164
165
---
166
167
### `explain`
168
169
Universal lookup: explain any node (function, class, file, concept, rule, decision) by name.
170
171
**Input schema:**
172
```json
173
{
174
"type": "object",
175
"properties": {
176
"name": {
177
"type": "string",
178
"description": "Node name to explain"
179
},
180
"file": {
181
"type": "string",
182
"description": "Optional file path to disambiguate code nodes"
183
}
184
},
185
"required": ["name"]
186
}
187
```
188
189
**Output:** `ContextBundle` as JSON.
190
191
---
192
193
### `search`
194
195
Search the graph by text query.
196
197
**Input schema:**
198
```json
199
{
200
"type": "object",
201
"properties": {
202
"query": {
203
"type": "string",
204
"description": "Search query"
205
},
206
"all": {
207
"type": "boolean",
208
"description": "Search all layers including knowledge layer",
209
"default": false
210
},
211
"docs": {
212
"type": "boolean",
213
"description": "Search docstrings and wiki content only",
214
"default": false
215
},
216
"limit": {
217
"type": "integer",
218
"description": "Maximum results to return",
219
"default": 20
220
}
221
},
222
"required": ["query"]
223
}
224
```
225
226
**Output:** Array of `ContextNode` objects as JSON.
227
228
---
229
230
### `query`
231
232
Execute a raw Cypher query against the graph.
233
234
**Input schema:**
235
```json
236
{
237
"type": "object",
238
"properties": {
239
"cypher": {
240
"type": "string",
241
"description": "Cypher query string"
242
},
243
"params": {
244
"type": "object",
245
"description": "Optional query parameters",
246
"default": {}
247
}
248
},
249
"required": ["cypher"]
250
}
251
```
252
253
**Output:** Array of result rows as JSON.
254
255
!!! warning
256
This tool executes writes as well as reads. Agents should use read-only queries (`MATCH` / `RETURN`) unless explicitly performing graph updates. Use `--read-only` mode or `read_only=True` in `create_mcp_server()` to enforce this at the server level.
257
258
---
259
260
### `get_rationale`
261
262
Return the rationale, decisions, and rules that govern a named code node.
263
264
**Input schema:**
265
```json
266
{
267
"type": "object",
268
"properties": {
269
"name": {
270
"type": "string",
271
"description": "Function, class, or file name"
272
},
273
"file": {
274
"type": "string",
275
"description": "Optional file path to disambiguate"
276
}
277
},
278
"required": ["name"]
279
}
280
```
281
282
**Output:** Array of `Decision` and `Rule` nodes with `rationale` fields, as JSON.
283
284
---
285
286
### `find_owners`
287
288
Return the people and domains that own a code node, based on CODEOWNERS, annotation, and domain membership.
289
290
**Input schema:**
291
```json
292
{
293
"type": "object",
294
"properties": {
295
"name": {
296
"type": "string",
297
"description": "Function, class, or file name"
298
},
299
"file": {
300
"type": "string",
301
"description": "Optional file path"
302
}
303
},
304
"required": ["name"]
305
}
306
```
307
308
**Output:** Array of `Person` and `Domain` nodes as JSON.
309
310
---
311
312
### `search_knowledge`
313
314
Search the knowledge layer only (concepts, rules, decisions, wiki pages, domains).
315
316
**Input schema:**
317
```json
318
{
319
"type": "object",
320
"properties": {
321
"query": {
322
"type": "string",
323
"description": "Search query"
324
},
325
"limit": {
326
"type": "integer",
327
"description": "Maximum results to return",
328
"default": 20
329
}
330
},
331
"required": ["query"]
332
}
333
```
334
335
**Output:** Array of knowledge layer `ContextNode` objects as JSON.
336
337
---
338
339
### `blast_radius`
340
341
Return all code nodes transitively reachable from a given node via CALLS, IMPORTS, and INHERITS edges — the set of things that could break if this node changes.
342
343
**Input schema:**
344
```json
345
{
346
"type": "object",
347
"properties": {
348
"name": {
349
"type": "string",
350
"description": "Starting node name"
351
},
352
"file": {
353
"type": "string",
354
"description": "Optional file path to disambiguate"
355
},
356
"depth": {
357
"type": "integer",
358
"description": "Maximum traversal depth",
359
"default": 3
360
}
361
},
362
"required": ["name"]
363
}
364
```
365
366
**Output:** Array of `ContextNode` objects ordered by distance from the starting node.
367
368
---
369
370
## Security
371
372
### Read-only mode
373
374
Start the server in read-only mode to prevent agents from modifying the graph:
375
376
```bash
377
navegador mcp --read-only
378
```
379
380
In read-only mode:
381
- The `ingest` tool is disabled (returns an error if called)
382
- The `query` tool validates that queries contain only `MATCH`, `RETURN`, `WITH`, `WHERE`, `ORDER BY`, `LIMIT`, and `SKIP` clauses
383
- Write Cypher keywords (`CREATE`, `MERGE`, `SET`, `DELETE`, `DETACH`) are rejected
384
385
### Query complexity limits
386
387
Set a maximum query complexity to prevent runaway traversals:
388
389
```bash
390
navegador mcp --max-query-complexity 100
391
```
392
393
Or in `.navegador/config.toml`:
394
395
```toml
396
[mcp]
397
max_query_complexity = 100
398
```
399
400
Queries that exceed the complexity threshold return an error rather than executing.
401

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button