@chamba/mcp 0.5.2 → 0.6.1
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/dist/main.js +56 -34
- package/package.json +3 -3
package/dist/main.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// src/main.ts
|
|
2
|
+
import { readFileSync } from "fs";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
2
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
5
|
|
|
4
6
|
// src/logging.ts
|
|
@@ -646,14 +648,17 @@ ${shown.map((n) => `- ${n}`).join("\n")}${more}` + (names.length === 0 ? "\n\n\u
|
|
|
646
648
|
// src/tools/workspace-init.ts
|
|
647
649
|
import {
|
|
648
650
|
joinPath as joinPath4,
|
|
651
|
+
ObsidianDetector as ObsidianDetector4,
|
|
649
652
|
renderWorkspaceMarkdown,
|
|
653
|
+
VAULT_OVERVIEW_FILE,
|
|
654
|
+
VaultInitializer,
|
|
650
655
|
WORKSPACE_DIR as WORKSPACE_DIR4,
|
|
651
656
|
WORKSPACE_RELATIVE_PATH,
|
|
652
657
|
WorkspaceScanner as WorkspaceScanner4
|
|
653
658
|
} from "@chamba/core";
|
|
654
659
|
import { z as z12 } from "zod";
|
|
655
660
|
var TOOL_NAME14 = "chamba_workspace_init";
|
|
656
|
-
var DESCRIPTION14 =
|
|
661
|
+
var DESCRIPTION14 = 'Scan the workspace and generate `.chamba/workspace.md` (description, languages, framework, conventions, active projects, folder map). Respects .gitignore/.dockerignore and never reads node_modules or binaries. If the file already exists it is NOT overwritten \u2014 its current contents are returned. When no Obsidian vault is available, it also bootstraps one at the workspace root and seeds a "Workspace overview" note (disable with createVault: false).';
|
|
657
662
|
function registerWorkspaceInit(server, logger, services) {
|
|
658
663
|
server.registerTool(
|
|
659
664
|
TOOL_NAME14,
|
|
@@ -661,47 +666,49 @@ function registerWorkspaceInit(server, logger, services) {
|
|
|
661
666
|
title: "Init workspace",
|
|
662
667
|
description: DESCRIPTION14,
|
|
663
668
|
inputSchema: {
|
|
664
|
-
root: z12.string().optional().describe("Workspace root to scan. Defaults to the directory chamba runs in.")
|
|
669
|
+
root: z12.string().optional().describe("Workspace root to scan. Defaults to the directory chamba runs in."),
|
|
670
|
+
createVault: z12.boolean().optional().describe("Bootstrap an Obsidian vault at the root when none is found (default true).")
|
|
665
671
|
}
|
|
666
672
|
},
|
|
667
|
-
async ({ root }) => {
|
|
673
|
+
async ({ root, createVault }) => {
|
|
668
674
|
const workspaceRoot = root ?? services.cwd;
|
|
669
675
|
const wsPath = joinPath4(workspaceRoot, WORKSPACE_RELATIVE_PATH);
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
676
|
+
const workspace = await new WorkspaceScanner4(services.fs).scan(workspaceRoot);
|
|
677
|
+
const wsExisted = await services.fs.exists(wsPath);
|
|
678
|
+
let markdown;
|
|
679
|
+
if (wsExisted) {
|
|
680
|
+
markdown = await services.fs.readFile(wsPath);
|
|
681
|
+
} else {
|
|
682
|
+
markdown = renderWorkspaceMarkdown(workspace);
|
|
683
|
+
await services.fs.mkdir(joinPath4(workspaceRoot, WORKSPACE_DIR4));
|
|
684
|
+
await services.fs.writeFile(wsPath, markdown);
|
|
685
|
+
}
|
|
686
|
+
const wsLine = wsExisted ? `\`${WORKSPACE_RELATIVE_PATH}\` already exists at ${wsPath}; not overwriting.` : `Created \`${WORKSPACE_RELATIVE_PATH}\` at ${wsPath}.`;
|
|
687
|
+
let vaultLine = "Vault: skipped (createVault: false).";
|
|
688
|
+
if (createVault !== false) {
|
|
689
|
+
const detection = await new ObsidianDetector4(services.fs).detect({
|
|
690
|
+
explicitPath: services.obsidianVaultPath,
|
|
691
|
+
searchRoots: obsidianSearchRoots(services)
|
|
692
|
+
});
|
|
693
|
+
if (detection.found) {
|
|
694
|
+
vaultLine = `Vault: using the existing one at ${detection.path}; left it untouched.`;
|
|
695
|
+
} else {
|
|
696
|
+
const seeded = await new VaultInitializer(services.fs, services.clock).seed({
|
|
697
|
+
vaultPath: workspaceRoot,
|
|
698
|
+
workspace
|
|
699
|
+
});
|
|
700
|
+
vaultLine = `Vault: none found \u2014 created one at the workspace root and seeded \`${VAULT_OVERVIEW_FILE}\`. Add \`.obsidian/\` to .gitignore if you don't want it committed.`;
|
|
701
|
+
logger.info({ tool: TOOL_NAME14, vault: seeded.vaultPath }, "vault bootstrapped");
|
|
702
|
+
}
|
|
685
703
|
}
|
|
686
|
-
const scanner = new WorkspaceScanner4(services.fs);
|
|
687
|
-
const workspace = await scanner.scan(workspaceRoot);
|
|
688
|
-
const markdown = renderWorkspaceMarkdown(workspace);
|
|
689
|
-
await services.fs.mkdir(joinPath4(workspaceRoot, WORKSPACE_DIR4));
|
|
690
|
-
await services.fs.writeFile(wsPath, markdown);
|
|
691
704
|
logger.info(
|
|
692
|
-
{ tool: TOOL_NAME14, wsPath, projects: workspace.projects.length },
|
|
693
|
-
"workspace
|
|
705
|
+
{ tool: TOOL_NAME14, wsPath, wsExisted, projects: workspace.projects.length },
|
|
706
|
+
"workspace init"
|
|
694
707
|
);
|
|
695
|
-
return {
|
|
696
|
-
|
|
697
|
-
{
|
|
698
|
-
type: "text",
|
|
699
|
-
text: `Created \`${WORKSPACE_RELATIVE_PATH}\` at ${wsPath}.
|
|
708
|
+
return { content: [{ type: "text", text: `${wsLine}
|
|
709
|
+
${vaultLine}
|
|
700
710
|
|
|
701
|
-
${markdown}`
|
|
702
|
-
}
|
|
703
|
-
]
|
|
704
|
-
};
|
|
711
|
+
${markdown}` }] };
|
|
705
712
|
}
|
|
706
713
|
);
|
|
707
714
|
}
|
|
@@ -827,7 +834,22 @@ function createServer(logger, services = createNodeServices()) {
|
|
|
827
834
|
}
|
|
828
835
|
|
|
829
836
|
// src/main.ts
|
|
837
|
+
function readPackageVersion() {
|
|
838
|
+
try {
|
|
839
|
+
const pkgPath = fileURLToPath(new URL("../package.json", import.meta.url));
|
|
840
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
841
|
+
return pkg.version ?? "unknown";
|
|
842
|
+
} catch {
|
|
843
|
+
return "unknown";
|
|
844
|
+
}
|
|
845
|
+
}
|
|
830
846
|
async function main() {
|
|
847
|
+
const flag = process.argv[2];
|
|
848
|
+
if (flag === "--version" || flag === "-v") {
|
|
849
|
+
process.stdout.write(`${readPackageVersion()}
|
|
850
|
+
`);
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
831
853
|
const logger = createLogger();
|
|
832
854
|
const server = createServer(logger);
|
|
833
855
|
const transport = new StdioServerTransport();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chamba/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "chamba MCP server — orchestration, workspace, worktree and Obsidian tools for any MCP-capable editor",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
37
37
|
"pino": "^9.0.0",
|
|
38
38
|
"zod": "^3.23.0",
|
|
39
|
-
"@chamba/
|
|
40
|
-
"@chamba/
|
|
39
|
+
"@chamba/core": "0.6.1",
|
|
40
|
+
"@chamba/adapters": "0.6.1"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "^22.0.0",
|