SHELLO CLI MCP SETUP -

1. How was the MCP server installed, where is it located, and can you delete the ssh-mcp folder?

  • How/Where: The @[ssh-mcp] folder is a Node.js + TypeScript project. When we ran npm install inside that folder, Node’s package manager downloaded the dependencies into ssh-mcp/node_modules/ and compiled the TypeScript source code into standard JavaScript under ssh-mcp/build/index.js.
  • Can you delete the folder?: No, do not delete the ssh-mcp folder. Shello CLI does not copy or merge the code of the server into its own files. Instead, it runs the server directly from where it stands on your filesystem. If you delete the folder, Shello CLI will fail to start the server.

2. Where does Shello CLI get the code of the MCP server from?

It gets the code directly from the path configured in your .shello/settings.yml. When Shello CLI starts, it looks at the command config:

command: "node"
args:
  - "C:/REPO/shello-cli-python/ssh-mcp/build/index.js"  # <--- Points to the file we just compiled
  - "--host=13.126.25.225"
  ...

It uses the node interpreter on your machine to execute the JavaScript file (C:/REPO/shello-cli-python/ssh-mcp/build/index.js) in a separate background process.


3. How is the MCP server used in Shello CLI?

  1. Subprocess Spawning: When you start Shello CLI, Python launches the Node server as a background subprocess using standard stdin/stdout streams.
  2. Tool Discovery: Shello CLI sends a message to the Node subprocess asking “what tools do you have?”. The Node subprocess responds with the JSON schemas for exec and sudo-exec.
  3. Dynamic Registration: Shello CLI translates those schemas into OpenAI-compatible formats and registers them in its Python tool registry alongside built-in commands like run_shell_command.
  4. Execution: If the AI model decides to call exec, Python serializes the arguments, writes them to the stdin stream of the Node subprocess as a JSON-RPC message, the Node process executes the SSH commands on your EC2 instance, and writes the output back to Python’s stdout stream.

Architecture & Interaction Diagram

Here is a sequence diagram showing the lifecycle of tool discovery and command execution:

sequenceDiagram
    autonumber
    participant LLM as AI Model (OpenAI/Bedrock)
    participant CLI as Shello CLI (Python Process)
    participant MCPClient as MCPClient (fastmcp / anyio)
    participant Server as ssh-mcp Server (Node Subprocess)
    participant EC2 as Remote EC2 Instance

    Note over CLI, Server: 1. Initialization & Tool Discovery
    CLI->>MCPClient: create_mcp_client(config)
    MCPClient->>Server: Spawns Node Subprocess (node build/index.js --host=...)
    MCPClient->>Server: Request: list_tools() (JSON-RPC via stdin)
    Server-->>MCPClient: Return: ['exec', 'sudo-exec'] schemas (via stdout)
    MCPClient-->>CLI: Returns MCP Client & Discovered Tool Schemas
    CLI->>CLI: Register tools in registry._REGISTRY

    Note over LLM, EC2: 2. Execution Loop
    CLI->>LLM: Send user prompt + tools list (including 'exec', 'sudo-exec')
    LLM-->>CLI: Return tool_call: exec(command="hostname")
    CLI->>CLI: ToolExecutor.execute_tool("exec")
    CLI->>MCPClient: call_tool("exec", {"command": "hostname"})
    MCPClient->>Server: JSON-RPC tools/call (stdin)
    Server->>EC2: SSH Execute: "hostname"
    EC2-->>Server: SSH Return: "devom-ec2-instance"
    Server-->>MCPClient: JSON-RPC Response (stdout)
    MCPClient-->>CLI: Return ToolResult(success=True, output="devom-ec2-instance")
    CLI->>LLM: Send Tool Result
    LLM-->>CLI: Final Answer: "The hostname of your EC2 instance is devom-ec2-instance."
    CLI->>CLI: session end -> Close subprocesses cleanly