@mcptoolshop/file-forge 0.1.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.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -0
  3. package/build/config/index.d.ts +29 -0
  4. package/build/config/index.d.ts.map +1 -0
  5. package/build/config/index.js +229 -0
  6. package/build/config/index.js.map +1 -0
  7. package/build/index.d.ts +9 -0
  8. package/build/index.d.ts.map +1 -0
  9. package/build/index.js +23 -0
  10. package/build/index.js.map +1 -0
  11. package/build/security/index.d.ts +8 -0
  12. package/build/security/index.d.ts.map +1 -0
  13. package/build/security/index.js +8 -0
  14. package/build/security/index.js.map +1 -0
  15. package/build/security/read-only.d.ts +32 -0
  16. package/build/security/read-only.d.ts.map +1 -0
  17. package/build/security/read-only.js +62 -0
  18. package/build/security/read-only.js.map +1 -0
  19. package/build/security/sandbox.d.ts +60 -0
  20. package/build/security/sandbox.d.ts.map +1 -0
  21. package/build/security/sandbox.js +231 -0
  22. package/build/security/sandbox.js.map +1 -0
  23. package/build/server.d.ts +20 -0
  24. package/build/server.d.ts.map +1 -0
  25. package/build/server.js +63 -0
  26. package/build/server.js.map +1 -0
  27. package/build/tools/metadata.d.ts +11 -0
  28. package/build/tools/metadata.d.ts.map +1 -0
  29. package/build/tools/metadata.js +423 -0
  30. package/build/tools/metadata.js.map +1 -0
  31. package/build/tools/read.d.ts +11 -0
  32. package/build/tools/read.d.ts.map +1 -0
  33. package/build/tools/read.js +335 -0
  34. package/build/tools/read.js.map +1 -0
  35. package/build/tools/scaffold.d.ts +11 -0
  36. package/build/tools/scaffold.d.ts.map +1 -0
  37. package/build/tools/scaffold.js +345 -0
  38. package/build/tools/scaffold.js.map +1 -0
  39. package/build/tools/search.d.ts +11 -0
  40. package/build/tools/search.d.ts.map +1 -0
  41. package/build/tools/search.js +250 -0
  42. package/build/tools/search.js.map +1 -0
  43. package/build/tools/write.d.ts +11 -0
  44. package/build/tools/write.d.ts.map +1 -0
  45. package/build/tools/write.js +538 -0
  46. package/build/tools/write.js.map +1 -0
  47. package/build/types.d.ts +402 -0
  48. package/build/types.d.ts.map +1 -0
  49. package/build/types.js +146 -0
  50. package/build/types.js.map +1 -0
  51. package/build/utils/errors.d.ts +43 -0
  52. package/build/utils/errors.d.ts.map +1 -0
  53. package/build/utils/errors.js +125 -0
  54. package/build/utils/errors.js.map +1 -0
  55. package/build/utils/index.d.ts +10 -0
  56. package/build/utils/index.d.ts.map +1 -0
  57. package/build/utils/index.js +9 -0
  58. package/build/utils/index.js.map +1 -0
  59. package/build/utils/logger.d.ts +88 -0
  60. package/build/utils/logger.d.ts.map +1 -0
  61. package/build/utils/logger.js +166 -0
  62. package/build/utils/logger.js.map +1 -0
  63. package/build/utils/validation.d.ts +43 -0
  64. package/build/utils/validation.d.ts.map +1 -0
  65. package/build/utils/validation.js +196 -0
  66. package/build/utils/validation.js.map +1 -0
  67. package/package.json +64 -0
  68. package/templates/typescript-starter/package.json +18 -0
  69. package/templates/typescript-starter/src/index.ts +9 -0
  70. package/templates/typescript-starter/template.json +24 -0
  71. package/templates/typescript-starter/tsconfig.json +14 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 mcp-tool-shop
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,125 @@
1
+ # MCP File Forge
2
+
3
+ A Model Context Protocol (MCP) server for secure file operations and project scaffolding.
4
+
5
+ ## Features
6
+
7
+ - **Secure File Operations**: Read, write, copy, move, and delete files with sandboxed access controls
8
+ - **Project Scaffolding**: Create projects from templates with variable substitution
9
+ - **Windows-First**: Optimized for Windows paths, permissions, and conventions
10
+ - **Search Capabilities**: Glob patterns and regex content search
11
+ - **Configurable Security**: Define allowed paths, size limits, and read-only modes
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @mcp-tool-shop/file-forge
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ### With Claude Desktop
22
+
23
+ Add to your `claude_desktop_config.json`:
24
+
25
+ ```json
26
+ {
27
+ "mcpServers": {
28
+ "file-forge": {
29
+ "command": "node",
30
+ "args": ["path/to/mcp-file-forge/build/index.js"],
31
+ "env": {
32
+ "MCP_FILE_FORGE_ALLOWED_PATHS": "C:/Projects,C:/Users/you/Documents"
33
+ }
34
+ }
35
+ }
36
+ }
37
+ ```
38
+
39
+ ### Standalone
40
+
41
+ ```bash
42
+ npx @mcp-tool-shop/file-forge
43
+ ```
44
+
45
+ ## Available Tools
46
+
47
+ ### File Reading
48
+ - `read_file` - Read file contents with encoding and line range options
49
+ - `read_directory` - List directory contents with metadata
50
+ - `read_multiple` - Batch read multiple files
51
+
52
+ ### File Writing
53
+ - `write_file` - Write or overwrite file contents
54
+ - `create_directory` - Create directories
55
+ - `copy_file` - Copy files or directories
56
+ - `move_file` - Move or rename files
57
+ - `delete_file` - Delete files or directories
58
+
59
+ ### Search
60
+ - `glob_search` - Find files matching glob patterns
61
+ - `grep_search` - Search file contents with regex
62
+
63
+ ### Metadata
64
+ - `file_stat` - Get file statistics
65
+ - `file_exists` - Check if path exists
66
+
67
+ ### Scaffolding
68
+ - `scaffold_project` - Create project from template
69
+ - `list_templates` - List available templates
70
+
71
+ ## Configuration
72
+
73
+ ### Environment Variables
74
+
75
+ | Variable | Description | Default |
76
+ |----------|-------------|---------|
77
+ | `MCP_FILE_FORGE_ALLOWED_PATHS` | Comma-separated allowed paths | `.` |
78
+ | `MCP_FILE_FORGE_READ_ONLY` | Disable write operations | `false` |
79
+ | `MCP_FILE_FORGE_MAX_FILE_SIZE` | Max file size in bytes | `104857600` |
80
+ | `MCP_FILE_FORGE_LOG_LEVEL` | Logging level | `info` |
81
+
82
+ ### Config File
83
+
84
+ Create `mcp-file-forge.json` in the working directory:
85
+
86
+ ```json
87
+ {
88
+ "sandbox": {
89
+ "allowed_paths": ["./projects"],
90
+ "denied_paths": ["**/secrets/**"],
91
+ "max_file_size": 52428800
92
+ }
93
+ }
94
+ ```
95
+
96
+ ## Security
97
+
98
+ - Path sandboxing restricts operations to allowed directories
99
+ - Symlink following is disabled by default
100
+ - Read-only mode available for safe browsing
101
+ - Size limits prevent memory exhaustion
102
+
103
+ ## Development
104
+
105
+ ```bash
106
+ # Install dependencies
107
+ npm install
108
+
109
+ # Build
110
+ npm run build
111
+
112
+ # Development mode (watch)
113
+ npm run dev
114
+
115
+ # Run tests
116
+ npm test
117
+ ```
118
+
119
+ ## License
120
+
121
+ MIT
122
+
123
+ ## Author
124
+
125
+ mcp-tool-shop
@@ -0,0 +1,29 @@
1
+ /**
2
+ * MCP File Forge - Configuration Module
3
+ *
4
+ * Handles loading and merging configuration from multiple sources.
5
+ */
6
+ import type { ServerConfig } from '../types.js';
7
+ /**
8
+ * Load and merge configuration from all sources.
9
+ *
10
+ * Priority (highest to lowest):
11
+ * 1. CLI arguments (not implemented yet)
12
+ * 2. Environment variables
13
+ * 3. Config file
14
+ * 4. Built-in defaults
15
+ */
16
+ export declare function loadConfig(): Promise<ServerConfig>;
17
+ /**
18
+ * Get the current configuration.
19
+ */
20
+ export declare function getConfig(): ServerConfig;
21
+ /**
22
+ * Reset configuration (useful for testing).
23
+ */
24
+ export declare function resetConfig(): void;
25
+ /**
26
+ * Get default configuration.
27
+ */
28
+ export declare function getDefaultConfig(): ServerConfig;
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,YAAY,EAA4C,MAAM,aAAa,CAAC;AA4L1F;;;;;;;;GAQG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,YAAY,CAAC,CA+BxD;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,YAAY,CAKxC;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,CAE/C"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * MCP File Forge - Configuration Module
3
+ *
4
+ * Handles loading and merging configuration from multiple sources.
5
+ */
6
+ import * as fs from 'node:fs/promises';
7
+ import * as path from 'node:path';
8
+ import { ServerConfigSchema } from '../types.js';
9
+ /**
10
+ * Default configuration values.
11
+ */
12
+ const DEFAULT_CONFIG = {
13
+ sandbox: {
14
+ allowed_paths: ['.'],
15
+ denied_paths: ['**/node_modules/**', '**/.git/**'],
16
+ follow_symlinks: false,
17
+ max_file_size: 104857600, // 100MB
18
+ max_depth: 20,
19
+ },
20
+ templates: {
21
+ paths: ['./templates'],
22
+ },
23
+ logging: {
24
+ level: 'info',
25
+ },
26
+ read_only: false,
27
+ };
28
+ /**
29
+ * Environment variable prefix.
30
+ */
31
+ const ENV_PREFIX = 'MCP_FILE_FORGE_';
32
+ /**
33
+ * Parse a comma-separated string into an array.
34
+ */
35
+ function parseCSV(value) {
36
+ return value
37
+ .split(',')
38
+ .map((s) => s.trim())
39
+ .filter((s) => s.length > 0);
40
+ }
41
+ /**
42
+ * Parse environment variables into partial config.
43
+ */
44
+ function parseEnvironment() {
45
+ const config = {};
46
+ const sandbox = {};
47
+ const templates = {};
48
+ const logging = {};
49
+ // Read-only mode
50
+ const readOnly = process.env[`${ENV_PREFIX}READ_ONLY`];
51
+ if (readOnly !== undefined) {
52
+ config.read_only = readOnly.toLowerCase() === 'true';
53
+ }
54
+ // Sandbox settings
55
+ const allowedPaths = process.env[`${ENV_PREFIX}ALLOWED_PATHS`];
56
+ if (allowedPaths) {
57
+ sandbox.allowed_paths = parseCSV(allowedPaths);
58
+ }
59
+ const deniedPaths = process.env[`${ENV_PREFIX}DENIED_PATHS`];
60
+ if (deniedPaths) {
61
+ sandbox.denied_paths = parseCSV(deniedPaths);
62
+ }
63
+ const followSymlinks = process.env[`${ENV_PREFIX}FOLLOW_SYMLINKS`];
64
+ if (followSymlinks !== undefined) {
65
+ sandbox.follow_symlinks = followSymlinks.toLowerCase() === 'true';
66
+ }
67
+ const maxFileSize = process.env[`${ENV_PREFIX}MAX_FILE_SIZE`];
68
+ if (maxFileSize) {
69
+ const parsed = parseInt(maxFileSize, 10);
70
+ if (!isNaN(parsed)) {
71
+ sandbox.max_file_size = parsed;
72
+ }
73
+ }
74
+ const maxDepth = process.env[`${ENV_PREFIX}MAX_DEPTH`];
75
+ if (maxDepth) {
76
+ const parsed = parseInt(maxDepth, 10);
77
+ if (!isNaN(parsed)) {
78
+ sandbox.max_depth = parsed;
79
+ }
80
+ }
81
+ // Template settings
82
+ const templatePaths = process.env[`${ENV_PREFIX}TEMPLATE_PATHS`];
83
+ if (templatePaths) {
84
+ templates.paths = parseCSV(templatePaths);
85
+ }
86
+ // Logging settings
87
+ const logLevel = process.env[`${ENV_PREFIX}LOG_LEVEL`];
88
+ if (logLevel) {
89
+ const level = logLevel.toLowerCase();
90
+ if (['error', 'warn', 'info', 'debug'].includes(level)) {
91
+ logging.level = level;
92
+ }
93
+ }
94
+ const logFile = process.env[`${ENV_PREFIX}LOG_FILE`];
95
+ if (logFile) {
96
+ logging.file = logFile;
97
+ }
98
+ // Merge partial configs
99
+ if (Object.keys(sandbox).length > 0) {
100
+ config.sandbox = sandbox;
101
+ }
102
+ if (Object.keys(templates).length > 0) {
103
+ config.templates = templates;
104
+ }
105
+ if (Object.keys(logging).length > 0) {
106
+ config.logging = logging;
107
+ }
108
+ return config;
109
+ }
110
+ /**
111
+ * Load configuration from a JSON file.
112
+ */
113
+ async function loadConfigFile(configPath) {
114
+ try {
115
+ const content = await fs.readFile(configPath, 'utf-8');
116
+ return JSON.parse(content);
117
+ }
118
+ catch {
119
+ // Config file doesn't exist or is invalid
120
+ return {};
121
+ }
122
+ }
123
+ /**
124
+ * Deep merge two configuration objects.
125
+ */
126
+ function mergeConfig(base, override) {
127
+ return {
128
+ sandbox: {
129
+ ...base.sandbox,
130
+ ...override.sandbox,
131
+ },
132
+ templates: {
133
+ ...base.templates,
134
+ ...override.templates,
135
+ },
136
+ logging: {
137
+ ...base.logging,
138
+ ...override.logging,
139
+ },
140
+ read_only: override.read_only ?? base.read_only,
141
+ };
142
+ }
143
+ /**
144
+ * Find config file in current directory or parent directories.
145
+ */
146
+ async function findConfigFile() {
147
+ const configNames = ['mcp-file-forge.json', '.mcp-file-forge.json'];
148
+ let currentDir = process.cwd();
149
+ // Search up to 5 levels
150
+ for (let i = 0; i < 5; i++) {
151
+ for (const name of configNames) {
152
+ const configPath = path.join(currentDir, name);
153
+ try {
154
+ await fs.access(configPath);
155
+ return configPath;
156
+ }
157
+ catch {
158
+ // File doesn't exist, continue
159
+ }
160
+ }
161
+ const parentDir = path.dirname(currentDir);
162
+ if (parentDir === currentDir)
163
+ break;
164
+ currentDir = parentDir;
165
+ }
166
+ return null;
167
+ }
168
+ /**
169
+ * Global configuration instance.
170
+ */
171
+ let globalConfig = null;
172
+ /**
173
+ * Load and merge configuration from all sources.
174
+ *
175
+ * Priority (highest to lowest):
176
+ * 1. CLI arguments (not implemented yet)
177
+ * 2. Environment variables
178
+ * 3. Config file
179
+ * 4. Built-in defaults
180
+ */
181
+ export async function loadConfig() {
182
+ if (globalConfig) {
183
+ return globalConfig;
184
+ }
185
+ // Start with defaults
186
+ let config = { ...DEFAULT_CONFIG };
187
+ // Load config file if found
188
+ const configPath = await findConfigFile();
189
+ if (configPath) {
190
+ const fileConfig = await loadConfigFile(configPath);
191
+ config = mergeConfig(config, fileConfig);
192
+ console.error(`[config] Loaded config from ${configPath}`);
193
+ }
194
+ // Apply environment variables (higher priority)
195
+ const envConfig = parseEnvironment();
196
+ config = mergeConfig(config, envConfig);
197
+ // Validate the final config
198
+ const result = ServerConfigSchema.safeParse(config);
199
+ if (!result.success) {
200
+ console.error('[config] Warning: Invalid configuration, using defaults');
201
+ console.error(result.error.issues);
202
+ globalConfig = DEFAULT_CONFIG;
203
+ return DEFAULT_CONFIG;
204
+ }
205
+ globalConfig = result.data;
206
+ return result.data;
207
+ }
208
+ /**
209
+ * Get the current configuration.
210
+ */
211
+ export function getConfig() {
212
+ if (!globalConfig) {
213
+ throw new Error('Configuration not loaded. Call loadConfig() first.');
214
+ }
215
+ return globalConfig;
216
+ }
217
+ /**
218
+ * Reset configuration (useful for testing).
219
+ */
220
+ export function resetConfig() {
221
+ globalConfig = null;
222
+ }
223
+ /**
224
+ * Get default configuration.
225
+ */
226
+ export function getDefaultConfig() {
227
+ return { ...DEFAULT_CONFIG };
228
+ }
229
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD;;GAEG;AACH,MAAM,cAAc,GAAiB;IACnC,OAAO,EAAE;QACP,aAAa,EAAE,CAAC,GAAG,CAAC;QACpB,YAAY,EAAE,CAAC,oBAAoB,EAAE,YAAY,CAAC;QAClD,eAAe,EAAE,KAAK;QACtB,aAAa,EAAE,SAAS,EAAE,QAAQ;QAClC,SAAS,EAAE,EAAE;KACd;IACD,SAAS,EAAE;QACT,KAAK,EAAE,CAAC,aAAa,CAAC;KACvB;IACD,OAAO,EAAE;QACP,KAAK,EAAE,MAAM;KACd;IACD,SAAS,EAAE,KAAK;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,GAAG,iBAAiB,CAAC;AAErC;;GAEG;AACH,SAAS,QAAQ,CAAC,KAAa;IAC7B,OAAO,KAAK;SACT,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB;IACvB,MAAM,MAAM,GAA0B,EAAE,CAAC;IACzC,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,MAAM,SAAS,GAA4B,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAuB,EAAE,CAAC;IAEvC,iBAAiB;IACjB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,WAAW,CAAC,CAAC;IACvD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC;IACvD,CAAC;IAED,mBAAmB;IACnB,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,eAAe,CAAC,CAAC;IAC/D,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,CAAC,aAAa,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,cAAc,CAAC,CAAC;IAC7D,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,YAAY,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,iBAAiB,CAAC,CAAC;IACnE,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,CAAC,eAAe,GAAG,cAAc,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC;IACpE,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,eAAe,CAAC,CAAC;IAC9D,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YACnB,OAAO,CAAC,aAAa,GAAG,MAAM,CAAC;QACjC,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,WAAW,CAAC,CAAC;IACvD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YACnB,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,gBAAgB,CAAC,CAAC;IACjE,IAAI,aAAa,EAAE,CAAC;QAClB,SAAS,CAAC,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC5C,CAAC;IAED,mBAAmB;IACnB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,WAAW,CAAC,CAAC;IACvD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACvD,OAAO,CAAC,KAAK,GAAG,KAA4C,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,UAAU,CAAC,CAAC;IACrD,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,wBAAwB;IACxB,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,MAAM,CAAC,OAAO,GAAG,OAAwB,CAAC;IAC5C,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtC,MAAM,CAAC,SAAS,GAAG,SAA2B,CAAC;IACjD,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,MAAM,CAAC,OAAO,GAAG,OAAoB,CAAC;IACxC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,cAAc,CAAC,UAAkB;IAC9C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAA0B,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,0CAA0C;QAC1C,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAClB,IAAkB,EAClB,QAA+B;IAE/B,OAAO;QACL,OAAO,EAAE;YACP,GAAG,IAAI,CAAC,OAAO;YACf,GAAG,QAAQ,CAAC,OAAO;SACpB;QACD,SAAS,EAAE;YACT,GAAG,IAAI,CAAC,SAAS;YACjB,GAAG,QAAQ,CAAC,SAAS;SACtB;QACD,OAAO,EAAE;YACP,GAAG,IAAI,CAAC,OAAO;YACf,GAAG,QAAQ,CAAC,OAAO;SACpB;QACD,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS;KAChD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,cAAc;IAC3B,MAAM,WAAW,GAAG,CAAC,qBAAqB,EAAE,sBAAsB,CAAC,CAAC;IACpE,IAAI,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE/B,wBAAwB;IACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAC/C,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC5B,OAAO,UAAU,CAAC;YACpB,CAAC;YAAC,MAAM,CAAC;gBACP,+BAA+B;YACjC,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,SAAS,KAAK,UAAU;YAAE,MAAM;QACpC,UAAU,GAAG,SAAS,CAAC;IACzB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,IAAI,YAAY,GAAwB,IAAI,CAAC;AAE7C;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,sBAAsB;IACtB,IAAI,MAAM,GAAG,EAAE,GAAG,cAAc,EAAE,CAAC;IAEnC,4BAA4B;IAC5B,MAAM,UAAU,GAAG,MAAM,cAAc,EAAE,CAAC;IAC1C,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,UAAU,CAAC,CAAC;QACpD,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACzC,OAAO,CAAC,KAAK,CAAC,+BAA+B,UAAU,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,gDAAgD;IAChD,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAC;IACrC,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAExC,4BAA4B;IAC5B,MAAM,MAAM,GAAG,kBAAkB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;QACzE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACnC,YAAY,GAAG,cAAc,CAAC;QAC9B,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC;IAC3B,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,YAAY,GAAG,IAAI,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP File Forge - Entry Point
4
+ *
5
+ * A Model Context Protocol server for secure file operations
6
+ * and project scaffolding.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}
package/build/index.js ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP File Forge - Entry Point
4
+ *
5
+ * A Model Context Protocol server for secure file operations
6
+ * and project scaffolding.
7
+ */
8
+ import { startServer } from './server.js';
9
+ // Handle uncaught errors
10
+ process.on('uncaughtException', (error) => {
11
+ console.error('[mcp-file-forge] Uncaught exception:', error);
12
+ process.exit(1);
13
+ });
14
+ process.on('unhandledRejection', (reason) => {
15
+ console.error('[mcp-file-forge] Unhandled rejection:', reason);
16
+ process.exit(1);
17
+ });
18
+ // Start the server
19
+ startServer().catch((error) => {
20
+ console.error('[mcp-file-forge] Fatal error:', error);
21
+ process.exit(1);
22
+ });
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,yBAAyB;AACzB,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE;IACxC,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;IAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;IAC1C,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,MAAM,CAAC,CAAC;IAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,mBAAmB;AACnB,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC5B,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * MCP File Forge - Security Module
3
+ *
4
+ * Exports all security-related functionality.
5
+ */
6
+ export { Sandbox, getSandbox, resetSandbox } from './sandbox.js';
7
+ export { enableReadOnlyMode, disableReadOnlyMode, isReadOnlyMode, validateWriteAllowed, WRITE_TOOLS, isWriteTool, } from './read-only.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/security/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,WAAW,EACX,WAAW,GACZ,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * MCP File Forge - Security Module
3
+ *
4
+ * Exports all security-related functionality.
5
+ */
6
+ export { Sandbox, getSandbox, resetSandbox } from './sandbox.js';
7
+ export { enableReadOnlyMode, disableReadOnlyMode, isReadOnlyMode, validateWriteAllowed, WRITE_TOOLS, isWriteTool, } from './read-only.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/security/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,WAAW,EACX,WAAW,GACZ,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * MCP File Forge - Read-Only Mode
3
+ *
4
+ * Controls whether write operations are allowed.
5
+ */
6
+ import type { FileForgeError } from '../types.js';
7
+ /**
8
+ * Enable read-only mode (disables all write operations).
9
+ */
10
+ export declare function enableReadOnlyMode(): void;
11
+ /**
12
+ * Disable read-only mode (allows write operations).
13
+ */
14
+ export declare function disableReadOnlyMode(): void;
15
+ /**
16
+ * Check if read-only mode is enabled.
17
+ */
18
+ export declare function isReadOnlyMode(): boolean;
19
+ /**
20
+ * Validate that a write operation is allowed.
21
+ * Returns an error if in read-only mode.
22
+ */
23
+ export declare function validateWriteAllowed(): FileForgeError | null;
24
+ /**
25
+ * List of tool names that require write access.
26
+ */
27
+ export declare const WRITE_TOOLS: readonly ["write_file", "create_directory", "copy_file", "move_file", "delete_file", "scaffold_project"];
28
+ /**
29
+ * Check if a tool requires write access.
30
+ */
31
+ export declare function isWriteTool(toolName: string): boolean;
32
+ //# sourceMappingURL=read-only.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-only.d.ts","sourceRoot":"","sources":["../../src/security/read-only.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAOlD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,GAAG,IAAI,CAY5D;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,0GAOd,CAAC;AAEX;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAErD"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * MCP File Forge - Read-Only Mode
3
+ *
4
+ * Controls whether write operations are allowed.
5
+ */
6
+ /**
7
+ * Global read-only state.
8
+ */
9
+ let readOnlyMode = false;
10
+ /**
11
+ * Enable read-only mode (disables all write operations).
12
+ */
13
+ export function enableReadOnlyMode() {
14
+ readOnlyMode = true;
15
+ }
16
+ /**
17
+ * Disable read-only mode (allows write operations).
18
+ */
19
+ export function disableReadOnlyMode() {
20
+ readOnlyMode = false;
21
+ }
22
+ /**
23
+ * Check if read-only mode is enabled.
24
+ */
25
+ export function isReadOnlyMode() {
26
+ return readOnlyMode;
27
+ }
28
+ /**
29
+ * Validate that a write operation is allowed.
30
+ * Returns an error if in read-only mode.
31
+ */
32
+ export function validateWriteAllowed() {
33
+ if (readOnlyMode) {
34
+ return {
35
+ code: 'WRITE_DISABLED',
36
+ message: 'Write operations are disabled in read-only mode',
37
+ details: {
38
+ mode: 'read-only',
39
+ hint: 'Set MCP_FILE_FORGE_READ_ONLY=false to enable write operations',
40
+ },
41
+ };
42
+ }
43
+ return null;
44
+ }
45
+ /**
46
+ * List of tool names that require write access.
47
+ */
48
+ export const WRITE_TOOLS = [
49
+ 'write_file',
50
+ 'create_directory',
51
+ 'copy_file',
52
+ 'move_file',
53
+ 'delete_file',
54
+ 'scaffold_project',
55
+ ];
56
+ /**
57
+ * Check if a tool requires write access.
58
+ */
59
+ export function isWriteTool(toolName) {
60
+ return WRITE_TOOLS.includes(toolName);
61
+ }
62
+ //# sourceMappingURL=read-only.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-only.js","sourceRoot":"","sources":["../../src/security/read-only.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,IAAI,YAAY,GAAG,KAAK,CAAC;AAEzB;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,YAAY,GAAG,IAAI,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,YAAY,GAAG,KAAK,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO;YACL,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,iDAAiD;YAC1D,OAAO,EAAE;gBACP,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,+DAA+D;aACtE;SACF,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,YAAY;IACZ,kBAAkB;IAClB,WAAW;IACX,WAAW;IACX,aAAa;IACb,kBAAkB;CACV,CAAC;AAEX;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,OAAO,WAAW,CAAC,QAAQ,CAAC,QAAwC,CAAC,CAAC;AACxE,CAAC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * MCP File Forge - Sandbox Security Layer
3
+ *
4
+ * Path validation and access control for file operations.
5
+ */
6
+ import type { SandboxConfig, FileForgeError } from '../types.js';
7
+ /**
8
+ * Sandbox manager for validating and controlling file access.
9
+ */
10
+ export declare class Sandbox {
11
+ private config;
12
+ private resolvedAllowedPaths;
13
+ private initialized;
14
+ constructor(config?: Partial<SandboxConfig>);
15
+ /**
16
+ * Initialize the sandbox by resolving all allowed paths to absolute paths.
17
+ */
18
+ initialize(): Promise<void>;
19
+ /**
20
+ * Check if a path is within the allowed sandbox paths.
21
+ */
22
+ isPathAllowed(targetPath: string): boolean;
23
+ /**
24
+ * Validate a path and return error if not allowed.
25
+ */
26
+ validatePath(targetPath: string): Promise<FileForgeError | null>;
27
+ /**
28
+ * Check if a path contains traversal attempts.
29
+ */
30
+ private hasPathTraversal;
31
+ /**
32
+ * Validate file size against limits.
33
+ */
34
+ validateFileSize(size: number): FileForgeError | null;
35
+ /**
36
+ * Validate recursion depth.
37
+ */
38
+ validateDepth(depth: number): FileForgeError | null;
39
+ /**
40
+ * Get the current configuration.
41
+ */
42
+ getConfig(): SandboxConfig;
43
+ /**
44
+ * Get resolved allowed paths.
45
+ */
46
+ getAllowedPaths(): string[];
47
+ /**
48
+ * Update configuration at runtime.
49
+ */
50
+ updateConfig(config: Partial<SandboxConfig>): void;
51
+ }
52
+ /**
53
+ * Get or create the global sandbox instance.
54
+ */
55
+ export declare function getSandbox(config?: Partial<SandboxConfig>): Sandbox;
56
+ /**
57
+ * Reset the global sandbox (useful for testing).
58
+ */
59
+ export declare function resetSandbox(): void;
60
+ //# sourceMappingURL=sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/security/sandbox.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEjE;;GAEG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,oBAAoB,CAAgB;IAC5C,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,GAAE,OAAO,CAAC,aAAa,CAAM;IAU/C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBjC;;OAEG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAkC1C;;OAEG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAqDtE;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAkBxB;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAcrD;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAcnD;;OAEG;IACH,SAAS,IAAI,aAAa;IAI1B;;OAEG;IACH,eAAe,IAAI,MAAM,EAAE;IAI3B;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI;CAkBnD;AAOD;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,OAAO,CAKnE;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAEnC"}