API Reference
pandō is an MCP toolserver that gives AI agents structural access to your codebase. 27 tools organized into 6 categories for navigation, transformation, snapshots, and maintenance.
Node Paths
Many tools reference code nodes using a path syntax: src/app.ts#FD:0. The # separates the file path from the node address. FD means "function declaration" and :0 is its index. Use find-nodes to discover these paths.
Expected Hashes
Mutation tools require an expectedHash parameter (format p123:c456) to ensure you are operating on the version of code you intend. This prevents race conditions when multiple agents work on the same file. Hashes are returned by query tools.
Boundary Modes
Search tools support three boundary modes: project searches only the current project root, reachable includes dependencies reachable via imports, and workspace searches the entire indexed workspace.
Getting Started
4 toolsCore workspace tools for initializing pandō, setting the project root, and getting an overview of your codebase structure.
read-this-first() Quickstart hints for pandō AST usage
Returns a quickstart guide with essential hints for working with the pandō AST toolserver. Call this first in any new session to understand available capabilities, node path syntax, and recommended workflows.
This tool takes no parameters.
read-this-first()get-project-root() Return the current project root
Returns the absolute path of the currently configured project root. The project root determines the scope of file indexing and the default boundary for search operations.
This tool takes no parameters.
get-project-root()
// Returns: "/Users/dev/my-project"set-project-root(root) Set the project root
Sets the project root directory for pandō (absolute or relative to current root). Must be an existing directory; triggers background indexing.
| Name | Type | Description |
|---|---|---|
| root required | string | Absolute path or path relative to the current project root. Must exist and be a directory. |
{
"root": "./repo"
}workspace-overview() Summarize workspace files, node counts, modules
Returns a structured summary of the current workspace including total file count, node count, module structure, and language breakdown. Useful for understanding the scale and shape of a codebase before diving into queries.
This tool takes no parameters.
workspace-overview()
// Returns workspace stats: files, nodes, modules, languagesQuerying Code
5 toolsNavigate and search your codebase structurally. Find symbols by kind, name, or text content. Trace references, callers, exports, and import graphs.
find-nodes(q, qMode, name, async, exported, static, private, protected, readonly, abstract, paramCount, exportedOnly, defaultOnly, symbolKinds, hasDecorator, implements, extends, returns, asOf, scopeNode, expectedHash, limit, offset, sort, lang, semanticKind, include, cursor, datalog, boundary, reachabilityDepth, reachabilityOptions) Search code nodes by kind, name, text, or scope
The primary search tool for discovering code nodes across the workspace. Supports full-text search, pattern matching on names, filtering by symbol kind, scoping to specific nodes, and Datalog queries for advanced structural searches.
| Name | Type | Description |
|---|---|---|
| q | string | Free-text search query. Searched against node content. |
| qMode | 'fts' | 'like' | Query mode. fts for full-text search, like for SQL LIKE pattern matching. |
| name | string | object | Filter by symbol name. Pass a string for exact match, or an object with like, contains, startsWith, endsWith, or in (array) for pattern matching. |
| symbolKinds | string[] | Filter by AST node kinds: function, class, interface, type, variable, method, property, enum, module, etc. |
| async | boolean | Filter for async functions/methods. |
| exported | boolean | Filter by export status. |
| static | boolean | Filter for static members. |
| private | boolean | Filter for private members. |
| protected | boolean | Filter for protected members. |
| readonly | boolean | Filter for readonly members. |
| abstract | boolean | Filter for abstract members. |
| paramCount | object | Parameter count filter. Keys: op (>, <, >=, <=, =), value (number). |
| exportedOnly | boolean | Only return exported symbols. |
| defaultOnly | boolean | Only return default exports. |
| hasDecorator | string | Filter for nodes with a specific decorator. |
| implements | string | Filter for classes implementing a specific interface. |
| extends | string | Filter for classes extending a specific base class. |
| returns | string | Filter by return type. |
| asOf | string | Snapshot ID for time-travel queries. |
| scopeNode | string | Limit search to descendants of a specific node path (e.g. src/app.ts#CD:0). |
| include | object | Control what data is returned. Keys: self (boolean), body (boolean), parents (boolean), topN (number), maxChars (number). |
| datalog | object | Advanced datalog query spec (bypasses standard filters). Keys: query (string), bindings (string[]), inputs (array), result (object). |
| boundary | 'project' | 'reachable' | 'workspace' | Search boundary. project (default) searches the project root, reachable includes imported dependencies, workspace searches everything indexed. |
| limit | number | Maximum number of results to return. |
| offset | number | Number of results to skip for pagination. |
| sort | object | Sort results. Keys: by (file | name | path), direction (asc | desc). |
| expectedHash | string | Hash (no @) required when scopeNode includes #. |
| lang | string | string[] | Filter by programming language. |
| semanticKind | string | string[] | Filter by semantic kind. |
| cursor | string | Opaque cursor for datalog paging. |
| reachabilityDepth | number | Max depth for reachable boundary. |
| reachabilityOptions | object | Advanced reachability options for boundary='reachable'. |
{
"symbolKinds": ["function"],
"name": "init",
"limit": 10
}find-references(to, expectedHash, boundary, includeDeclaration, includeStrings, includeComments, limit, offset, relType, sort, reachabilityDepth, reachabilityOptions, asOf) Find references to a symbol
Finds all references to a given symbol across the codebase. Can filter by relationship type (call, import, type reference, etc.). Requires the node path and its expected hash to ensure consistency.
| Name | Type | Description |
|---|---|---|
| to required | string | Node path of the target symbol (e.g. src/app.ts#FD:0). |
| expectedHash required | string | Hash of the target node for consistency verification (format: p123:c456). |
| relType | string | Filter by relationship type: call, new, type, reference, import, export, extends, implements. |
| boundary | 'project' | 'reachable' | 'workspace' | Search boundary for reference lookup. |
| limit | number | Maximum number of results to return. |
| offset | number | Number of results to skip for pagination. |
| includeDeclaration | boolean | Include the declaration site in results. |
| includeStrings | boolean | Include references found in string literals. |
| includeComments | boolean | Include references found in comments. |
| sort | object | Sort results. Keys: by, direction. |
| asOf | string | Snapshot ID for time-travel queries. |
| reachabilityDepth | number | Max depth for reachable boundary. |
| reachabilityOptions | object | Advanced reachability options for boundary='reachable'. |
{
"to": "src/app.ts#FD:0",
"expectedHash": "p123:c456"
}find-callers(of, expectedHash, depth, aggregate, boundary, asOf, offset, limit, relType, sort, reachabilityDepth, reachabilityOptions) Find callers of a function or method
Traces the call graph to find all callers of a given function or method. Supports recursive traversal up to a configurable depth, making it useful for impact analysis before refactoring.
| Name | Type | Description |
|---|---|---|
| of required | string | Node path of the function/method to find callers for. |
| expectedHash required | string | Hash of the target node for consistency verification. |
| depth | number | 'all' | How many levels up the call graph to traverse. Maximum 10, or 'all' for full traversal. |
| boundary | 'project' | 'reachable' | 'workspace' | Search boundary for caller lookup. |
| limit | number | Maximum number of results to return. |
| offset | number | Number of results to skip for pagination. |
| aggregate | boolean | Aggregate callers across depth levels. |
| asOf | string | Snapshot ID for time-travel queries. |
| relType | string | Filter by relationship type. |
| sort | object | Sort results. Keys: by, direction. |
| reachabilityDepth | number | Max depth for reachable boundary. |
| reachabilityOptions | object | Advanced reachability options for boundary='reachable'. |
{
"of": "src/service.ts#FD:2",
"expectedHash": "pabc:cdef",
"depth": 2
}list-exports(scope, symbolKinds, export_kinds, limit, offset) List exports from files or directories
Lists all exported symbols from a given scope (file or directory). Can filter by symbol kind and export kind. Useful for understanding the public API surface of a module or package.
| Name | Type | Description |
|---|---|---|
| scope | string | File or directory path to scope the export listing (e.g. packages/ui/). |
| symbolKinds | string[] | Filter by symbol kinds (e.g. ['function', 'class']). |
| export_kinds | string[] | Filter by export kind (named, default, re-export). |
| limit | number | Maximum number of results to return. |
| offset | number | Number of results to skip for pagination. |
{
"scope": "packages/ui/",
"limit": 20
}analyze-imports(groupBy, limit, offset) Analyze imports grouped by module or file
Analyzes the import graph of the project. Groups imports by module (npm package) or by file, providing insight into dependency usage patterns and coupling between modules.
| Name | Type | Description |
|---|---|---|
| groupBy | 'module' | 'file' | How to group the import analysis. module groups by npm package, file groups by source file. |
| limit | number | Maximum number of groups to return. |
| offset | number | Number of groups to skip for pagination. |
{
"groupBy": "module"
}Reading Content
3 toolsRead file content, query the underlying index database, and access the logical schema. These tools provide raw access to the data backing the structural index.
get-content(target, format, maxBytes, offset) Read file content in raw or parsed form
Reads the content of a file or node. Supports raw text output or parsed AST representation. Use maxBytes and offset for streaming large files in chunks.
| Name | Type | Description |
|---|---|---|
| target required | string | File path or node path to read. |
| format | 'raw' | 'parsed' | Output format. raw returns plain text, parsed returns AST. |
| maxBytes | number | Maximum number of bytes to return. |
| offset | number | Byte offset to start reading from. |
{ "target": "src/index.ts", "maxBytes": 2000 }get-db-schema(includeColumns) Return the logical unified index schema
Returns the schema of the underlying SQLite index database. Useful for understanding the data model before writing custom SQL queries with query-db.
| Name | Type | Description |
|---|---|---|
| includeColumns | boolean | When true, includes column definitions for each table. |
{ "includeColumns": true }query-db(sql, maxRows) Execute readonly SQL against index chunks
Executes a read-only SQL query directly against the index database. Supports standard SQLite syntax. Use get-db-schema first to understand available tables.
| Name | Type | Description |
|---|---|---|
| sql required | string | SQL query text to execute against the index chunk databases. |
| maxRows | number | Maximum number of rows to return. |
{ "sql": "SELECT name FROM sqlite_master LIMIT 20", "maxRows": 200 }Code Transformations
5 toolsStructurally modify code with precision. Rename symbols across references, insert and replace nodes, delete code safely, or batch-transform matches with filter-map-reduce.
rename(path, newName, expectedHash, boundary, requireConfirmation, confirmed, includeStrings, includeComments, page, reachabilityDepth, reachabilityOptions) Rename a symbol and update all references
Renames a symbol and automatically updates all references across the codebase. This is a structural rename, not a text find-and-replace, so it only modifies actual references to the symbol.
| Name | Type | Description |
|---|---|---|
| path required | string | Node path of the symbol to rename. |
| newName required | string | The new name for the symbol. |
| expectedHash required | string | Hash for consistency verification (format: p123:c456). |
| boundary | 'project' | 'reachable' | 'workspace' | Search boundary for rename scope. |
| requireConfirmation | boolean | When boundary > project, require explicit approval. |
| confirmed | boolean | Set true to approve cross-project rename. |
| includeStrings | boolean | Also rename occurrences in string literals. |
| includeComments | boolean | Also rename occurrences in comments. |
| page | object | Pagination for cross-project confirmation details. Keys: offset, limit. |
| reachabilityDepth | number | Max depth for reachable boundary. |
| reachabilityOptions | object | Advanced reachability options for boundary='reachable'. |
{
"path": "src/app.ts#FD:0",
"newName": "initApp",
"expectedHash": "p123:c456"
}delete(path, expectedHashes, forceDeleteReferencesMayBreakSyntax, page) Delete code targets and their references
Deletes a code node and optionally removes all references to it. Use forceDeleteReferencesMayBreakSyntax when you want to remove references even if it may leave syntax errors that need manual cleanup.
| Name | Type | Description |
|---|---|---|
| path required | string | Node path of the code to delete. |
| expectedHashes required | string[] | Hash-only entries (no @), same length as path list. |
| forceDeleteReferencesMayBreakSyntax required | boolean | Must be true to proceed with deletion. |
| page | object | Pagination for changedFiles in response. Keys: offset, limit (limit 1..100). |
{
"path": "src/app.ts#FD:0",
"expectedHashes": ["p123:c456"],
"forceDeleteReferencesMayBreakSyntax": true
}insert(to, code, replaceExistingNodeAtPath, expectedHash, createFileIfMissing, newFileInitialContent, forceInsertWillBreakSyntax) Insert raw code at an anchor position
Inserts raw code at a specific anchor position relative to a node. Anchors determine insertion point: before, after, start, end, bodyStartOf, or bodyEndOf a target node.
| Name | Type | Description |
|---|---|---|
| to required | object | Anchor object specifying insertion point. Use one key: before, after, start, end, bodyStartOf, or bodyEndOf, with the node path as value. |
| code required | string | The raw code string to insert. |
| replaceExistingNodeAtPath required | boolean | Must be explicitly true/false. When true, replaces the existing node at the anchor path instead of inserting alongside it. |
| expectedHash | string | Hash for consistency verification (no @). |
| createFileIfMissing | boolean | Create file when using a single file anchor. |
| newFileInitialContent | string | Initial content when creating a file. |
| forceInsertWillBreakSyntax | boolean | Allow syntax errors after insert. |
{
"to": { "bodyEndOf": "src/a.ts#FD:0" },
"code": "\nreturn 1;",
"replaceExistingNodeAtPath": false,
"expectedHash": "p123:c456"
}replace(path, expectedHash, with, scope, forceReplaceWillBreakSyntax) Replace a node with new code
Replaces an entire node or its body with new code. Use scope to control whether the entire node declaration is replaced or just its body content.
| Name | Type | Description |
|---|---|---|
| path required | string | Node path of the code to replace. |
| expectedHash required | string | Hash for consistency verification. |
| with required | string | The replacement code string. |
| scope | 'node' | 'body' | Replace the full node declaration or just its body. |
| forceReplaceWillBreakSyntax | boolean | Allow syntax errors after replacement. |
{
"path": "src/app.ts#FD:0",
"expectedHash": "p123:c456",
"with": "function x() {}"
}filter-map-reduce(query, transforms, apply) Batch apply transforms to matched nodes
A powerful batch transformation tool. First queries for matching nodes (filter), then applies a sequence of transforms (map) to each match. Supports insert, delete, and replace operations with special anchors like $MATCH, $LABEL(name), and $CREATED[idx].
| Name | Type | Description |
|---|---|---|
| query required | object | Query object to find matching nodes. Same shape as find-nodes parameters (symbolKinds, name, etc.). |
| transforms required | object[] | Array of transform operations. Each has op (insert, delete, replace), and operation-specific fields. Use $MATCH as anchor for the matched node, $LABEL(name) for labeled sub-nodes, $CREATED[idx] for previously created nodes. |
| apply | object | Execution controls. Keys: stopOnFirstFailure (boolean), failureThreshold (number), failureRate (number), markFailures (report-only | in-code), maxDurationMs (number), maxMatches (number), pageSize (number, max 100). Omit to perform a dry run. |
{
"query": {
"symbolKinds": ["function"],
"name": "foo"
},
"transforms": [
{
"op": "insert",
"to": { "bodyEndOf": "$MATCH" },
"code": "\nreturn 1;",
"replaceExistingNodeAtPath": false
}
]
}Snapshots & Time Travel
7 toolsCapture, compare, and restore workspace state. Snapshots provide a safety net for complex transformations and enable diffing between any two points in time.
list-snapshots(offset, limit) List available snapshots
Returns a paginated list of all snapshots in the workspace, ordered by creation time. Each snapshot includes its ID, timestamp, message, and file count.
| Name | Type | Description |
|---|---|---|
| offset | number | Number of snapshots to skip for pagination. |
| limit | number | Maximum number of snapshots to return. |
{ "offset": 10, "limit": 20 }diff-snapshots(head, base, page) Diff file membership between snapshots
Compares two snapshots and returns the differences in file membership, showing which files were added, removed, or modified between the base and head snapshots.
| Name | Type | Description |
|---|---|---|
| head required | string | Snapshot ID of the newer state. |
| base | string | Optional base snapshot ID of the older state to compare against. |
| page | number | Page number for paginated diff results. |
{ "head": "S_current", "base": "S_previous" }get-snapshot-trailers(snapshotId, keys) Fetch trailer metadata from a snapshot
Retrieves trailer metadata attached to a specific snapshot. Trailers are key-value pairs stored alongside the snapshot, useful for tracking context like the triggering action or agent identity.
| Name | Type | Description |
|---|---|---|
| snapshotId required | string | ID of the snapshot to read trailers from. |
| keys | string[] | Specific trailer keys to retrieve. Omit to get all trailers. |
{ "snapshotId": "S_current", "keys": ["message", "author"] }get-snapshot-file(snapshotId, path, oid) Read a file at a specific snapshot
Reads the contents of a specific file as it existed at the time of a given snapshot. Useful for reviewing historical state or comparing file versions across time.
| Name | Type | Description |
|---|---|---|
| snapshotId | string | ID of the snapshot to read from. Use with path, or omit and provide oid instead. |
| path | string | Repo-relative file path within the snapshot. Use with snapshotId. |
| oid | string | Blob oid (40 hex), optionally prefixed with blob:. Alternative to snapshotId + path. |
{ "snapshotId": "S_previous", "path": "src/app.ts" }snapshot-worktree(message, trailers) Snapshot current git worktree changes
Captures the current state of the git worktree as a new snapshot. Includes all tracked and untracked changes. Attach a message and optional trailer metadata for context.
| Name | Type | Description |
|---|---|---|
| message | string | Human-readable message describing the snapshot. |
| trailers | object | Key-value pairs of metadata to attach as trailers. |
{ "message": "Before refactoring auth module", "trailers": { "agent": "claude" } }restore-snapshot(snapshotId, trailers, page, shouldCreateNewSnapshot, deleteSnapshotId) Restore entire workspace to a snapshot
Restores the entire workspace to the state captured in a specific snapshot. This overwrites all current files with the snapshot versions. A new snapshot of the current state is automatically created before restoration for safety.
| Name | Type | Description |
|---|---|---|
| snapshotId required | string | ID of the snapshot to restore to. |
| trailers | object | Optional trailers for the restore snapshot. |
| page | object | Pagination for summary items. Keys: offset, limit (limit 1..100). |
| shouldCreateNewSnapshot | boolean | Set false to avoid creating a new snapshot after restore. |
| deleteSnapshotId | string | If shouldCreateNewSnapshot=false, delete this snapshot ID (internal use). |
{ "snapshotId": "S_previous" }restore-files(snapshotId, files, page, trailers) Restore specific files from a snapshot
Restores specific files from a snapshot without affecting the rest of the workspace. Useful for cherry-picking individual file states from history.
| Name | Type | Description |
|---|---|---|
| snapshotId required | string | ID of the snapshot to restore files from. |
| files required | string[] | Array of repo-relative file paths to restore from the snapshot. |
| page | object | Pagination for summary items. Keys: offset, limit (limit 1..100). |
| trailers | object | Optional trailers for the restore snapshot. |
{ "snapshotId": "S_previous", "files": ["src/app.ts", "src/utils.ts"] }Configuration & Maintenance
3 toolsManage index exclusions and repair snapshot history. These tools help maintain a healthy pandō workspace.
repair-history() Repair missing blobs in snapshot history
Scans the snapshot history for missing or corrupted blobs and attempts to repair them. Run this if snapshot operations return errors about missing content.
This tool takes no parameters.
repair-history()add-exclude-dir(directory) Add directory to index exclusion list
Adds a directory to the exclusion list so it will not be indexed by pandō. Useful for excluding build output, vendor directories, or other non-source content.
| Name | Type | Description |
|---|---|---|
| directory required | string | Directory path to exclude from indexing. |
{ "directory": "dist/" }remove-exclude-dir(directory) Remove directory from exclusion list
Removes a directory from the exclusion list, allowing it to be indexed again. The directory will be picked up on the next index refresh.
| Name | Type | Description |
|---|---|---|
| directory required | string | Directory path to remove from the exclusion list. |
{ "directory": "dist/" }Start Building
Install the pandō extension and give your AI agent structural access to your codebase.
View pricing & plans →