@ebowwa/claude-code-config-mcp 1.0.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.
@@ -0,0 +1,146 @@
1
+ // ============================================================================
2
+ // Atomic File Operations - Safe config file writes with backup support
3
+ // ============================================================================
4
+ import { writeFile, rename, unlink, readFile, mkdir, mkdtemp } from 'node:fs/promises';
5
+ import { existsSync, constants } from 'node:fs';
6
+ import { join, dirname } from 'node:path';
7
+ import { tmpdir } from 'node:os';
8
+ import { randomBytes } from 'node:crypto';
9
+ /**
10
+ * Atomic write implementation
11
+ * Writes to a temporary file, then renames over the target
12
+ * This is safe against crashes and concurrent access
13
+ */
14
+ export async function atomicWrite(filePath, content, options = {}) {
15
+ const { createBackup = true, backupDir, encoding = 'utf8', } = options;
16
+ // Create parent directory if it doesn't exist
17
+ const parentDir = dirname(filePath);
18
+ await mkdir(parentDir, { recursive: true });
19
+ // Create backup if requested and file exists
20
+ if (createBackup && existsSync(filePath)) {
21
+ await createBackupFile(filePath, backupDir);
22
+ }
23
+ // Create temp file in OS temp directory (same filesystem for atomic rename)
24
+ const tempDir = await mkdtemp(join(getTempDir(), 'mcp-atomic-'));
25
+ const tempFileName = `${randomBytes(16).toString('hex')}.tmp`;
26
+ const tempFilePath = join(tempDir, tempFileName);
27
+ try {
28
+ // Write to temp file
29
+ await writeFile(tempFilePath, content, { encoding, mode: 0o644 });
30
+ // Atomic rename (overwrites target if exists)
31
+ await rename(tempFilePath, filePath);
32
+ }
33
+ catch (error) {
34
+ // Clean up temp file if rename failed
35
+ try {
36
+ await unlink(tempFilePath);
37
+ }
38
+ catch {
39
+ // Ignore cleanup errors
40
+ }
41
+ throw error;
42
+ }
43
+ finally {
44
+ // Clean up temp directory
45
+ try {
46
+ await unlink(tempDir).catch(() => { });
47
+ }
48
+ catch {
49
+ // Ignore cleanup errors
50
+ }
51
+ }
52
+ }
53
+ /**
54
+ * Create a backup of a file
55
+ */
56
+ async function createBackupFile(filePath, backupDir) {
57
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
58
+ const backupFileName = `${basename(filePath)}.backup.${timestamp}`;
59
+ const backupPath = backupDir
60
+ ? join(backupDir, backupFileName)
61
+ : `${filePath}.backup`;
62
+ // Ensure backup directory exists
63
+ const backupDirPath = dirname(backupPath);
64
+ await mkdir(backupDirPath, { recursive: true });
65
+ // Copy file to backup location
66
+ const content = await readFile(filePath);
67
+ await writeFile(backupPath, content);
68
+ return backupPath;
69
+ }
70
+ /**
71
+ * Get temp directory
72
+ */
73
+ function getTempDir() {
74
+ return tmpdir();
75
+ }
76
+ /**
77
+ * Get file basename without extension
78
+ */
79
+ function basename(filePath) {
80
+ return filePath.split('/').pop() || filePath;
81
+ }
82
+ /**
83
+ * Safe file read with encoding detection
84
+ */
85
+ export async function safeReadFile(filePath, encoding = 'utf8') {
86
+ try {
87
+ const content = await readFile(filePath, { encoding });
88
+ // Remove BOM if present
89
+ if (content.charCodeAt(0) === 0xFEFF) {
90
+ return content.slice(1);
91
+ }
92
+ return content;
93
+ }
94
+ catch (error) {
95
+ throw new Error(`Failed to read file ${filePath}: ${error.message}`);
96
+ }
97
+ }
98
+ /**
99
+ * Check if file is writable
100
+ */
101
+ export async function isFileWritable(filePath) {
102
+ try {
103
+ await writeFile(filePath, '', { flag: constants.O_WRONLY | constants.O_CREAT });
104
+ await unlink(filePath);
105
+ return true;
106
+ }
107
+ catch {
108
+ return false;
109
+ }
110
+ }
111
+ /**
112
+ * Normalize line endings to LF
113
+ */
114
+ export function normalizeLineEndings(content) {
115
+ return content.replace(/\r\n/g, '\n');
116
+ }
117
+ /**
118
+ * Detect and strip BOM
119
+ */
120
+ export function stripBOM(content) {
121
+ if (content.charCodeAt(0) === 0xFEFF) {
122
+ return content.slice(1);
123
+ }
124
+ return content;
125
+ }
126
+ /**
127
+ * Format JSON with proper indentation
128
+ */
129
+ export function formatJSON(obj, indent = 2) {
130
+ return JSON.stringify(obj, null, indent) + '\n';
131
+ }
132
+ /**
133
+ * Parse JSON with error reporting
134
+ */
135
+ export function safeJSONParse(content, filePath) {
136
+ try {
137
+ return JSON.parse(content);
138
+ }
139
+ catch (error) {
140
+ const message = error.message;
141
+ const match = message.match(/position (\d+)/);
142
+ const position = match ? match[1] : 'unknown';
143
+ throw new Error(`Invalid JSON in ${filePath} at position ${position}: ${message}`);
144
+ }
145
+ }
146
+ //# sourceMappingURL=file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/utils/file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Get home directory cross-platform
3
+ */
4
+ export declare function getHomeDir(): string;
5
+ /**
6
+ * Get Claude Code global config directory (~/.claude)
7
+ */
8
+ export declare function getClaudeConfigDir(): string;
9
+ /**
10
+ * Get Claude Code app config directory (~/.config/claude-code)
11
+ * This is where MCP servers are configured for the Claude Code app
12
+ */
13
+ export declare function getClaudeAppConfigDir(): string;
14
+ /**
15
+ * Get Claude CLI config file path (~/.claude.json)
16
+ * This is where MCP servers are configured for the claude CLI
17
+ */
18
+ export declare function getClaudeCliConfigPath(): string;
19
+ /**
20
+ * Get project-local Claude Code config directory (.claude)
21
+ */
22
+ export declare function getProjectClaudeDir(cwd?: string): string;
23
+ /**
24
+ * Resolve Claude config file paths
25
+ */
26
+ export declare function getConfigPaths(cwd?: string): {
27
+ globalClaudeMd: string;
28
+ keybindings: string;
29
+ settings: string;
30
+ claudeJson: string;
31
+ mcpServers: string;
32
+ hooksDir: string;
33
+ pluginsDir: string;
34
+ appConfig: string;
35
+ projectClaudeMd: string;
36
+ };
37
+ /**
38
+ * Validate and sanitize a file path
39
+ * Prevents path traversal attacks and ensures path is within allowed directories
40
+ */
41
+ export declare function validatePath(userPath: string, cwd?: string): string;
42
+ /**
43
+ * Check if a path exists
44
+ */
45
+ export declare function pathExists(filePath: string): boolean;
46
+ /**
47
+ * Get relative path from home directory for display
48
+ */
49
+ export declare function getDisplayPath(filePath: string): string;
50
+ /**
51
+ * Get MCP config file paths based on target
52
+ * @param target - Which config(s) to get ('cli', 'app', or 'both')
53
+ * @returns Object with the requested config paths
54
+ */
55
+ export declare function getMCPConfigPaths(target?: 'cli' | 'app' | 'both'): {
56
+ cli?: string;
57
+ app?: string;
58
+ };
59
+ //# sourceMappingURL=path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAEvE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAsB;;;;;;;;;;EAqBzD;AAYD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,MAAM,CA4ClF;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAMpD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,KAAK,GAAG,KAAK,GAAG,MAAe,GAAG;IAC1E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAWA"}
@@ -0,0 +1,146 @@
1
+ // ============================================================================
2
+ // Path Utilities - Cross-platform path handling for Claude Code config
3
+ // ============================================================================
4
+ import { resolve, normalize, isAbsolute, join, dirname } from 'node:path';
5
+ import { homedir } from 'node:os';
6
+ import { existsSync } from 'node:fs';
7
+ /**
8
+ * Get home directory cross-platform
9
+ */
10
+ export function getHomeDir() {
11
+ return homedir();
12
+ }
13
+ /**
14
+ * Get Claude Code global config directory (~/.claude)
15
+ */
16
+ export function getClaudeConfigDir() {
17
+ return join(getHomeDir(), '.claude');
18
+ }
19
+ /**
20
+ * Get Claude Code app config directory (~/.config/claude-code)
21
+ * This is where MCP servers are configured for the Claude Code app
22
+ */
23
+ export function getClaudeAppConfigDir() {
24
+ return join(getHomeDir(), '.config', 'claude-code');
25
+ }
26
+ /**
27
+ * Get Claude CLI config file path (~/.claude.json)
28
+ * This is where MCP servers are configured for the claude CLI
29
+ */
30
+ export function getClaudeCliConfigPath() {
31
+ return join(getHomeDir(), '.claude.json');
32
+ }
33
+ /**
34
+ * Get project-local Claude Code config directory (.claude)
35
+ */
36
+ export function getProjectClaudeDir(cwd = process.cwd()) {
37
+ return join(cwd, '.claude');
38
+ }
39
+ /**
40
+ * Resolve Claude config file paths
41
+ */
42
+ export function getConfigPaths(cwd = process.cwd()) {
43
+ const claudeDir = getClaudeConfigDir();
44
+ const claudeAppDir = getClaudeAppConfigDir();
45
+ const projectClaudeDir = getProjectClaudeDir(cwd);
46
+ return {
47
+ // Global config files
48
+ globalClaudeMd: join(claudeDir, 'CLAUDE.md'),
49
+ keybindings: join(claudeDir, 'keybindings.json'),
50
+ settings: join(claudeDir, 'settings.json'),
51
+ claudeJson: join(claudeDir, 'claude.json'),
52
+ mcpServers: join(claudeDir, 'mcp_servers.json'),
53
+ hooksDir: join(claudeDir, 'hooks'),
54
+ pluginsDir: join(claudeDir, 'plugins'),
55
+ // App config file (where MCP servers are actually configured)
56
+ appConfig: join(claudeAppDir, 'config.json'),
57
+ // Project-local config files
58
+ projectClaudeMd: join(projectClaudeDir, 'CLAUDE.md'),
59
+ };
60
+ }
61
+ /**
62
+ * Allowed base paths for security (whitelist)
63
+ */
64
+ const ALLOWED_BASES = [
65
+ getClaudeConfigDir(),
66
+ getProjectClaudeDir(),
67
+ getClaudeAppConfigDir(),
68
+ getClaudeCliConfigPath(),
69
+ ];
70
+ /**
71
+ * Validate and sanitize a file path
72
+ * Prevents path traversal attacks and ensures path is within allowed directories
73
+ */
74
+ export function validatePath(userPath, cwd = process.cwd()) {
75
+ // Normalize path
76
+ const normalized = normalize(userPath.replace(/\0/g, ''));
77
+ // Resolve to absolute path
78
+ const absolute = isAbsolute(normalized)
79
+ ? resolve(normalized)
80
+ : resolve(cwd, normalized);
81
+ // Check for path traversal attempts
82
+ if (normalized.includes('..')) {
83
+ throw new Error('Path traversal detected');
84
+ }
85
+ // Build allowed bases including the current project directory
86
+ const allowedBases = [
87
+ ...ALLOWED_BASES,
88
+ getClaudeConfigDir(),
89
+ getProjectClaudeDir(cwd),
90
+ ];
91
+ // Check if path is within allowed bases
92
+ // For files that don't exist yet, check the parent directory
93
+ let checkPath = absolute;
94
+ while (checkPath !== '/' && checkPath !== cwd && checkPath !== getHomeDir()) {
95
+ const isAllowed = allowedBases.some(base => {
96
+ const resolvedBase = resolve(base);
97
+ return (checkPath === resolvedBase ||
98
+ checkPath.startsWith(resolvedBase + '/') ||
99
+ resolvedBase.startsWith(checkPath + '/'));
100
+ });
101
+ if (isAllowed) {
102
+ return absolute;
103
+ }
104
+ // Move up one directory to check
105
+ checkPath = dirname(checkPath);
106
+ }
107
+ // If we get here, the path is not allowed
108
+ throw new Error(`Path not allowed: ${userPath}`);
109
+ }
110
+ /**
111
+ * Check if a path exists
112
+ */
113
+ export function pathExists(filePath) {
114
+ try {
115
+ return existsSync(filePath);
116
+ }
117
+ catch {
118
+ return false;
119
+ }
120
+ }
121
+ /**
122
+ * Get relative path from home directory for display
123
+ */
124
+ export function getDisplayPath(filePath) {
125
+ const home = getHomeDir();
126
+ if (filePath.startsWith(home)) {
127
+ return filePath.replace(home, '~');
128
+ }
129
+ return filePath;
130
+ }
131
+ /**
132
+ * Get MCP config file paths based on target
133
+ * @param target - Which config(s) to get ('cli', 'app', or 'both')
134
+ * @returns Object with the requested config paths
135
+ */
136
+ export function getMCPConfigPaths(target = 'both') {
137
+ const result = {};
138
+ if (target === 'cli' || target === 'both') {
139
+ result.cli = getClaudeCliConfigPath();
140
+ }
141
+ if (target === 'app' || target === 'both') {
142
+ result.app = getConfigPaths().appConfig;
143
+ }
144
+ return result;
145
+ }
146
+ //# sourceMappingURL=path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"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"}
package/lmdb.db ADDED
Binary file
package/lmdb.db-lock ADDED
Binary file
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@ebowwa/claude-code-config-mcp",
3
+ "version": "1.0.0",
4
+ "description": "Claude Code Config MCP server - Manage Claude Code configuration files (CLAUDE.md, keybindings.json, settings.json, hooks)",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "mcp-claude-code-config": "./dist/index.js"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "dev": "bun run --watch src/index.ts",
14
+ "start": "node dist/index.js",
15
+ "test": "bun test",
16
+ "lint": "eslint src/**/*.ts"
17
+ },
18
+ "dependencies": {
19
+ "@modelcontextprotocol/sdk": "^1.0.0",
20
+ "zod": "^4.3.5"
21
+ },
22
+ "devDependencies": {
23
+ "@types/node": "^20.0.0",
24
+ "typescript": "^5.0.0"
25
+ },
26
+ "engines": {
27
+ "node": ">=20.0.0",
28
+ "bun": ">=1.0.0"
29
+ },
30
+ "keywords": [
31
+ "mcp",
32
+ "claude-code",
33
+ "config",
34
+ "configuration",
35
+ "settings",
36
+ "keybindings",
37
+ "claude-md",
38
+ "hooks",
39
+ "file-management"
40
+ ],
41
+ "author": "ebowwa",
42
+ "license": "MIT"
43
+ }