Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,90 @@ Analyzes code structure, dependencies, and relationships across a repository. Us
- Cleans up temporary files automatically
- Cross-platform compatible

### Individual Graph Tools

For targeted analysis, use these specialized tools instead of the comprehensive `explore_codebase`:

#### `get_call_graph`

Generate a function-level call graph showing caller/callee relationships.

**Use this to:**
- Find all functions that call a specific function
- Find all functions called by a specific function
- Trace call chains through the codebase
- Understand function dependencies

**Parameters:**

| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `directory` | string | Yes | Path to repository directory |
| `jq_filter` | string | No | jq filter for custom data extraction |

#### `get_dependency_graph`

Generate a module-level dependency graph showing import relationships.

**Use this to:**
- Understand module dependencies
- Find circular dependencies
- Identify tightly coupled modules
- Plan module extraction or refactoring

**Parameters:**

| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `directory` | string | Yes | Path to repository directory |
| `jq_filter` | string | No | jq filter for custom data extraction |

#### `get_domain_graph`

Generate a high-level domain classification graph.

**Use this to:**
- Understand the architectural domains in a codebase
- See how code is organized into logical areas
- Get a bird's-eye view of system structure
- Identify domain boundaries

**Parameters:**

| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `directory` | string | Yes | Path to repository directory |
| `jq_filter` | string | No | jq filter for custom data extraction |

#### `get_parse_graph`

Generate an AST-level parse graph with fine-grained code structure.

**Use this to:**
- Analyze detailed code structure
- Find specific syntax patterns
- Understand class/function definitions at AST level
- Support precise refactoring operations

**Parameters:**

| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `directory` | string | Yes | Path to repository directory |
| `jq_filter` | string | No | jq filter for custom data extraction |
Comment on lines +311 to +367
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Clarify that directory can be omitted when a default workdir is set.

The server supports a default working directory and passes it to tools, but these tables mark directory as strictly required. This can confuse users who rely on the CLI default (e.g., node dist/index.js /path/to/repo).

Doc tweak example
-| `directory` | string | Yes | Path to repository directory |
+| `directory` | string | Yes* | Path to repository directory |
 ...
+* If the server was started with a default working directory, `directory` can be omitted.
🤖 Prompt for AI Agents
In `@README.md` around lines 311 - 367, The README marks the `directory` parameter
as required for get_dependency_graph, get_domain_graph, and get_parse_graph even
though the server can use a configured default working directory; update each
parameters table for `get_dependency_graph`, `get_domain_graph`, and
`get_parse_graph` to mark `directory` as optional (or indicate "Optional if
default workdir is set"), keep `jq_filter` optional, and add a short clarifying
sentence/note explaining that if a default workdir is configured the `directory`
argument may be omitted (include a brief CLI example like `node dist/index.js
/path/to/repo` or the equivalent to show omission). Ensure the wording is
consistent across all three function docs.


### Choosing the Right Tool

| Tool | Best For | Output Size |
|------|----------|-------------|
| `explore_codebase` | Comprehensive analysis with built-in queries | Largest - all graph types |
| `get_call_graph` | Function call tracing, debugging | Medium - functions only |
| `get_dependency_graph` | Module refactoring, circular deps | Small - modules only |
| `get_domain_graph` | Architecture overview | Smallest - domains only |
| `get_parse_graph` | AST analysis, precise refactoring | Large - full AST |

**Tip:** Start with `get_domain_graph` for a quick architecture overview, then drill down with `get_call_graph` or `get_dependency_graph` for specific areas.

## Tool Performance & Timeout Requirements

The `explore_codebase` tool analyzes your entire repository to build a comprehensive code graph. Analysis time scales with repository size and complexity.
Expand Down Expand Up @@ -502,6 +586,69 @@ To enable verbose logging, set the `DEBUG` environment variable:

Benchmark this MCP server using [mcpbr](https://github.com/caspianmoon/mcpbr-benchmark-caching) with the provided [`mcpbr-config.yaml`](./mcpbr-config.yaml) configuration.

## Local Development & Testing

### Building from Source

```bash
git clone https://github.com/supermodeltools/mcp.git
cd mcp
npm install
npm run build
```

### Running Locally

```bash
# Start the MCP server
node dist/index.js

# Or with a default working directory
node dist/index.js /path/to/repo
```

### Testing Tools Locally

Run the integration tests to verify the server and tools:

```bash
# Run all tests including integration tests
npm test

# Run only integration tests
npm test -- src/server.integration.test.ts
```

### Using MCP Inspector

For interactive testing, use the [MCP Inspector](https://github.com/modelcontextprotocol/inspector):

```bash
# Install the inspector
npm install -g @modelcontextprotocol/inspector

# Run with your server
npx @modelcontextprotocol/inspector node dist/index.js
```

This opens a web UI where you can:
- See all available tools
- Call tools with custom arguments
- View responses in real-time

### Running Tests

```bash
# Run all tests
npm test

# Run with coverage
npm run test:coverage

# Type checking
npm run typecheck
```

## Links

- [API Documentation](https://docs.supermodeltools.com)
Expand Down
22 changes: 22 additions & 0 deletions src/filtering.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
/**
* jq filtering utilities for JSON response transformation.
* Provides optional jq filter application to API responses.
* @module filtering
*/
// @ts-nocheck
import initJq from 'jq-web';

/**
* Optionally applies a jq filter to a response object.
* @param jqFilter - The jq filter string, or undefined to skip filtering
* @param response - The JSON response to filter
* @returns The filtered response, or the original response if no filter provided
*/
export async function maybeFilter(jqFilter: unknown | undefined, response: any): Promise<any> {
if (jqFilter && typeof jqFilter === 'string') {
return await jq(response, jqFilter);
Expand All @@ -9,10 +20,21 @@ export async function maybeFilter(jqFilter: unknown | undefined, response: any):
}
}

/**
* Applies a jq filter to JSON data.
* @param json - The JSON data to filter
* @param jqFilter - The jq filter expression
* @returns The filtered result
*/
async function jq(json: any, jqFilter: string) {
return (await initJq).json(json, jqFilter);
}

/**
* Type guard to check if an error is a jq parsing error.
* @param error - The error to check
* @returns True if the error is a jq-related error with stderr output
*/
export function isJqError(error: any): error is Error {
return error instanceof Error && 'stderr' in error;
}
Expand Down
9 changes: 9 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
#!/usr/bin/env node
/**
* Entry point for the Supermodel MCP Server.
* Starts the MCP server with optional default working directory.
* @module index
*/
import { Server } from './server';
import * as logger from './utils/logger';

/**
* Main entry point that initializes and starts the MCP server.
* Accepts an optional workdir argument from the command line.
*/
async function main() {
// Parse command-line arguments to get optional default workdir
// Usage: node dist/index.js [workdir]
Expand Down
Loading