smart-context-mcp 1.0.2 → 1.0.3
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 +6 -4
- package/package.json +1 -1
- package/scripts/init-clients.js +1 -1
- package/scripts/report-metrics.js +21 -17
- package/src/mcp-server.js +6 -3
- package/src/utils/runtime-config.js +13 -1
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ npx smart-context-init --target .
|
|
|
27
27
|
|
|
28
28
|
That's it. Restart your AI client (Cursor, Codex, Claude Desktop) and the tools are available.
|
|
29
29
|
|
|
30
|
-
**Important:** The init command automatically sets the correct
|
|
30
|
+
**Important:** The init command automatically sets the correct project-root env var in the generated configs, so the MCP server runs from your project root. This works for standalone projects, monorepos, and nested workspaces.
|
|
31
31
|
|
|
32
32
|
## What you get
|
|
33
33
|
|
|
@@ -233,13 +233,15 @@ or:
|
|
|
233
233
|
DEVCTX_PROJECT_ROOT=/path/to/target-repo node ./src/mcp-server.js
|
|
234
234
|
```
|
|
235
235
|
|
|
236
|
-
or (recommended for MCP clients):
|
|
236
|
+
or (recommended for MCP clients and generated configs):
|
|
237
237
|
|
|
238
238
|
```bash
|
|
239
|
-
|
|
239
|
+
DEVCTX_PROJECT_ROOT=/path/to/target-repo node ./src/mcp-server.js
|
|
240
240
|
```
|
|
241
241
|
|
|
242
|
-
|
|
242
|
+
Legacy configs that still set `MCP_PROJECT_ROOT` remain supported for backward compatibility.
|
|
243
|
+
|
|
244
|
+
`smart-context-init` automatically sets `DEVCTX_PROJECT_ROOT` in the generated client configs (`.cursor/mcp.json`, `.codex/config.toml`, `.mcp.json`, `.qwen/settings.json`), so the MCP server always launches from the correct project context, even in monorepos or when installed globally.
|
|
243
245
|
|
|
244
246
|
## What it is good at
|
|
245
247
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smart-context-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "MCP server that reduces agent token usage and improves response quality with compact file summaries, ranked code search, and curated context.",
|
|
5
5
|
"author": "Francisco Caballero Portero <fcp1978@hotmail.com>",
|
|
6
6
|
"type": "module",
|
package/scripts/init-clients.js
CHANGED
|
@@ -11,7 +11,7 @@ const requireValue = (argv, index, flag) => {
|
|
|
11
11
|
return value;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
-
const parseArgs = (argv) => {
|
|
14
|
+
export const parseArgs = (argv) => {
|
|
15
15
|
const options = {
|
|
16
16
|
file: null,
|
|
17
17
|
json: false,
|
|
@@ -46,7 +46,7 @@ const parseArgs = (argv) => {
|
|
|
46
46
|
|
|
47
47
|
const unique = (items) => [...new Set(items.filter(Boolean))];
|
|
48
48
|
|
|
49
|
-
const resolveMetricsInput = (options) => {
|
|
49
|
+
export const resolveMetricsInput = (options) => {
|
|
50
50
|
if (options.file) {
|
|
51
51
|
return { filePath: options.file, source: 'explicit' };
|
|
52
52
|
}
|
|
@@ -66,7 +66,7 @@ const resolveMetricsInput = (options) => {
|
|
|
66
66
|
return { filePath: defaultPath, source: 'default' };
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
-
const readEntries = (filePath) => {
|
|
69
|
+
export const readEntries = (filePath) => {
|
|
70
70
|
if (!fs.existsSync(filePath)) {
|
|
71
71
|
throw new Error(`No metrics file found at ${filePath}`);
|
|
72
72
|
}
|
|
@@ -100,7 +100,7 @@ const getSavedTokens = (entry, compressedTokens) => {
|
|
|
100
100
|
return Math.max(0, Number(entry.rawTokens ?? 0) - compressedTokens);
|
|
101
101
|
};
|
|
102
102
|
|
|
103
|
-
const aggregate = (entries) => {
|
|
103
|
+
export const aggregate = (entries) => {
|
|
104
104
|
const byTool = new Map();
|
|
105
105
|
let rawTokens = 0;
|
|
106
106
|
let compressedTokens = 0;
|
|
@@ -148,6 +148,21 @@ const aggregate = (entries) => {
|
|
|
148
148
|
|
|
149
149
|
const formatNumber = (value) => new Intl.NumberFormat('en-US').format(value);
|
|
150
150
|
|
|
151
|
+
export const createReport = (options) => {
|
|
152
|
+
const resolved = resolveMetricsInput(options);
|
|
153
|
+
const { entries, invalidLines } = readEntries(resolved.filePath);
|
|
154
|
+
const filteredEntries = options.tool ? entries.filter((entry) => entry.tool === options.tool) : entries;
|
|
155
|
+
const summary = aggregate(filteredEntries);
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
filePath: resolved.filePath,
|
|
159
|
+
source: resolved.source,
|
|
160
|
+
toolFilter: options.tool,
|
|
161
|
+
invalidLines,
|
|
162
|
+
summary,
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
|
|
151
166
|
const printHuman = (report) => {
|
|
152
167
|
console.log('');
|
|
153
168
|
console.log('devctx metrics report');
|
|
@@ -176,20 +191,9 @@ const printHuman = (report) => {
|
|
|
176
191
|
}
|
|
177
192
|
};
|
|
178
193
|
|
|
179
|
-
const main = () => {
|
|
194
|
+
export const main = () => {
|
|
180
195
|
const options = parseArgs(process.argv.slice(2));
|
|
181
|
-
const
|
|
182
|
-
const { entries, invalidLines } = readEntries(resolved.filePath);
|
|
183
|
-
const filteredEntries = options.tool ? entries.filter((entry) => entry.tool === options.tool) : entries;
|
|
184
|
-
const summary = aggregate(filteredEntries);
|
|
185
|
-
|
|
186
|
-
const report = {
|
|
187
|
-
filePath: resolved.filePath,
|
|
188
|
-
source: resolved.source,
|
|
189
|
-
toolFilter: options.tool,
|
|
190
|
-
invalidLines,
|
|
191
|
-
summary,
|
|
192
|
-
};
|
|
196
|
+
const report = createReport(options);
|
|
193
197
|
|
|
194
198
|
if (options.json) {
|
|
195
199
|
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
package/src/mcp-server.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
process.
|
|
1
|
+
const configuredProjectRoot =
|
|
2
|
+
process.env.DEVCTX_PROJECT_ROOT?.trim() ||
|
|
3
|
+
process.env.MCP_PROJECT_ROOT?.trim();
|
|
4
|
+
|
|
5
|
+
if (configuredProjectRoot) {
|
|
6
|
+
process.chdir(configuredProjectRoot);
|
|
4
7
|
}
|
|
5
8
|
|
|
6
9
|
import { runDevctxServer } from './server.js';
|
|
@@ -14,10 +14,22 @@ const readArgValue = (name) => {
|
|
|
14
14
|
return process.argv[index + 1] ?? null;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
+
const readEnvValue = (...names) => {
|
|
18
|
+
for (const name of names) {
|
|
19
|
+
const value = process.env[name]?.trim();
|
|
20
|
+
|
|
21
|
+
if (value) {
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return null;
|
|
27
|
+
};
|
|
28
|
+
|
|
17
29
|
const defaultDevctxRoot = path.resolve(currentDir, '..', '..');
|
|
18
30
|
const defaultProjectRoot = path.resolve(defaultDevctxRoot, '..', '..');
|
|
19
31
|
const projectRootArg = readArgValue('--project-root');
|
|
20
|
-
const projectRootEnv =
|
|
32
|
+
const projectRootEnv = readEnvValue('DEVCTX_PROJECT_ROOT', 'MCP_PROJECT_ROOT');
|
|
21
33
|
const rawProjectRoot = projectRootArg ?? projectRootEnv ?? defaultProjectRoot;
|
|
22
34
|
|
|
23
35
|
export const devctxRoot = defaultDevctxRoot;
|