ssh-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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Tufan Tunç
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,92 @@
1
+ # SSH MCP Server
2
+
3
+ [![License](https://img.shields.io/github/license/tufantunc/ssh-mcp)](./LICENSE)
4
+ [![NPM Version](https://img.shields.io/npm/v/ssh-mcp)](https://www.npmjs.com/package/ssh-mcp)
5
+
6
+ **SSH MCP Server** is a local Model Context Protocol (MCP) server that exposes SSH control for Linux and Windows systems, enabling LLMs and other MCP clients to execute shell commands securely via SSH.
7
+
8
+ ## Contents
9
+
10
+ - [Quick Start](#quick-start)
11
+ - [Features](#features)
12
+ - [Installation](#installation)
13
+ - [Client Setup](#client-setup)
14
+ - [Testing](#testing)
15
+ - [Disclaimer](#disclaimer)
16
+ - [Support](#support)
17
+
18
+ ## Quick Start
19
+
20
+ - [Install](#installation) SSH MCP Server
21
+ - [Configure](#configuration) SSH MCP Server
22
+ - [Set up](#client-setup) your MCP Client (e.g. Claude Desktop, Cursor, etc)
23
+ - Execute remote shell commands on your Linux or Windows server via natural language
24
+
25
+ ## Features
26
+
27
+ - MCP-compliant server exposing SSH capabilities
28
+ - Execute shell commands on remote Linux and Windows systems
29
+ - Secure authentication via password or SSH key
30
+ - Built with TypeScript and the official MCP SDK
31
+
32
+ ### Tools
33
+
34
+ - `exec`: Execute a shell command on the remote server
35
+
36
+ ## Installation
37
+
38
+ 1. **Clone the repository:**
39
+ ```bash
40
+ git clone https://github.com/tufantunc/ssh-mcp.git
41
+ cd ssh-mcp
42
+ ```
43
+ 2. **Install dependencies:**
44
+ ```bash
45
+ npm install
46
+ ```
47
+
48
+ ## Client Setup
49
+
50
+ You can configure Claude Desktop to use this MCP Server.
51
+ - `host`: Hostname or IP of the Linux or Windows server
52
+ - `port`: SSH port (default: 22)
53
+ - `user`: SSH username
54
+ - `password`: SSH password (or use `key` for key-based auth) (optional)
55
+ - `key`: Path to private SSH key (optional)
56
+
57
+
58
+ ```commandline
59
+ {
60
+ "mcpServers": {
61
+ "ssh-mcp": {
62
+ "command": "npx",
63
+ "args": [
64
+ "ssh-mcp",
65
+ "-y",
66
+ "--",
67
+ "--host=1.2.3.4",
68
+ "--port=22",
69
+ "--user=root",
70
+ "--password=pass",
71
+ "--key=path/to/key"
72
+ ]
73
+ }
74
+ }
75
+ }
76
+ ```
77
+
78
+ ## Testing
79
+
80
+ You can use the [MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector) for visual debugging of this MCP Server.
81
+
82
+ ```sh
83
+ npm run inspect
84
+ ```
85
+
86
+ ## Disclaimer
87
+
88
+ SSH MCP Server is provided under the [MIT License](./LICENSE). Use at your own risk. This project is not affiliated with or endorsed by any SSH or MCP provider.
89
+
90
+ ## Support
91
+
92
+ If you find SSH MCP Server helpful, consider starring the repository or contributing! Pull requests and feedback are welcome.
package/build/index.js ADDED
@@ -0,0 +1,101 @@
1
+ // This file should be renamed to index.ts for TypeScript support
2
+ import 'dotenv/config';
3
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
+ import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
5
+ import { Client as SSHClient } from 'ssh2';
6
+ import { z } from 'zod';
7
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
8
+ // Parse SSH config from process.argv
9
+ // Example usage: node build/index.js --host=1.2.3.4 --port=22 --user=root --password=pass --key=path/to/key
10
+ function parseArgv() {
11
+ const args = process.argv.slice(2);
12
+ const config = {};
13
+ for (const arg of args) {
14
+ const match = arg.match(/^--([^=]+)=(.*)$/);
15
+ if (match) {
16
+ config[match[1]] = match[2];
17
+ }
18
+ }
19
+ return config;
20
+ }
21
+ const argvConfig = parseArgv();
22
+ const HOST = argvConfig.host;
23
+ const PORT = argvConfig.port ? parseInt(argvConfig.port) : 22;
24
+ const USER = argvConfig.user;
25
+ const PASSWORD = argvConfig.password;
26
+ const KEY = argvConfig.key;
27
+ const server = new McpServer({
28
+ name: 'SSH MCP Server',
29
+ version: '1.0.0',
30
+ capabilities: {
31
+ resources: {},
32
+ tools: {},
33
+ },
34
+ });
35
+ server.tool("exec", "Execute a shell command on the remote SSH server and return the output.", {
36
+ command: z.string().describe("Shell command to execute on the remote SSH server"),
37
+ }, async ({ command }) => {
38
+ const sshConfig = {
39
+ host: HOST,
40
+ port: PORT,
41
+ username: USER,
42
+ };
43
+ if (PASSWORD) {
44
+ sshConfig.password = PASSWORD;
45
+ }
46
+ else if (KEY) {
47
+ const fs = await import('fs/promises');
48
+ sshConfig.privateKey = await fs.readFile(KEY, 'utf8');
49
+ }
50
+ const result = await execSshCommand(sshConfig, command);
51
+ return result;
52
+ });
53
+ async function execSshCommand(sshConfig, command) {
54
+ return new Promise((resolve, reject) => {
55
+ const conn = new SSHClient();
56
+ conn.on('ready', () => {
57
+ conn.exec(command, (err, stream) => {
58
+ if (err) {
59
+ reject(new McpError(ErrorCode.InternalError, `SSH exec error: ${err.message}`));
60
+ conn.end();
61
+ return;
62
+ }
63
+ let stdout = '';
64
+ let stderr = '';
65
+ stream.on('close', (code, signal) => {
66
+ conn.end();
67
+ if (stderr) {
68
+ reject(new McpError(ErrorCode.InternalError, `Error (code ${code}):\n${stderr}`));
69
+ }
70
+ else {
71
+ resolve({
72
+ content: [{
73
+ type: 'text',
74
+ text: stdout,
75
+ }],
76
+ });
77
+ }
78
+ });
79
+ stream.on('data', (data) => {
80
+ stdout += data.toString();
81
+ });
82
+ stream.stderr.on('data', (data) => {
83
+ stderr += data.toString();
84
+ });
85
+ });
86
+ });
87
+ conn.on('error', (err) => {
88
+ reject(new McpError(ErrorCode.InternalError, `SSH connection error: ${err.message}`));
89
+ });
90
+ conn.connect(sshConfig);
91
+ });
92
+ }
93
+ async function main() {
94
+ const transport = new StdioServerTransport();
95
+ await server.connect(transport);
96
+ console.error("SSH MCP Server running on stdio");
97
+ }
98
+ main().catch((error) => {
99
+ console.error("Fatal error in main():", error);
100
+ process.exit(1);
101
+ });
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "ssh-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server exposing SSH control for Linux and Windows systems via Model Context Protocol.",
5
+ "type": "module",
6
+ "bin": {
7
+ "ssh-mcp": "build/index.js"
8
+ },
9
+ "scripts": {
10
+ "prepare": "npm run build",
11
+ "build": "tsc --outDir build",
12
+ "inspect": "npx @modelcontextprotocol/inspector node build/index.js"
13
+ },
14
+ "files": [
15
+ "build"
16
+ ],
17
+ "dependencies": {
18
+ "@modelcontextprotocol/sdk": "^1.10.2",
19
+ "dotenv": "^16.3.1",
20
+ "ssh2": "^1.11.0",
21
+ "zod": "^3.24.3"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "^20.17.31",
25
+ "@types/ssh2": "^1.15.5",
26
+ "typescript": "^5.4.5"
27
+ }
28
+ }