CodeAlive exposes query_artifact_metadata for querying the metrics and structure of indexed code. An agent can find functions with high cognitive complexity and many incoming call relationships, or calculate average complexity by namespace.
These questions require calculated metrics and a call graph. CodeAlive makes them available through the same MCP server the agent uses to search and read source. Queries use ArtifactQuery v1, a small, read-only SQL-like language.
How a QA agent uses it
One of our customers built an internal AI tool for QA. It reads code through CodeAlive and writes test cases for a task. When interface or DTO names appear in the diff, the agent finds their declarations, reads their fields, and uses that information to prepare test cases.
Here is an example based on that workflow:
A known name can also be found with grep. The customer uses a symbol query to get declarations with paths and identifiers ready for fetch_artifacts. If several modules declare the same name, path and namespace help select the right one.
For a DTO such as ParcelRouteWindowRequestDto, the sequence is the same: find the declaration, retrieve its source, and read its fields. The metadata query itself does not return the DTO's fields.
Alongside statement, the agent passes data_sources: repository or workspace names returned by get_data_sources. The following examples use those same arguments; substitute paths from your project.
Which functions to read before refactoring
In a large codebase, a list of the longest functions can become unhelpful quickly. For a first pass, use a narrower criterion: high complexity combined with many direct call relationships.
The query selects up to twenty functions with implementations that are not marked as tests, ordered by complexity. The thresholds of 15 and 10 are illustrative.
This lets the agent start with functions that are difficult to read and have many direct callers. It opens their source with fetch_artifacts, retrieves callers with get_artifact_relationships, and checks which scenarios the refactoring needs to preserve.
Searching for function names alone cannot produce this list. First you would need to calculate complexity, resolve calls, and combine the results. The tool uses data already collected by the index.
CodeAlive's complexity is a cognitive-load score, rather than cyclomatic complexity. incoming_calls_count counts direct indexed relationships. It does not establish production execution frequency or the full effect of a change.
Where a module's dependencies concentrate
Suppose you need to change public methods in a payments module. Before editing, inspect how their incoming relationships are distributed across directories:
The summary suggests where to start reading API consumers. For individual functions, the agent expands their relationships and checks whether the change reaches neighboring parts of the system. That evidence helps determine PR boundaries.
The relationship sum is not a count of unique consumers: one function can call several methods in the selected module. Separate directories do not establish independent changes either.
Another view of the code is complexity by namespace:
Use this to choose a module for the next review pass, then query individual functions in that namespace. The count alongside the average shows the population size; source inspection determines which functions need changes.
The complexity >= 0 condition keeps functions with a calculated score, including zero. Without it, COUNT(*) and AVG(complexity) could describe different populations. Functions without a score can be checked separately with complexity IS NULL.
Other query capabilities
ArtifactQuery operates on files, symbols, functions, and containers. Depending on the entity, fields include file sizes and line counts, languages, symbol kinds and visibility, test and recursion flags, return types, reference counts, and descendant counts. Filtering, sorting, grouping, and the aggregates COUNT(*), AVG, MIN, MAX, and SUM are supported.
Fields differ in which operations they allow. get_artifact_query_schema returns the current schema and examples, so an agent can check field names and supported groupings.
Results describe the selected indexed scope: freshness, excluded paths, and language support matter. Every query requires LIMIT between 1 and 100. It caps output rows or groups; aggregates use all matching records in scope. A broad query can exceed its execution budget, requiring a narrower directory or conditions.
Content search and graph navigation use separate tools. See the CodeAlive MCP documentation for tool descriptions and connection instructions.