Skip to main content
Glama
tiefeiyu
by tiefeiyu

Portal — MCP Server for Interactive Programs

An MCP (Model Context Protocol) server purpose-built for interactive programs. Start, monitor, read/write I/O, and control processes that need sustained bidirectional interaction — all through MCP tool calls. Where a one-shot Shell tool hangs on interactive programs, Portal is designed for them.

Python 3.11+ MCP 1.x Windows POSIX uv License

Why Portal

AI agents (Claude, Cursor, …) can drive interactive programs the way they drive a shell — minus the hanging:

  • Interactive programs, end to end — start, read/write I/O, signal, and kill processes that require sustained bidirectional interaction (SSH, GDB, database CLIs, REPLs, full-screen TUIs).

  • Real terminal (PTY) support — ConPTY on Windows (10 1809+) and ptyprocess on POSIX. Programs that check isatty() (ssh, gdb, psql, REPLs) behave exactly as they do in a human-run terminal.

  • Full-screen TUI snapshotsprocess_screen captures the live screen of vim, htop, less and other full-screen TUIs, whose raw record streams are garbled fragments.

  • Never hangs, never orphans — a per-process idle timeout kills stuck programs and cleans up their data.

  • Learns from experience — a persistent, machine-global registry (program_query / program_record) remembers which executables need a PTY, with a confirmation counter so settled facts stick.

  • Clean output — ANSI escape sequences stripped; I/O history stored in SQLite with timestamps, queryable per source (stdout / stderr / stdin).

  • Cross-platform — Windows and POSIX, Python 3.11+, run via uv with zero installation.

When to use it

Situation

Examples

Use

Interactive programs

ssh, gdb, psql, mysql, telnet, REPLs

Portal

Full-screen TUIs

vim, htop, less, top, man

Portal

One-shot commands

ls, echo, build commands

built-in Shell tool

Related MCP server: PTY MCP Server

Quick Start

No package installation needed — Portal runs directly with uv:

uv sync   # optional: pre-create .venv; `uv run` auto-syncs on first launch

Requires uv and Python 3.11+. Dependencies are managed by uv from pyproject.toml: mcp (1.x), aiosqlite, pyte, plus pywinpty (Windows) / ptyprocess (POSIX).

MCP client configuration

Add to your MCP client configuration (e.g., Claude Code), substituting <PORTAL_PATH> with the absolute path of this repo:

{
  "mcpServers": {
    "portal": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--project", "<PORTAL_PATH>", "portal-mcp"]
    }
  }
}

Claude Code one-liner:

claude mcp add portal -- uv run --project "<PORTAL_PATH>" portal-mcp

The PORTAL_DB_PATH environment variable controls the SQLite database location. By default each server instance uses its own file, .portal/portal-<pid>-<timestamp>.db in the working directory — created fresh on every startup, kept as timestamped history, and named per-instance so a lingering or concurrent server can never lock the file and block a new one.

One-Click Install

Copy the prompt from llms-install.md into your AI agent to automatically install and configure Portal.

MCP Tools

Tool

Description

process_start

Start a subprocess with optional args, cwd, env, timeout

process_read

Read output records (stdout/stderr/stdin/both) within a time window

process_write

Write content to a process's stdin

process_signal

Send an OS-native signal to a process

process_list

List all managed processes with summary info

process_inspect

Get detailed info about a process

process_kill

Kill a single process (output data retained)

process_kill_all

Kill all managed processes

process_clear

Clear I/O records for a process

process_cleanup

Remove a terminated process and all its data

process_screen

Snapshot the live screen of a PTY process (for full-screen TUIs)

program_query

Look up whether a program needs a PTY (persistent registry)

program_record

Record a confirmed program fact in the persistent registry

Tools Reference

process_start

Start a subprocess and begin capturing its output.

  • command (required): Executable or command to run

  • args (optional): List of command-line arguments

  • cwd (optional): Working directory

  • env (optional): Environment variables (merged with current env)

  • timeout_ms (optional): Idle timeout in milliseconds (0 = no timeout)

  • pty (optional, default false): Run on a virtual PTY instead of pipes — set true for programs that check isatty() (ssh, gdb, psql, REPLs) or render full-screen TUIs (vim, htop, less); when in doubt, use true (see Virtual PTY support)

Returns: id, os_pid, status

process_read

Read captured output from a process. Resets the idle timer.

  • id (required): Internal process ID

  • source (optional): stdout, stderr, stdin, or both (default: both)

  • duration (optional): How far back to read (default: 1000)

  • unit (optional): Time unit — ns, us, ms, s (default: ms)

Returns: List of records with timestamp, source, content

process_write

Write content to the process's stdin. Only works while running.

  • id (required): Internal process ID

  • content (required): String to write

process_signal

Send an OS signal. On Windows, supports CTRL_C_EVENT (0) and CTRL_BREAK_EVENT (1). On POSIX, supports the full signal set (SIGTERM, SIGKILL, SIGINT, etc.).

  • id (required): Internal process ID

  • signal (required): Signal name or number

process_list

List all managed processes.

Returns: Array of {id, os_pid, status, timeout_ms, inactive_duration_ms, io_count}

process_inspect

Get full details of a single process.

  • id (required): Internal process ID

Returns: All metadata plus io_count, stdout_count, stderr_count, stdin_count

process_kill

Kill a single process. Output data is retained for later reading.

  • id (required): Internal process ID

process_kill_all

Kill all managed processes immediately.

process_clear

Clear all I/O records for a process. The table remains, records are deleted.

  • id (required): Internal process ID

process_cleanup

Remove a terminated process and all its data. Only allowed for exited or killed processes.

  • id (required): Internal process ID

Virtual PTY Support

By default Portal runs programs on OS pipes. Programs that check isatty() (ssh, gdb, psql, interactive REPLs) or render full-screen TUIs (vim, htop, less) need a virtual PTY instead: pass "pty": true to process_start. On Windows this uses ConPTY (Windows 10 1809+); on POSIX it uses ptyprocess.

PTY mode differences from pipe mode:

  • stdout and stderr are merged into one console stream (process_read with source="stderr" returns empty)

  • records are arbitrary chunks, not lines — a line may span multiple records, and prompts may arrive without a trailing newline

  • input you write is echoed back into the output stream (real terminal behavior) — treat echoes as your own input

  • to interrupt a PTY process, write  and a carriage return as two separate writes (Ctrl+C then Enter — split delivery is measurably more reliable) via process_write; a KeyboardInterrupt traceback is expected output

  • process_signal on PTY processes supports only SIGTERM (terminate, a hard kill on Windows), SIGKILL (kill) and CTRL_C_EVENT (graceful Ctrl+C); other signals are rejected

  • exit code is null on Windows (ConPTY exposes none)

process_screen snapshots the live screen of a PTY process — use it for full-screen TUIs, whose record streams are garbled fragments. Passing cols/rows resizes the live PTY first; omitting them is a pure snapshot. The screen stays queryable after exit until process_cleanup.

Choosing pty

Signal

Examples

Decision

Checks isatty()

ssh, gdb, psql, mysql, telnet, REPLs

pty: true

Full-screen TUI

vim, htop, top, less, man

pty: true

Interactive flags

-i / -it / -t

pty: true

One-shot / batch

python -c, build commands

pty: false

Paged one-shots

git log/diff, less

pipe mode + --no-pager/GIT_PAGER=cat

When in doubt, use pty: true — a non-interactive program tolerates a PTY; an interactive one without one hangs.

Program registry

program_query / program_record maintain a persistent, machine-global registry (programs.db in the platform app-data dir, or PORTAL_DATA_DIR if set) of which executables need a PTY. Agents record conclusions after first encounters — including negatives. Repeated confirmation increments confirmed_count (>= 2 means settled); recording the opposite value resets it (a correction).

Process Lifecycle

START → RUNNING → EXITED  → (read-only, data retained)
                → KILLED  → (read-only, data retained)
                → timeout → KILL + CLEANUP (data removed)

READ and WRITE operations reset the idle timer, preventing timeout kills.

ANSI Stripping

All color codes and cursor movement sequences (\x1b[...m, \x1b[...J, etc.) are stripped from output before storage. In pipe mode content is otherwise stored as-is, preserving whatever newline conventions the process uses; in PTY mode bare carriage returns (\r) are also removed (ConPTY emits \r\n).

Architecture

MCP Client
    │ JSON-RPC (stdio)
    ▼
Portal MCP Server
  ├── ProcessManager (lifecycle + timeout monitor)
  │     └── ManagedProcess (per-process wrapper)
  │           └── asyncio.subprocess.Process
  └── Database (SQLite via aiosqlite)
        ├── processes table (metadata)
        └── proc_<id> tables (I/O records)

Development

# Sync the uv environment (includes pytest)
uv sync

# Run tests
uv run pytest tests/ -v

License

MIT — free to use, modify, distribute, and integrate into commercial projects, with attribution.

Author

Developed and maintained by TieFeiyu.

Install Server
A
license - permissive license
A
quality
A
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides tools for executing shell commands both synchronously and asynchronously with real-time output streaming and process management capabilities. It enables users to start background tasks, monitor progress, and manage long-running processes via Stdio or HTTP transports.
    353
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to manage interactive pseudo-terminal (PTY) sessions for programs requiring full terminal emulation like vim, ssh, and interactive REPLs. It provides tools to spawn sessions, send input with escape sequences, and read buffered terminal output.
    19
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    Enables AI agents to start and manage pseudo-terminal sessions, run shell commands and interact with REPLs programmatically.
    7
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables spawning, interacting with, and capturing screen output from terminal-based programs for debugging PTY/TTY/TUI applications.
    15
    7
    MIT

View all related MCP servers

Related MCP Connectors

  • Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.

  • Manage Supabase projects end to end across database, auth, storage, realtime, and migrations. Moni…

  • Control Unreal Engine to browse assets, import content, and manage levels and sequences. Automate…

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tiefeiyu/Portal'

If you have feedback or need assistance with the MCP directory API, please join our Discord server