@mindstone/mcp-server-replit-ssh
Advanced tools
+1
-1
@@ -1,2 +0,2 @@ | ||
| export type ErrorCode = 'CONFIG_MISSING' | 'CONFIG_INVALID' | 'CONFIG_REWRITE_FAILED' | 'KEY_WRITE_REJECTED_SYMLINK' | 'PERMISSION_HARDENING_FAILED' | 'WINDOWS_USERNAME_MISSING' | 'HOST_NOT_ALLOWED' | 'HOST_KEY_UNKNOWN' | 'HOST_KEY_MISMATCH' | 'HOST_KEY_RECORD_FAILED' | 'AUTH_FAILED' | 'CONNECTION_FAILED' | 'CONNECTION_TIMEOUT' | 'PATH_INVALID' | 'DELETE_DISABLED' | 'DESTINATION_EXISTS' | 'IO_ERROR' | 'FILE_TOO_LARGE' | 'INTERNAL_ERROR' | 'WRITE_VERIFICATION_FAILED' | 'KEY_GENERATION_FAILED' | 'SFTP_UNAVAILABLE'; | ||
| export type ErrorCode = 'CONFIG_MISSING' | 'CONFIG_INVALID' | 'CONFIG_REWRITE_FAILED' | 'KEY_WRITE_REJECTED_SYMLINK' | 'PERMISSION_HARDENING_FAILED' | 'WINDOWS_USERNAME_MISSING' | 'HOST_NOT_ALLOWED' | 'HOST_KEY_UNKNOWN' | 'HOST_KEY_MISMATCH' | 'HOST_KEY_RECORD_FAILED' | 'AUTH_FAILED' | 'CONNECTION_FAILED' | 'CONNECTION_TIMEOUT' | 'PATH_INVALID' | 'DESTINATION_EXISTS' | 'IO_ERROR' | 'FILE_TOO_LARGE' | 'INTERNAL_ERROR' | 'WRITE_VERIFICATION_FAILED' | 'KEY_GENERATION_FAILED' | 'SFTP_UNAVAILABLE'; | ||
| export interface StructuredError { | ||
@@ -3,0 +3,0 @@ ok: false; |
+1
-1
@@ -86,3 +86,3 @@ import { createRequire } from 'node:module'; | ||
| title: 'Delete Replit File', | ||
| description: 'Permanently delete a file from a Replit project (files only, not directories). Deletion is irreversible — there is no trash. Disabled by default; requires MCP_REPLIT_SSH_ALLOW_DELETE=1 in the server environment.', | ||
| description: 'Permanently delete a file from a Replit project (files only, not directories). Deletion is irreversible — there is no trash. Enabled by default; approval gating is the responsibility of the host tool-approval layer.', | ||
| annotations: remoteWriteAnnotations, | ||
@@ -89,0 +89,0 @@ inputSchema: deleteFileSchema.shape, |
@@ -10,8 +10,5 @@ import { z } from 'zod'; | ||
| }); | ||
| // AGENTS.md invariant #7: irreversible deletion requires an explicit env | ||
| // opt-in on top of destructiveHint — there is no trash/undo on the remote. | ||
| // Read at call time (not module load) so tests and hosts can toggle it. | ||
| function deleteAllowed() { | ||
| return process.env.MCP_REPLIT_SSH_ALLOW_DELETE === '1'; | ||
| } | ||
| // Deletion is irreversible on the remote (no trash/undo). The tool is | ||
| // enabled by default — gating is the host's tool-approval layer's job, | ||
| // signalled via destructiveHint. | ||
| export async function replitDeleteFile(args, callerSignal) { | ||
@@ -41,11 +38,2 @@ const rawPath = args.path?.trim(); | ||
| } | ||
| if (!deleteAllowed()) { | ||
| return JSON.stringify({ | ||
| ok: false, | ||
| error: 'File deletion is disabled. Set MCP_REPLIT_SSH_ALLOW_DELETE=1 in the server environment to enable it.', | ||
| code: 'DELETE_DISABLED', | ||
| action_required: 'Deleting files is irreversible on Replit (no trash), so this tool requires an explicit opt-in.', | ||
| next_step: 'Restart the MCP server with MCP_REPLIT_SSH_ALLOW_DELETE=1 set, then retry. Leave it unset to keep deletion disabled.', | ||
| }); | ||
| } | ||
| const checks = preflightChecks(args.host, args.user); | ||
@@ -52,0 +40,0 @@ if ('error' in checks) |
+1
-1
| { | ||
| "name": "@mindstone/mcp-server-replit-ssh", | ||
| "version": "0.2.0", | ||
| "version": "0.2.1", | ||
| "mcpName": "io.github.mindstone/mcp-server-replit-ssh", | ||
@@ -5,0 +5,0 @@ "description": "Replit SSH MCP server — read, write, list, and check files on Replit projects over SSH/SFTP, plus generate the local SSH key and config.", |
+3
-4
@@ -12,3 +12,3 @@ # @mindstone/mcp-server-replit-ssh | ||
| - **Version:** [0.2.0](./CHANGELOG.md) · [npm](https://www.npmjs.com/package/@mindstone/mcp-server-replit-ssh) | ||
| - **Version:** [0.2.1](./CHANGELOG.md) · [npm](https://www.npmjs.com/package/@mindstone/mcp-server-replit-ssh) | ||
| - **Auth:** Local SSH key on disk (`~/.ssh/rebel-replit` by default; resolved via `~/.ssh/config` `IdentityFile` if set). No env-var-supplied secrets. | ||
@@ -121,3 +121,2 @@ - **Tools:** [9](./src/server.ts) (connection, files, ssh-setup) | ||
| - `MCP_REPLIT_SSH_KNOWN_HOSTS_PATH` — explicit path to the connector's SSH known-hosts file. Defaults to `$MCP_WORKSPACE_PATH/.replit-ssh-known-hosts`, falling back to `$HOME/.replit-mcp/known_hosts`. The file is created with mode `0o600` and the parent directory with mode `0o700`. | ||
| - `MCP_REPLIT_SSH_ALLOW_DELETE` — set to `1` to enable `replit_delete_file`. Deletion is irreversible on Replit (no trash), so the tool fails closed with `DELETE_DISABLED` unless this opt-in is set. | ||
@@ -168,3 +167,3 @@ ## Host configuration examples | ||
| - `replit_move` — move or rename a file or directory. Never overwrites: fails with `DESTINATION_EXISTS` if the destination path is taken. The destination parent directory must already exist. | ||
| - `replit_delete_file` — permanently delete a file (files only, not directories). Deletion is irreversible on Replit — there is no trash — so this tool is disabled unless `MCP_REPLIT_SSH_ALLOW_DELETE=1` is set in the server environment (it also carries `destructiveHint: true`). | ||
| - `replit_delete_file` — permanently delete a file (files only, not directories). Deletion is irreversible on Replit — there is no trash — so the tool carries `destructiveHint: true` and relies on the host's tool-approval layer as the gate. | ||
| - `replit_setup_ssh` — generate an Ed25519 key pair at `~/.ssh/rebel-replit`, write public/private files with mode `0600` (or `icacls` ACL on Windows), and append a `*.replit.dev` block to `~/.ssh/config`. Idempotent by default; pass `force_regenerate=true` to replace the existing key (you will need to re-register the new public key with Replit). | ||
@@ -181,3 +180,3 @@ | ||
| - **Untrusted-content envelopes.** Content from `replit_read_file`, directory-entry names from `replit_list_files`, matched paths/lines from `replit_search_files`, and the peer-authored fields from `replit_check_connection` (server version, working directory, and diagnostic event details such as the server banner and keyboard-interactive prompts) are wrapped in `<untrusted-content source="…">…</untrusted-content>` envelopes per AGENTS.md invariant #6. Hosts must keep the envelopes intact when surfacing tool output to the model. Added in 0.1.2 to close audit finding `replit-ssh-006`; check-connection coverage added later. | ||
| - **Delete is opt-in and fail-closed.** `replit_delete_file` performs irreversible deletion (Replit has no trash), so beyond `destructiveHint: true` it refuses to run unless `MCP_REPLIT_SSH_ALLOW_DELETE=1` is set in the server environment, failing with `DELETE_DISABLED` otherwise. Directories are never deleted. | ||
| - **Delete is irreversible; approval is the host's job.** `replit_delete_file` performs irreversible deletion (Replit has no trash). The tool is enabled by default and carries `destructiveHint: true` — gating belongs to the host's tool-approval layer. Directories are never deleted. | ||
| - **Move never overwrites.** `replit_move` pre-checks the destination and fails with `DESTINATION_EXISTS` rather than clobbering an existing file. | ||
@@ -184,0 +183,0 @@ - **Algorithm allow-list.** Outbound SSH connections restrict the negotiated KEX/host-key/cipher/HMAC algorithms to curve25519-sha256 + ssh-ed25519/rsa-sha2-* + ChaCha20-Poly1305/AES-GCM + ETM HMACs. Blocks downgrade negotiation to weaker suites if the proxy is ever misconfigured. |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
10
-9.09%155648
-0.61%3048
-0.39%184
-0.54%