pty-mcp-server 0.0.3.0 → 0.0.4.0
raw patch · 4 files changed
+91/−30 lines, 4 filesdep +pms-infra-procspawn
Dependencies added: pms-infra-procspawn
Files
- CHANGELOG.md +4/−0
- README.md +45/−14
- app/Main.hs +12/−3
- pty-mcp-server.cabal +30/−13
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for pty-mcp-server +## 0.0.4.0 -- 2025-06-29++* Added prompts interface.+ ## 0.0.3.0 -- 2025-06-22 * Added file change monitoring for tools-list.json.
README.md view
@@ -9,17 +9,43 @@ Use responsibly, with full awareness and at your own risk. ----+## 📘 Overview -`pty-mcp-server` is a Haskell implementation of the MCP (Model Context Protocol),-designed to enable AI agents to acquire and control PTY (pseudo-terminal) connections dynamically.+**`pty-mcp-server`** is a Haskell implementation of an **MCP (Model Context Protocol) server** that enables AI agents to dynamically acquire and control **PTY (pseudo-terminal) sessions**, allowing interaction with real system environments through terminal-based interfaces. -Through MCP, AI can interact with external CLI-based tools in a structured, automated, and scriptable way, -leveraging PTY interfaces to execute tasks in real environments.+The server communicates exclusively via **standard input/output (stdio)**, ensuring simple and secure integration with MCP clients. Through this interface, AI agents can execute commands, retrieve system states, and apply configurations—just as a human operator would through a terminal. -As an MCP server, `pty-mcp-server` operates strictly in **stdio** mode, communicating with MCP clients exclusively via standard input and output (stdio).+--- +### 🎯 Purpose++- Provide AI agents with **TTY-based control capabilities** +- Enable **automated configuration, inspection, and operation** using CLI tools +- Facilitate **AI-driven workflows for system development, diagnostics, and remote interaction** +- Allow AI agents to access and operate on **systems beyond the reach of static scripts or APIs** +- Support **Infrastructure as Code (IaC)** scenarios requiring **interactive or stateful terminal workflows** +- Assist in **system integration** across heterogeneous environments and legacy systems +- Empower **AI agents to support DevOps, IaC, and integration pipelines** by operating tools that require human-like terminal interaction + --- +### 🔧 Example Use Cases++- **Dynamic execution of CLI tools** that require a PTY environment + (e.g., embedded systems over serial or SSH-based terminals) +- **REPL automation**: driving GHCi or other CLI-based interactive interpreters +- **Interactive debugging** of Haskell applications or shell-based workflows +- **System diagnostics** through scripted or interactive bash sessions +- **Remote server management** using SSH +- **Hands-on system operation** where CLI behavior cannot be emulated via non-interactive scripting +- **Network device interaction**: configuring routers, switches, or appliances via console +- **AI-assisted IaC workflows**: executing Terraform, Ansible, or shell-based deploy scripts that involve prompts, state reconciliation, or real-time input +- **AI-driven system integration testing** across multiple environments and CLI tools +- **Legacy system automation** where GUI/API is unavailable and only terminal interaction is supported +++---+ ## User Guide (Usage and Setup) ### Features@@ -31,6 +57,9 @@ Launches any command through a PTY interface with optional arguments. Great for general-purpose terminal automation. +- **`pty-terminate`** + Forcefully terminates an active pseudo-terminal (PTY) connection.+ - **`pty-message`** Sends input to an existing PTY session (e.g., `df -k`) without needing full context of the current terminal state. Abstracts interaction in a programmable way.@@ -55,6 +84,15 @@ Launches a GHCi session within a specified project directory, loading a target Haskell file. Supports argument passing and live code interaction. +- **`proc-spawn`** + Spawns an external process using the specified arguments and enables interactive communication via standard input and output. Unlike PTY-based execution, this communicates directly with the process using the runProcess function without allocating a pseudo-terminal. Suitable for non-TUI, stdin/stdout-based interactive programs.++- **`proc-terminate`** + Forcefully terminates a running process created via runProcess.++- **`proc-message`** + Sends structured text-based instructions or commands to a subprocess started with runProcess. It provides a programmable interface for interacting with the process via standard input.+ - **`Scriptable CLI Integration`** The `pty-mcp-server` supports execution of shell scripts associated with registered tools defined in `tools-list.json`. Each tool must be registered by name, and a corresponding shell script (`.sh`) should exist in the configured `tools/` directory. @@ -66,15 +104,10 @@ This separation of tool definitions (`tools-list.json`) and implementation (`tools/your-tool.sh`) ensures clean decoupling and simplifies extensibility. +> **Note:** +> Commands starting with `pty-` are not supported on Windows. These tools rely on POSIX-style pseudo terminals (PTY), which are not natively available in the Windows environment. -### Example Use Cases -- Performing interactive REPL operations (e.g., using GHCi or other CLI-based REPLs)-- Interactive debugging of Haskell applications-- System diagnostics through bash scripting-- Remote server management via SSH-- Dynamic execution of CLI tools in PTY environments- ### Running with Podman or Docker You can build and run `pty-mcp-server` using either **Podman** or **Docker**.@@ -135,8 +168,6 @@ If you prefer to build it yourself, make sure the following requirements are met: - GHC >= 9.12 -- Linux environment with PTY support -- On Windows, use within a WSL (Windows Subsystem for Linux) environment You can install `pty-mcp-server` using `cabal`:
app/Main.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE MultilineStrings #-}-+{-# LANGUAGE CPP #-} module Main where import System.IO@@ -14,16 +14,25 @@ import qualified PMS.UI.Request.App.Control as URQ import qualified PMS.UI.Response.App.Control as URS import qualified PMS.UI.Notification.App.Control as UNO-import qualified PMS.Infrastructure.App.Control as INF import qualified PMS.Infra.CmdRun.App.Control as ICR+import qualified PMS.Infra.ProcSpawn.App.Control as IPS import qualified PMS.Infra.Watch.App.Control as IWA import qualified PMS.Domain.Service.App.Control as DSR +#ifdef mingw32_HOST_OS+#else+import qualified PMS.Infrastructure.App.Control as INF+#endif+ -- | -- main :: IO () main = getArgs >>= \args -> do- let apps = [URQ.run, URS.run, UNO.run, INF.run, ICR.run, IWA.run, DSR.run]+#ifdef mingw32_HOST_OS+ let apps = [URQ.run, URS.run, UNO.run, ICR.run, IPS.run, IWA.run, DSR.run]+#else+ let apps = [URQ.run, URS.run, UNO.run, ICR.run, IPS.run, IWA.run, DSR.run, INF.run]+#endif flip E.catchAny exception $ flip E.finally finalize $ A.run args apps
pty-mcp-server.cabal view
@@ -20,7 +20,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.0.3.0+version: 0.0.4.0 -- A short (one-line) description of the package. synopsis: pty-mcp-server@@ -67,18 +67,35 @@ -- other-extensions: -- Other library packages from which modules are imported.- build-depends: base ^>=4.21.0.0,- safe-exceptions,- optparse-applicative,- pms-ui-request,- pms-ui-response,- pms-ui-notification,- pms-infrastructure,- pms-infra-cmdrun,- pms-infra-watch,- pms-application-service,- pms-domain-service,- pms-domain-model+ if os(windows)+ build-depends:+ base ^>=4.21.0.0,+ safe-exceptions,+ optparse-applicative,+ pms-ui-request,+ pms-ui-response,+ pms-ui-notification,+ pms-infra-cmdrun,+ pms-infra-procspawn,+ pms-infra-watch,+ pms-application-service,+ pms-domain-service,+ pms-domain-model+ else+ build-depends:+ base ^>=4.21.0.0,+ safe-exceptions,+ optparse-applicative,+ pms-ui-request,+ pms-ui-response,+ pms-ui-notification,+ pms-infrastructure,+ pms-infra-cmdrun,+ pms-infra-procspawn,+ pms-infra-watch,+ pms-application-service,+ pms-domain-service,+ pms-domain-model -- Directories containing source files. hs-source-dirs: app