@depxray/mcp 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # @depxray/mcp
2
+
3
+ Give AI coding agents dependency-aware context before they edit your code.
4
+
5
+ `@depxray/mcp` is the Model Context Protocol server for depxray. It lets MCP-compatible clients such as Claude Desktop, Cursor, and other coding agents inspect JavaScript and TypeScript projects through static dependency analysis.
6
+
7
+ Use it when an agent needs to answer questions like:
8
+
9
+ - What does this file import?
10
+ - What files depend on this file?
11
+ - Are there circular dependencies?
12
+ - Which files appear to be orphaned?
13
+ - What is inside this folder?
14
+ - What does the project dependency graph look like?
15
+
16
+ The server runs locally over stdio and uses `@depxray/core`, the same scanner that powers the `depxray` CLI and browser UI.
17
+
18
+ ## Quick Start
19
+
20
+ ```bash
21
+ npx @depxray/mcp
22
+ ```
23
+
24
+ Most users do not run this command directly. Add it to your MCP client configuration so the client can start the server when needed.
25
+
26
+ ## Why Use This
27
+
28
+ - Help coding agents understand a repository before making edits
29
+ - Inspect imports and dependents for a target file
30
+ - Find circular dependencies before refactors
31
+ - Find orphan files that may be safe cleanup candidates
32
+ - Summarize folder-level dependency relationships
33
+ - Produce machine-readable project structure and dependency graph context
34
+
35
+ `@depxray/mcp` is especially useful for agentic coding workflows where the agent should inspect dependency impact before changing source files.
36
+
37
+ ## Claude Desktop Setup
38
+
39
+ Add this to your Claude Desktop MCP configuration:
40
+
41
+ ```json
42
+ {
43
+ "mcpServers": {
44
+ "depxray": {
45
+ "command": "npx",
46
+ "args": ["@depxray/mcp"]
47
+ }
48
+ }
49
+ }
50
+ ```
51
+
52
+ ## Cursor Setup
53
+
54
+ Add a new MCP server with:
55
+
56
+ ```json
57
+ {
58
+ "command": "npx",
59
+ "args": ["@depxray/mcp"]
60
+ }
61
+ ```
62
+
63
+ ## Agent Workflow Example
64
+
65
+ A coding agent can use the tools in this order before editing:
66
+
67
+ 1. Call `get_file_tree` to understand the project layout.
68
+ 2. Call `inspect_file` for the file it plans to modify.
69
+ 3. Call `get_folder_summary` for the surrounding folder.
70
+ 4. Call `find_circular` or `find_orphans` when planning a refactor.
71
+ 5. Call `scan_project` when it needs full graph context.
72
+
73
+ This gives the agent a clearer view of dependency impact before it changes code.
74
+
75
+ ## Tools
76
+
77
+ | Tool | Use When | Example Input |
78
+ | --- | --- | --- |
79
+ | `scan_project` | The agent needs full structure or dependency graph data. | `{ "rootDir": "/path/to/project", "mode": "dependencies" }` |
80
+ | `inspect_file` | The agent needs imports, dependents, and metrics for one file. | `{ "rootDir": "/path/to/project", "filePath": "src/App.tsx" }` |
81
+ | `find_circular` | The agent should detect dependency cycles before a refactor. | `{ "rootDir": "/path/to/project" }` |
82
+ | `find_orphans` | The agent should find files with no incoming references. | `{ "rootDir": "/path/to/project" }` |
83
+ | `get_file_tree` | The agent needs a compact project tree. | `{ "rootDir": "/path/to/project", "maxDepth": 3 }` |
84
+ | `get_folder_summary` | The agent needs folder-level dependency metrics. | `{ "rootDir": "/path/to/project", "folderPath": "src/components" }` |
85
+
86
+ `scan_project` supports `mode: "dependencies"` and `mode: "structure"`. Dependency mode returns imports, circular counts, orphan files, and graph edges. Structure mode returns directory and file parent-child graph data.
87
+
88
+ ## Supported Projects
89
+
90
+ `@depxray/mcp` analyzes JavaScript and TypeScript projects with:
91
+
92
+ - `.js`, `.jsx`, `.ts`, and `.tsx` files
93
+ - static imports
94
+ - type-only imports
95
+ - dynamic imports
96
+ - CommonJS `require`
97
+ - re-exports and barrel files
98
+ - `tsconfig.json` and `jsconfig.json` path aliases
99
+
100
+ ## Privacy
101
+
102
+ The MCP server runs locally and performs static analysis on files in the project paths provided by the MCP client. It does not send your source code to depxray or any external depxray service.
103
+
104
+ Your MCP client may still send tool results to its own model provider. Review your client configuration and provider policy if you are working with private code.
105
+
106
+ ## Relationship To `depxray`
107
+
108
+ This package is the MCP interface for depxray.
109
+
110
+ - Use `npx depxray scan` for the browser UI, CLI JSON output, and static HTML reports.
111
+ - Use `npx @depxray/mcp` when an MCP-compatible AI coding agent needs depxray tools.
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ export declare function createDepxrayMcpServer(): McpServer;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAepE,wBAAgB,sBAAsB,IAAI,SAAS,CAoFlD"}
package/dist/index.js ADDED
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+ import { pathToFileURL } from 'node:url';
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
+ import { z } from 'zod';
7
+ import { findCircularTool } from './tools/findCircular.js';
8
+ import { findOrphansTool } from './tools/findOrphans.js';
9
+ import { getFileTreeTool } from './tools/getFileTree.js';
10
+ import { getFolderSummaryTool } from './tools/getFolderSummary.js';
11
+ import { inspectFileTool } from './tools/inspectFile.js';
12
+ import { scanProjectTool } from './tools/scanProject.js';
13
+ import { jsonContent } from './tools/shared.js';
14
+ const require = createRequire(import.meta.url);
15
+ const packageJson = require('../package.json');
16
+ const rootDirSchema = z.string().min(1).describe('Absolute or relative project root directory.');
17
+ export function createDepxrayMcpServer() {
18
+ const server = new McpServer({
19
+ name: 'depxray',
20
+ version: packageJson.version,
21
+ });
22
+ server.registerTool('scan_project', {
23
+ title: 'Scan project',
24
+ description: 'Scan a project and return graph data for structure or dependency analysis.',
25
+ inputSchema: {
26
+ rootDir: rootDirSchema,
27
+ mode: z.enum(['structure', 'dependencies']).optional().describe('Graph mode to return. Defaults to dependencies.'),
28
+ },
29
+ }, async (input) => jsonContent(await scanProjectTool(input)));
30
+ server.registerTool('inspect_file', {
31
+ title: 'Inspect file',
32
+ description: 'Return imports, dependents, and dependency metrics for one project file.',
33
+ inputSchema: {
34
+ filePath: z.string().min(1).describe('File path to inspect. Relative paths resolve from rootDir.'),
35
+ rootDir: rootDirSchema.optional().describe('Project root directory. Defaults to the MCP process working directory.'),
36
+ },
37
+ }, async (input) => jsonContent(await inspectFileTool(input)));
38
+ server.registerTool('find_circular', {
39
+ title: 'Find circular dependencies',
40
+ description: 'Find circular dependency chains in a project.',
41
+ inputSchema: {
42
+ rootDir: rootDirSchema,
43
+ },
44
+ }, async (input) => jsonContent(await findCircularTool(input)));
45
+ server.registerTool('find_orphans', {
46
+ title: 'Find orphan files',
47
+ description: 'Find source files with no inbound dependency references, excluding configured entry points.',
48
+ inputSchema: {
49
+ rootDir: rootDirSchema,
50
+ entryPointPatterns: z.array(z.string().min(1)).optional().describe('Optional glob patterns to exclude entry points from orphan results.'),
51
+ },
52
+ }, async (input) => jsonContent(await findOrphansTool(input)));
53
+ server.registerTool('get_file_tree', {
54
+ title: 'Get file tree',
55
+ description: 'Return the project file tree, optionally limited by traversal depth.',
56
+ inputSchema: {
57
+ rootDir: rootDirSchema,
58
+ maxDepth: z.number().int().nonnegative().optional().describe('Maximum folder depth to scan.'),
59
+ },
60
+ }, async (input) => jsonContent(await getFileTreeTool(input)));
61
+ server.registerTool('get_folder_summary', {
62
+ title: 'Get folder summary',
63
+ description: 'Return dependency metrics for a folder, including internal, incoming, outgoing, circular, and orphan references.',
64
+ inputSchema: {
65
+ rootDir: rootDirSchema,
66
+ folderPath: z.string().min(1).describe('Folder path to summarize. Relative paths resolve from rootDir.'),
67
+ },
68
+ }, async (input) => jsonContent(await getFolderSummaryTool(input)));
69
+ return server;
70
+ }
71
+ async function main() {
72
+ const server = createDepxrayMcpServer();
73
+ await server.connect(new StdioServerTransport());
74
+ }
75
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
76
+ main().catch((error) => {
77
+ const message = error instanceof Error ? error.stack ?? error.message : String(error);
78
+ console.error(message);
79
+ process.exit(1);
80
+ });
81
+ }
82
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export interface FindCircularInput {
2
+ rootDir: string;
3
+ }
4
+ export declare function findCircularTool(input: FindCircularInput): Promise<{
5
+ count: number;
6
+ chains: import("@depxray/core").CircularChain[];
7
+ }>;
8
+ //# sourceMappingURL=findCircular.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findCircular.d.ts","sourceRoot":"","sources":["../../src/tools/findCircular.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB;;;GAQ9D"}
@@ -0,0 +1,11 @@
1
+ import { scanProject } from '@depxray/core';
2
+ import { resolveRootDir } from './shared.js';
3
+ export async function findCircularTool(input) {
4
+ const rootDir = resolveRootDir(input.rootDir);
5
+ const result = await scanProject({ rootDir, detectCircular: true });
6
+ return {
7
+ count: result.graph.circularDependencies.length,
8
+ chains: result.graph.circularDependencies,
9
+ };
10
+ }
11
+ //# sourceMappingURL=findCircular.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findCircular.js","sourceRoot":"","sources":["../../src/tools/findCircular.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAM7C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAwB;IAC7D,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpE,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,MAAM;QAC/C,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,oBAAoB;KAC1C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface FindOrphansInput {
2
+ rootDir: string;
3
+ entryPointPatterns?: string[];
4
+ }
5
+ export declare function findOrphansTool(input: FindOrphansInput): Promise<{
6
+ count: number;
7
+ orphanFiles: string[];
8
+ }>;
9
+ //# sourceMappingURL=findOrphans.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findOrphans.d.ts","sourceRoot":"","sources":["../../src/tools/findOrphans.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,gBAAgB;;;GAY5D"}
@@ -0,0 +1,15 @@
1
+ import { scanProject } from '@depxray/core';
2
+ import { resolveRootDir } from './shared.js';
3
+ export async function findOrphansTool(input) {
4
+ const rootDir = resolveRootDir(input.rootDir);
5
+ const result = await scanProject({
6
+ rootDir,
7
+ detectCircular: true,
8
+ entryPointPatterns: input.entryPointPatterns,
9
+ });
10
+ return {
11
+ count: result.orphanFiles.length,
12
+ orphanFiles: result.orphanFiles,
13
+ };
14
+ }
15
+ //# sourceMappingURL=findOrphans.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findOrphans.js","sourceRoot":"","sources":["../../src/tools/findOrphans.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAO7C,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAuB;IAC3D,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC;QAC/B,OAAO;QACP,cAAc,EAAE,IAAI;QACpB,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;KAC7C,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM;QAChC,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface GetFileTreeInput {
2
+ rootDir: string;
3
+ maxDepth?: number;
4
+ }
5
+ export declare function getFileTreeTool(input: GetFileTreeInput): Promise<import("@depxray/core").FileTreeNode>;
6
+ //# sourceMappingURL=getFileTree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getFileTree.d.ts","sourceRoot":"","sources":["../../src/tools/getFileTree.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,gBAAgB,iDAI5D"}
@@ -0,0 +1,8 @@
1
+ import { scanFileTree } from '@depxray/core';
2
+ import { resolveRootDir } from './shared.js';
3
+ export async function getFileTreeTool(input) {
4
+ return scanFileTree(resolveRootDir(input.rootDir), {
5
+ maxDepth: input.maxDepth ?? Infinity,
6
+ });
7
+ }
8
+ //# sourceMappingURL=getFileTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getFileTree.js","sourceRoot":"","sources":["../../src/tools/getFileTree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAO7C,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAuB;IAC3D,OAAO,YAAY,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;QACjD,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,QAAQ;KACrC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,27 @@
1
+ export interface GetFolderSummaryInput {
2
+ rootDir: string;
3
+ folderPath: string;
4
+ }
5
+ export declare function getFolderSummaryTool(input: GetFolderSummaryInput): Promise<{
6
+ folder: string;
7
+ absolutePath: string;
8
+ directChildren: number;
9
+ descendants: number;
10
+ totalFiles: number;
11
+ internalImports: number;
12
+ incomingExternalRefs: number;
13
+ outgoingExternalRefs: number;
14
+ circularFiles: string[];
15
+ orphanFiles: string[];
16
+ incomingExternal: {
17
+ source: string;
18
+ target: string;
19
+ specifier: string;
20
+ }[];
21
+ outgoingExternal: {
22
+ source: string;
23
+ target: string;
24
+ specifier: string;
25
+ }[];
26
+ }>;
27
+ //# sourceMappingURL=getFolderSummary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getFolderSummary.d.ts","sourceRoot":"","sources":["../../src/tools/getFolderSummary.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,qBAAqB;;;;;;;;;;;;;;;;;;;;;GAkEtE"}
@@ -0,0 +1,58 @@
1
+ import * as path from 'node:path';
2
+ import { scanFileTree, scanProject, } from '@depxray/core';
3
+ import { assertPathInsideRoot, flattenTree, resolveProjectPath, resolveRootDir, } from './shared.js';
4
+ export async function getFolderSummaryTool(input) {
5
+ const rootDir = resolveRootDir(input.rootDir);
6
+ const folderAbsolutePath = resolveProjectPath(rootDir, input.folderPath);
7
+ assertPathInsideRoot(rootDir, folderAbsolutePath);
8
+ const [tree, result] = await Promise.all([
9
+ scanFileTree(rootDir),
10
+ scanProject({ rootDir, detectCircular: true }),
11
+ ]);
12
+ const allTreeNodes = flattenTree(tree);
13
+ const folderNode = allTreeNodes.find((node) => node.absolutePath === folderAbsolutePath);
14
+ if (!folderNode) {
15
+ throw new Error(`Folder not found: ${input.folderPath}`);
16
+ }
17
+ if (folderNode.kind !== 'directory') {
18
+ throw new Error(`Not a directory: ${input.folderPath}`);
19
+ }
20
+ const fileIds = new Set(result.graph.nodes
21
+ .filter((node) => {
22
+ const relative = path.relative(folderAbsolutePath, node.id);
23
+ return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
24
+ })
25
+ .map((node) => node.id));
26
+ const circularFiles = result.graph.nodes
27
+ .filter((node) => fileIds.has(node.id) && node.isCircular)
28
+ .map((node) => node.relativePath);
29
+ const orphanFiles = result.graph.nodes
30
+ .filter((node) => fileIds.has(node.id) && result.orphanFiles.includes(node.relativePath))
31
+ .map((node) => node.relativePath);
32
+ const internalImports = result.graph.edges.filter((edge) => (fileIds.has(edge.source) && fileIds.has(edge.target)));
33
+ const incomingExternal = result.graph.edges.filter((edge) => (!fileIds.has(edge.source) && fileIds.has(edge.target)));
34
+ const outgoingExternal = result.graph.edges.filter((edge) => (fileIds.has(edge.source) && !fileIds.has(edge.target)));
35
+ return {
36
+ folder: folderNode.relativePath,
37
+ absolutePath: folderNode.absolutePath,
38
+ directChildren: folderNode.children.length,
39
+ descendants: flattenTree(folderNode).length - 1,
40
+ totalFiles: fileIds.size,
41
+ internalImports: internalImports.length,
42
+ incomingExternalRefs: incomingExternal.length,
43
+ outgoingExternalRefs: outgoingExternal.length,
44
+ circularFiles,
45
+ orphanFiles,
46
+ incomingExternal: incomingExternal.map((edge) => ({
47
+ source: path.relative(rootDir, edge.source),
48
+ target: path.relative(rootDir, edge.target),
49
+ specifier: edge.importSpecifier,
50
+ })),
51
+ outgoingExternal: outgoingExternal.map((edge) => ({
52
+ source: path.relative(rootDir, edge.source),
53
+ target: path.relative(rootDir, edge.target),
54
+ specifier: edge.importSpecifier,
55
+ })),
56
+ };
57
+ }
58
+ //# sourceMappingURL=getFolderSummary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getFolderSummary.js","sourceRoot":"","sources":["../../src/tools/getFolderSummary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export interface InspectFileInput {
2
+ filePath: string;
3
+ rootDir?: string;
4
+ }
5
+ export declare function inspectFileTool(input: InspectFileInput): Promise<{
6
+ file: string;
7
+ absolutePath: string;
8
+ extension: string;
9
+ inDegree: number;
10
+ outDegree: number;
11
+ isCircular: boolean;
12
+ isOrphan: boolean;
13
+ imports: {
14
+ file: string;
15
+ absolutePath: string;
16
+ specifier: string;
17
+ names: string[];
18
+ isTypeOnly: boolean;
19
+ isDynamic: boolean;
20
+ }[];
21
+ dependents: {
22
+ file: string;
23
+ absolutePath: string;
24
+ specifier: string;
25
+ names: string[];
26
+ isTypeOnly: boolean;
27
+ isDynamic: boolean;
28
+ }[];
29
+ }>;
30
+ //# sourceMappingURL=inspectFile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspectFile.d.ts","sourceRoot":"","sources":["../../src/tools/inspectFile.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;GA6C5D"}
@@ -0,0 +1,48 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import * as path from 'node:path';
3
+ import { scanProject } from '@depxray/core';
4
+ import { assertPathInsideRoot, resolveProjectPath, resolveRootDir, } from './shared.js';
5
+ export async function inspectFileTool(input) {
6
+ const rootDir = resolveRootDir(input.rootDir ?? process.cwd());
7
+ const filePath = resolveProjectPath(rootDir, input.filePath);
8
+ assertPathInsideRoot(rootDir, filePath);
9
+ try {
10
+ await fs.access(filePath);
11
+ }
12
+ catch {
13
+ throw new Error(`File not found: ${filePath}`);
14
+ }
15
+ const result = await scanProject({ rootDir, detectCircular: true });
16
+ const node = result.graph.nodes.find((graphNode) => graphNode.id === filePath);
17
+ if (!node) {
18
+ throw new Error(`File not found in dependency graph: ${input.filePath}`);
19
+ }
20
+ const imports = result.graph.edges.filter((edge) => edge.source === filePath);
21
+ const dependents = result.graph.edges.filter((edge) => edge.target === filePath);
22
+ return {
23
+ file: node.relativePath,
24
+ absolutePath: node.id,
25
+ extension: node.extension,
26
+ inDegree: node.inDegree,
27
+ outDegree: node.outDegree,
28
+ isCircular: node.isCircular,
29
+ isOrphan: result.orphanFiles.includes(node.relativePath),
30
+ imports: imports.map((edge) => ({
31
+ file: path.relative(rootDir, edge.target),
32
+ absolutePath: edge.target,
33
+ specifier: edge.importSpecifier,
34
+ names: edge.importedNames,
35
+ isTypeOnly: edge.isTypeOnly,
36
+ isDynamic: edge.isDynamic,
37
+ })),
38
+ dependents: dependents.map((edge) => ({
39
+ file: path.relative(rootDir, edge.source),
40
+ absolutePath: edge.source,
41
+ specifier: edge.importSpecifier,
42
+ names: edge.importedNames,
43
+ isTypeOnly: edge.isTypeOnly,
44
+ isDynamic: edge.isDynamic,
45
+ })),
46
+ };
47
+ }
48
+ //# sourceMappingURL=inspectFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspectFile.js","sourceRoot":"","sources":["../../src/tools/inspectFile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,GACf,MAAM,aAAa,CAAC;AAOrB,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAuB;IAC3D,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC7D,oBAAoB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAExC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;IAC/E,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,uCAAuC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;IAC9E,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;IAEjF,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,YAAY;QACvB,YAAY,EAAE,IAAI,CAAC,EAAE;QACrB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC;QACxD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC9B,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;YACzC,YAAY,EAAE,IAAI,CAAC,MAAM;YACzB,SAAS,EAAE,IAAI,CAAC,eAAe;YAC/B,KAAK,EAAE,IAAI,CAAC,aAAa;YACzB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;QACH,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACpC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;YACzC,YAAY,EAAE,IAAI,CAAC,MAAM;YACzB,SAAS,EAAE,IAAI,CAAC,eAAe;YAC/B,KAAK,EAAE,IAAI,CAAC,aAAa;YACzB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { GraphMode } from './shared.js';
2
+ export interface ScanProjectInput {
3
+ rootDir: string;
4
+ mode?: GraphMode;
5
+ }
6
+ export declare function scanProjectTool(input: ScanProjectInput): Promise<import("./shared.js").ExplorerGraphData>;
7
+ //# sourceMappingURL=scanProject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanProject.d.ts","sourceRoot":"","sources":["../../src/tools/scanProject.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAO7C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,gBAAgB,oDAW5D"}
@@ -0,0 +1,13 @@
1
+ import { buildStructureGraph, scanFileTree, scanProject, } from '@depxray/core';
2
+ import { resolveRootDir, toDependencyGraphData, toStructureGraphData, } from './shared.js';
3
+ export async function scanProjectTool(input) {
4
+ const rootDir = resolveRootDir(input.rootDir);
5
+ const mode = input.mode ?? 'dependencies';
6
+ if (mode === 'structure') {
7
+ const tree = await scanFileTree(rootDir);
8
+ return toStructureGraphData(buildStructureGraph(tree));
9
+ }
10
+ const result = await scanProject({ rootDir, detectCircular: true });
11
+ return toDependencyGraphData(result);
12
+ }
13
+ //# sourceMappingURL=scanProject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanProject.js","sourceRoot":"","sources":["../../src/tools/scanProject.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,WAAW,GACZ,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAOrB,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAuB;IAC3D,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,cAAc,CAAC;IAE1C,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;QACzC,OAAO,oBAAoB,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,OAAO,qBAAqB,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { FileTreeNode, ScanError, ScanResult, StructureGraph, StructureGraphEdge, StructureGraphNode } from '@depxray/core';
2
+ export type GraphMode = 'structure' | 'dependencies';
3
+ export interface ExplorerGraphNode extends StructureGraphNode {
4
+ inDegree?: number;
5
+ outDegree?: number;
6
+ isCircular?: boolean;
7
+ isOrphan?: boolean;
8
+ componentName?: string;
9
+ }
10
+ export interface ExplorerGraphEdge extends StructureGraphEdge {
11
+ kind: GraphMode;
12
+ importSpecifier?: string;
13
+ importedNames?: string[];
14
+ isTypeOnly?: boolean;
15
+ isDynamic?: boolean;
16
+ }
17
+ export interface ExplorerGraphData {
18
+ schemaVersion: string;
19
+ mode: GraphMode;
20
+ projectRoot: string;
21
+ scannedAt: string;
22
+ totalFiles: number;
23
+ totalDirs: number;
24
+ totalImports: number;
25
+ circularCount: number;
26
+ orphanFiles: string[];
27
+ generatedBy: string;
28
+ errors: ScanError[];
29
+ nodes: ExplorerGraphNode[];
30
+ edges: ExplorerGraphEdge[];
31
+ }
32
+ export declare function resolveRootDir(rootDir: string): string;
33
+ export declare function resolveProjectPath(rootDir: string, targetPath: string): string;
34
+ export declare function assertPathInsideRoot(rootDir: string, targetPath: string): void;
35
+ export declare function jsonContent(data: unknown): {
36
+ content: {
37
+ type: "text";
38
+ text: string;
39
+ }[];
40
+ };
41
+ export declare function toStructureGraphData(graph: StructureGraph): ExplorerGraphData;
42
+ export declare function toDependencyGraphData(result: ScanResult): ExplorerGraphData;
43
+ export declare function flattenTree(rootNode: FileTreeNode): FileTreeNode[];
44
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,SAAS,EACT,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,eAAe,CAAC;AAKvB,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,cAAc,CAAC;AAErD,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,IAAI,EAAE,SAAS,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,KAAK,EAAE,iBAAiB,EAAE,CAAC;CAC5B;AAID,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAI9E;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAK9E;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO;;;;;EASxC;AAMD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,iBAAiB,CAuB7E;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,iBAAiB,CA+C3E;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,YAAY,GAAG,YAAY,EAAE,CAYlE"}
@@ -0,0 +1,113 @@
1
+ import * as path from 'node:path';
2
+ import { createRequire } from 'node:module';
3
+ const require = createRequire(import.meta.url);
4
+ const packageJson = require('../../package.json');
5
+ const EXPORT_SCHEMA_VERSION = '1.0.0';
6
+ export function resolveRootDir(rootDir) {
7
+ return path.resolve(rootDir);
8
+ }
9
+ export function resolveProjectPath(rootDir, targetPath) {
10
+ return path.isAbsolute(targetPath)
11
+ ? path.resolve(targetPath)
12
+ : path.resolve(rootDir, targetPath);
13
+ }
14
+ export function assertPathInsideRoot(rootDir, targetPath) {
15
+ const relative = path.relative(rootDir, targetPath);
16
+ if (relative.startsWith('..') || path.isAbsolute(relative)) {
17
+ throw new Error(`Path is outside project root: ${targetPath}`);
18
+ }
19
+ }
20
+ export function jsonContent(data) {
21
+ return {
22
+ content: [
23
+ {
24
+ type: 'text',
25
+ text: JSON.stringify(data, null, 2),
26
+ },
27
+ ],
28
+ };
29
+ }
30
+ function getGeneratedBy() {
31
+ return `@depxray/mcp@${packageJson.version}`;
32
+ }
33
+ export function toStructureGraphData(graph) {
34
+ const scannedAt = new Date().toISOString();
35
+ const totalFiles = graph.nodes.filter((node) => node.kind === 'file').length;
36
+ const totalDirs = graph.nodes.filter((node) => node.kind === 'directory').length;
37
+ return {
38
+ schemaVersion: EXPORT_SCHEMA_VERSION,
39
+ mode: 'structure',
40
+ projectRoot: graph.rootDir,
41
+ scannedAt,
42
+ totalFiles,
43
+ totalDirs,
44
+ totalImports: 0,
45
+ circularCount: 0,
46
+ orphanFiles: [],
47
+ generatedBy: getGeneratedBy(),
48
+ errors: [],
49
+ nodes: graph.nodes,
50
+ edges: graph.edges.map((edge) => ({
51
+ ...edge,
52
+ kind: 'structure',
53
+ })),
54
+ };
55
+ }
56
+ export function toDependencyGraphData(result) {
57
+ const orphanFileSet = new Set(result.orphanFiles);
58
+ const nodes = result.graph.nodes.map((node) => ({
59
+ id: node.id,
60
+ label: path.basename(node.relativePath),
61
+ relativePath: node.relativePath,
62
+ absolutePath: node.id,
63
+ kind: 'file',
64
+ extension: node.extension,
65
+ depth: Math.max(1, node.relativePath.split(/[/\\]/).filter(Boolean).length),
66
+ collapsed: false,
67
+ hidden: false,
68
+ childCount: node.outDegree,
69
+ descendantCount: Math.max(node.inDegree, node.outDegree),
70
+ inDegree: node.inDegree,
71
+ outDegree: node.outDegree,
72
+ isCircular: node.isCircular,
73
+ isOrphan: orphanFileSet.has(node.relativePath),
74
+ ...(node.componentName ? { componentName: node.componentName } : {}),
75
+ }));
76
+ const edges = result.graph.edges.map((edge, index) => ({
77
+ id: `${edge.source}->${edge.target}-${index}`,
78
+ source: edge.source,
79
+ target: edge.target,
80
+ kind: 'dependencies',
81
+ importSpecifier: edge.importSpecifier,
82
+ importedNames: edge.importedNames,
83
+ isTypeOnly: edge.isTypeOnly,
84
+ isDynamic: edge.isDynamic,
85
+ }));
86
+ return {
87
+ schemaVersion: EXPORT_SCHEMA_VERSION,
88
+ mode: 'dependencies',
89
+ projectRoot: result.graph.rootDir,
90
+ scannedAt: result.graph.metadata.scannedAt,
91
+ totalFiles: result.totalFiles,
92
+ totalDirs: 0,
93
+ totalImports: result.totalImports,
94
+ circularCount: result.circularCount,
95
+ orphanFiles: result.orphanFiles,
96
+ generatedBy: getGeneratedBy(),
97
+ errors: result.errors,
98
+ nodes,
99
+ edges,
100
+ };
101
+ }
102
+ export function flattenTree(rootNode) {
103
+ const nodes = [];
104
+ function visit(node) {
105
+ nodes.push(node);
106
+ for (const child of node.children) {
107
+ visit(child);
108
+ }
109
+ }
110
+ visit(rootNode);
111
+ return nodes;
112
+ }
113
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@depxray/mcp",
3
+ "version": "1.3.0",
4
+ "description": "MCP server for depxray dependency analysis and AI-agent codebase context.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "depxray-mcp": "dist/index.js"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "README.md"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "dev": "tsc --watch",
18
+ "test": "vitest run",
19
+ "clean": "rm -rf dist",
20
+ "prepublishOnly": "node ../../scripts/sync-versions.mjs && npm run build"
21
+ },
22
+ "dependencies": {
23
+ "@depxray/core": "1.3.0",
24
+ "@modelcontextprotocol/sdk": "^1.29.0",
25
+ "zod": "^4.4.3"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^20.0.0",
29
+ "typescript": "^5.4.0",
30
+ "vitest": "^1.6.0"
31
+ },
32
+ "keywords": [
33
+ "mcp",
34
+ "model-context-protocol",
35
+ "dependency-graph",
36
+ "static-analysis",
37
+ "codebase-context",
38
+ "ai-agent",
39
+ "coding-agent",
40
+ "agentic-ai",
41
+ "llm",
42
+ "typescript",
43
+ "javascript"
44
+ ],
45
+ "author": "Pannawish Kriengyakul",
46
+ "license": "MIT",
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/Pannawish/depxray.git"
50
+ }
51
+ }