nyaterm-bridge: Let AI execute commands in the real NyaTerm terminal

Introduction

When writing command execution capabilities for agents, the common practice is to equip the model with a temporary shell, letting it disconnect, reconnect, and maintain SSH configurations on its own. The cost of this is that assets like connections, jump hosts, and groups are not reused, the command process’s visibility depends on the terminal implementation, and it is difficult to retrospectively review exactly what commands you let the AI run.

nyaterm-bridge takes a different path: it hands over command execution to the NyaTerm terminal you are already using, allowing the AI to reuse the connections and groups already configured in NyaTerm, while using a workspace-level allowlist to restrict which groups and hosts it can touch. It has a complementary relationship with dsh-remote: file reading/writing, workspace mirroring, and SFTP synchronization continue to use dsh-remote, while command execution uses NyaTerm.

The plugin is maintained by visualcjy, belongs to the client-side plugin category, the directory page is at https://www.skillhub.cn/plugins/visualcjy/nyaterm-bridge , and the source code is at https://github.com/visualcjy/nyaterm-bridge .

What is it

One-sentence positioning: let AI execute commands in NyaTerm’s real terminal sessions, make the command process visible in real-time, and restrict available NyaTerm groups and hosts based on the workspace.

It solves two problems: the “landing point of command execution” and “who can be executed”. The former is achieved by reusing NyaTerm’s existing connections, approval, and audit capabilities; the latter is implemented via the allowlist maintained by the plugin itself.

Core Capabilities

Commands do not land in a temporary shell, but in the NyaTerm you are already using, thus directly reusing its assets and traceability capabilities. The following explains this along the “connection, execution, observation, audit” chain.

  1. Reuse existing connections. Groups, jump hosts, SSH/Serial/SFTP, and local terminals are all already configured in NyaTerm. The AI does not need to maintain a separate set of connection configurations and will not bypass your existing jump chain.

  2. Real terminal, observable and approvable. Commands are executed in a real session, and the process and output are visible in real-time. NyaTerm’s External MCP permission mode determines whether manual approval is required.

  3. Audit and playback. MCP calls enter NyaTerm’s audit logs; when session recording/preservation is enabled in NyaTerm, every command and output executed by the AI remains in the session record, available for review later.

  4. Allowlist stacking. The workspace allowlist determines which groups, hosts, and connections the AI can touch; this acts as a two-layer independent gate separate from NyaTerm’s own permission model.

Installation and Activation

Requires NyaTerm (official version) and External MCP enabled in NyaTerm Settings. On the DSH side, version 0.2.1 or higher is recommended. You can install it with one click by searching for nyaterm-bridge in the Plugin Market (dshmarket).

The command to install from the GitHub source code is as follows:

dsh plugin --profile web add github:visualcjy/nyaterm-bridge

For normal dsh web, replace web with your own profile; the desktop profile is managed by the application, please install from the interface. You can also go to DSH Plugins Page → Add Plugin → Install Third-Party Plugin and fill in github:visualcjy/nyaterm-bridge.

After installation, open DSH Settings → NyaTerm Allowlist and confirm that the “MCP Program Location” points to the local nyaterm-mcp (usually auto-detection works).

There are three prerequisites: External MCP is enabled on the NyaTerm side for the plugin to read the discovery document; there is at least one SSH connection in NyaTerm; the NyaTerm window cannot be locked or minimized, because approval prompts appear in the NyaTerm window, and if the window is unavailable, the command will stall or fail.

The discovery document path for external MCP is ~/.nyaterm/mcp/discovery.json (official) or ~/.nyaterm-preview/mcp/discovery.json (Preview), and it also accepts the environment variable NYATERM_MCP_DISCOVERY or the plugin config item discoveryFile.

Toolkit

The plugin holds the MCP connection itself and only registers the following set of nt_* tools; NyaTerm’s original tools are not added to the tool table, so there is no bypass of workspace validation.

Tool Function Read/Write
nt_connections List NyaTerm saved connections and group paths Read-only
nt_workspace Interpret current workspace allowlist determination results Read-only
nt_sessions List NyaTerm sessions and default session within current scope Read-only
nt_status Diagnose bridge, discovery file, permission mode, tool list Read-only
nt_open Open a real NyaTerm tab from a saved connection Write
nt_exec Execute command in a specified session Write
nt_output Read the most recent, ANSI-removed output of that session Read-only

The typical flow is nt_connections → nt_open → nt_exec → nt_output: first list available connections, then open the tab, then execute the command, and finally read the output.

Permission Model

Permissions are divided into three layers.

The first layer is on the NyaTerm side: External MCP’s permission_mode (confirm for popup approval per command / auto for direct execution) and session_scope; this is the final gate.

The second layer is the allowlist: mapping of workspaces to groups, hosts, and connections; workspaces not listed are rejected by default.

The third layer is the guard ctx.tools.guard(): performs a monotonic synchronous review of all nt_* calls; the returned denial cannot be overturned by subsequent listeners; workspaces with observe: true will also block irrelevant tools.

Read/write operations of the allowlist all go through the validation done inside the tool (awaited), and the guard only serves as a fallback, because the guard is synchronous and cannot fetch the connection list.

Configuring Allowlist

Prefer changing in the GUI: DSH Settings → NyaTerm Allowlist (client-side plugin, page left/right columns are in the same position as “Remote Workspace”). It pulls groups and connections from NyaTerm in real-time, selects workspaces from the DSH workspace list, and takes effect immediately after saving.

Under the hood is a JSON file, the location is determined by storeDir; when empty, it defaults to <home>/.dsh/nyaterm-bridge/, global and unrelated to any workspace and process cwd. Note that ~ in the config will not be expanded, and do not hardcode a user’s path in shared config.

{
  "workspaces": {
    "/Users/you/project": {
      "connections": ["2bf46e9f-…"],
      "observeConnections": ["c4bb63a6-…"],
      "groups": [], "hosts": [],
      "observeGroups": [], "observeHosts": [],
      "observe": false
    },
    "C:/work/lab-*": { "observe": true }
  }
}

Every tool call re-reads this file, so you can retry directly after changing it without restarting; writes use tmp + rename for atomic replacement.

Several points:

  1. connections / groups / hosts grant read/write; parallel observeConnections / observeGroups / observeHosts grant read-only.
  2. Write means can nt_open a session, can nt_exec commands; Read-only means can open a session, can nt_output read output, but cannot execute commands. To completely forbid, don’t even give this rule.
  3. observe: true makes the entire workspace read-only, overriding all the above grants.
  4. Priority is connection id > hostname > group; within the same level “read-only” wins. So “one group read-only, only give a certain management server read-write” can be written clearly with one rule.
  5. Matching rules: * is single-level path, ** is arbitrary depth, multiple patterns matching take priority. Backslash and / are equivalent, Windows drive letter case-insensitive.
  6. Unlisted is rejected, unless the plugin config defaultObserveOnly: true, in which case it degrades to read-only: can open session, read output, cannot execute.

Setting MCP Program Location

nyaterm-mcp is installed with NyaTerm; the path changes with installation method and user, so the plugin does not hardcode the path, but parses in the following order: bridgeExecutable saved in allowlist.json (highest priority) → bridgeExecutable in plugin config (deployment-level default) → platform candidate paths, finally looking up PATH.

The GUI is in DSH Settings → NyaTerm Allowlist → MCP Program Location. You can directly fill in the full path (supports quoted paths, ~, %LOCALAPPDATA% and other variables), or click “Auto Detect” to scan locally installed nyaterm-mcp, or click “Restore Auto” to clear and override.

It takes effect immediately after saving; the next nt_* call will relaunch the bridge according to the new path without restarting DSH. When saving, the plugin verifies that the file exists, is a regular file, is executable (Windows only checks existence), and the filename must be nyaterm-mcp / nyaterm-mcp.exe. Under the hood it is just a key in the allowlist storage file:

{
  "bridgeExecutable": "C:\\Users\\me\\AppData\\Local\\Programs\\NyaTerm\\nyaterm-mcp.exe",
  "workspaces": { "...": {} }
}

nt_status will display the finally selected path, source (saved setting / plugin config / auto-detect), and path validation result.

Plugin Configuration

The default config items in cordis.patch.yml are as follows; generally only enabled and enforceAllowlist are used:

- insert:
    - id: nyaterm-bridge
      name: 'nyaterm-bridge'
      config:
        enabled: true
        enforceAllowlist: true
        defaultObserveOnly: false
        # storeDir: /home/you/.dsh/nyaterm-bridge
        # bridgeExecutable: 部署级默认路径;留空 = 自动检测
        # discoveryFile: /home/you/.nyaterm/mcp/discovery.json
        # allowOtherTools: true
        # observeTools: []
        # workspaces: {}   # 内联 allowlist,优先级高于 allowlist.json

Cross-Platform Behavior

The plugin itself does not contain native modules; the host logic uses only Node.js built-in modules, and the client is half pure DOM. Platform differences are concentrated in “finding bridge” and “path matching”. Bridge positioning follows the order: Settings page bridgeExecutable → Plugin config bridgeExecutable → Platform candidate table → PATH lookup; the candidate table covers macOS’s /Applications and ~/Applications, Windows’s %LOCALAPPDATA%\Programs and %PROGRAMFILES%, Linux’s /usr/bin and /usr/local/bin.

The discovery directory uses os.homedir() to resolve (Windows GUI processes usually don’t have HOME); if the bridge path contains “Preview”, it prioritizes ~/.nyaterm-preview, otherwise ~/.nyaterm. Workspace globs will normalize pattern and cwd to /, remove trailing separators, unify Windows drive letters to uppercase; * does not cross separators, ** crosses arbitrary levels; matching is case-sensitive.

On Windows / Linux, you don’t need to know the installation path in advance; it automatically finds based on platform candidate locations and PATH. If a user installs it in a custom directory, they just need to open Settings → NyaTerm Allowlist → MCP Program Location and fill it in once; this value only exists in their own allowlist.json.

Known Limitations

Before deciding whether to adopt, you need to understand the following limitations first.

  1. NyaTerm’s MCP does not return host details (host/port/username are deliberately hidden), so allowlist can only be written based on group paths, connection id, and connection name.
  2. NyaTerm’s MCP does not have a tool to close sessions; tabs opened by nt_open need to be closed manually.
  3. nt_exec must include sessionId (when allowlist is enforced). Without sessionId, the target connection cannot be determined, and the plugin will reject it, which is intentional.
  4. NyaTerm’s MCP commands are executed out-of-band: commands do not appear in the terminal tab, and their audit logs are marked as insertedToTerminal: false; each nt_exec is a new shell, cwd and variables do not persist. To see commands running in the terminal, you must use NyaTerm’s built-in AI command card.
  5. Group rules can only be validated by the tool body; the guard only recognizes explicit connectionId, and the permission bypass interception of nt_open follows the body.
  6. After NyaTerm restarts, ports and tokens change; the plugin will re-read the discovery document and reconnect.
  7. sftp_* tools are not exposed; file operations continue to be handled by dsh-remote’s rw_* to avoid conflict between two file channels.

Suitable Scenarios and Notes

Suitable for teams or individuals who are already using NyaTerm to manage SSH/Serial/SFTP connections, want the AI to directly reuse these connections, and require command traceability and fine-grained authorization. Scenarios where you want to use NyaTerm’s connection assets but don’t want to build a separate command execution channel are a good fit.

What needs attention is that the plugin runs with the permissions of the current dsh process, and the actions it can perform are constrained by those permissions. Before installing, you should check the source code and license (README’s package.json states MIT, author is visualcjy, plugin version 0.1.0). The permission model is a combination of the plugin layer and the NyaTerm layer; only when both layers are configured as expected will the allowlist restrictions be complete.

Conclusion

The value of nyaterm-bridge lies in hanging the act of “AI executing commands” back onto the terminal and connections you are already using, while retaining observability, approval, auditability, and workspace-based authorization. The directory page is at https://www.skillhub.cn/plugins/visualcjy/nyaterm-bridge , and the source code is at https://github.com/visualcjy/nyaterm-bridge .

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye