SSH + Oracle DB MCP Server

SSH + Oracle DB MCP Server

Enables secure SSH and Oracle DB operations with persistent sessions, audit logging, and safe command execution, plus Oracle NMS documentation access.

Category
Visit Server

README

SSH + Oracle DB MCP Server

Production-grade MCP server for persistent SSH PTY sessions and cached Oracle DB diagnostic sessions, with strict server-side review, confirmation, and audit logging.

Highlights

  • Uses ssh2 directly so the server can keep a real PTY shell alive across MCP calls
  • Keeps Oracle DB connections open across MCP calls so agents can reuse DB session state
  • Supports guided interactive PTY commands with prompt classification and follow-up input tools
  • Auto-runs only an explicit safe read-only command list and safe SELECT queries
  • Requires user confirmation for anything outside the explicit safe list
  • Supports custom project and NMS commands, but never runs them blindly when MCP is not confident about the consequences
  • Can browse Oracle Utilities Network Management System documentation versions, download guide PDFs on demand, and return a cached local file path to the agent
  • Writes an audit record for SSH commands, Oracle SQL, hosts, DB targets, approvals, blocks, starts, completions, timeouts, and interrupts to a file on disk
  • Supports MCP stdio by default and optional HTTP + SSE transport

Project layout

src/
|-- index.ts
|-- session.ts
|-- ssh.ts
|-- executor.ts
|-- nms-docs.ts
|-- sudo.ts
|-- db.ts
|-- db-session.ts
|-- policy.ts
|-- sql-policy.ts
|-- policy-config.ts
|-- oracledb.d.ts
`-- utils.ts

ssh-mcp-policy.json
ssh-mcp-policy.example.json
mcp-audit.ndjson
scripts/mcp_smoke_test.mjs

Environment variables

Shell and transport:

  • MCP_SSH_IDLE_TIMEOUT_MS default 1800000
  • MCP_SSH_DEFAULT_TIMEOUT_MS default 30000
  • MCP_SSH_APPROVAL_TTL_MS default 600000
  • MCP_SSH_MAX_SESSIONS default 10
  • MCP_SSH_ALGORITHM_PROFILE default compat; use default to fall back to the raw ssh2 algorithm order
  • MCP_SSH_POLICY_FILE optional path to a custom JSON policy file
  • MCP_TRANSPORT stdio or sse, default stdio
  • MCP_SSE_PORT default 3000

Oracle DB:

  • MCP_DB_IDLE_TIMEOUT_MS default 1800000
  • MCP_DB_DEFAULT_TIMEOUT_MS default 30000
  • MCP_DB_MAX_SESSIONS default 5
  • MCP_DB_MAX_ROWS default 200
  • MCP_DB_CONFIG_DIR optional Oracle Net config directory for wallet or TNS-based connections; if unset, MCP also falls back to TNS_ADMIN when present
  • MCP_DB_WALLET_LOCATION optional wallet directory
  • MCP_DB_WALLET_PASSWORD optional wallet password
  • MCP_DB_HTTPS_PROXY optional HTTPS proxy for secure Oracle DB connections
  • MCP_DB_HTTPS_PROXY_PORT optional proxy port

Audit:

  • MCP_AUDIT_LOG_FILE default C:\ProjectNMS\NMS_MCP\mcp-audit.ndjson when running from this repo

Oracle NMS documentation:

  • MCP_NMS_DOCS_BOOKS_URL default https://docs.oracle.com/en/industries/energy-water/network-management-system/books.html
  • MCP_NMS_DOCS_CACHE_DIR default %USERPROFILE%\Documents\nms-docs

Tools

Shell tools:

  • ssh_connect
  • ssh_connect_target_session
  • review_command
  • review_command_batch
  • execute_command
  • execute_command_batch
  • start_interactive_command
  • write_stdin
  • send_interaction_input
  • read_output
  • read_interaction_state
  • resize_terminal
  • list_sessions
  • close_session
  • interrupt_session

Oracle DB tools:

  • oracle_connect
  • review_sql
  • execute_sql
  • list_db_sessions
  • list_nms_guides
  • get_nms_guide_pdf
  • close_db_session
  • interrupt_db_session

Shared visibility:

  • read_usage_guide
  • read_policy
  • read_audit_log

Oracle NMS documentation tools:

  • list_nms_guides
  • get_nms_guide_pdf

Safety model

The server does not trust user intent or agent intent. It reviews the exact command or SQL text first, decides whether it is on the explicit safe list, and otherwise requires confirmation before running it.

Interactive PTY model

For simple commands, use execute_command.

When you already know the target project or admin account you need, prefer ssh_connect_target_session so MCP logs in once, adopts that target shell once, and then lets the rest of the session run without repeating sudo.

For a related sequence of standalone checks on the same host, use execute_command_batch so MCP can review the whole set together and, when needed, ask for one shared confirmation instead of one prompt per command.

For anything that may prompt, stream, or open a REPL, use the guided interactive flow:

  1. start_interactive_command
  2. read_interaction_state
  3. send_interaction_input
  4. interrupt_session or wait for the command to complete

The server keeps the PTY stateful, classifies common prompt types, and returns structured interaction metadata such as:

  • promptType
  • promptText
  • expectsInput
  • safeToAutoRespond
  • suggestedInputs
  • foregroundCommand

Prompt types currently include shell prompts, sudo/password prompts, yes/no prompts, press-enter prompts, Python REPL prompts, SQL prompts, pagers, and fallback unknown interactive prompts.

Safe shell auto-run list

These commands can auto-run when MCP can clearly recognize them and does not detect extra unsafe behavior:

  • ls
  • pwd
  • cd
  • grep
  • find
  • locate
  • cat
  • ps
  • tail
  • head
  • sort
  • uniq
  • wc
  • echo
  • printf
  • hostname
  • whoami
  • id
  • date
  • uname
  • env
  • printenv
  • command
  • type
  • ss
  • netstat
  • lsof
  • readlink
  • realpath
  • smsReport
  • ISQL read-only SELECT commands only
  • ISQL -admin read-only SELECT commands only

Notes:

  • cd is treated as low-impact and allowed because it only changes the active shell directory
  • Exact Oracle NMS read-only diagnostics such as hostname, whoami, id, getent, grep -n ... | head, ps -ef | grep ... | grep -v grep, find ... | sort | tail, ss -ltn, and exact .nmsrc validation bundles can auto-run when they match the built-in diagnostics profile
  • Exact LDAP-style target-user handoffs such as sudo su - <target-user> or sudo -iu <target-user> can auto-run so MCP can adopt the target shell without an extra confirmation step
  • Exact read-only target-user diagnostics such as sudo -u <target-user> whoami, ps, grep, find, log-path discovery pipelines, or smsReport 2>&1 | head -n ... can auto-run when the underlying command already matches the safe diagnostics rules
  • Other sudo usage is still higher scrutiny and can require confirmation or be blocked by policy
  • For the cleanest Codex workflow, use ssh_connect_target_session instead of repeating sudo -u <target-user> on every command
  • Prefer plain read-only diagnostics or exact .nmsrc wrappers over privilege-changing bundles whenever possible
  • After switching to or adopting a target user shell, do not source .bashrc, .profile, or similar login files unless the command truly depends on extra environment setup
  • Commands that start interactive terminal programs such as python, sqlplus, ISQL, tail -f, less, top, or ssh are not treated as safe auto-run commands
  • If MCP sees shell redirection to files, heredocs, inline scripts, sudo, or other risky patterns, it will stop auto-running and ask first
  • If MCP is not confident that a custom project command is harmless, it asks first

Safe SQL auto-run list

These statements can auto-run when MCP can clearly recognize them as read-only:

  • SELECT ...
  • WITH ... SELECT ...

Notes:

  • Package or schema-qualified function calls inside a SELECT are not auto-run if MCP is not confident about side effects
  • SELECT ... FOR UPDATE is not auto-run

Confirmation behavior

Anything outside the safe auto-run lists requires explicit user confirmation.

What MCP returns:

  • decision: "allow" for explicit safe commands or queries
  • decision: "allow" for safe read-only command batches whose individual commands are all recognized as low risk
  • decision: "approval_required" for unknown, custom, mutating, or higher-risk actions
  • decision: "blocked" only when a deny rule or explicit blocked category in your policy file says MCP must refuse it entirely

Confirmation rule:

  • MCP asks the agent to show the exact command or SQL and a simple consequence summary
  • For execute_command_batch, MCP can ask once for the whole related command set
  • The user must reply with exact CONFIRM
  • The agent must retry with the returned approvalId and userConfirmation: "CONFIRM"
  • MCP should never self-confirm

Audit logging

Every reviewed or executed operation is appended to the audit file:

  • SSH host and username
  • DB target and username
  • command or SQL text
  • review / block / start / completion / timeout / interrupt events
  • timestamps and structured details

The default audit file is mcp-audit.ndjson. Each line is one JSON object so it is easy to search or archive.

Oracle NMS documentation access

Use list_nms_guides to scrape the live Oracle NMS docs library and discover available versions plus guide titles.

Use get_nms_guide_pdf with a version and guide query to resolve one PDF to a local cached file path. If the file is already cached, MCP returns that local path immediately. Otherwise MCP downloads the PDF into the configured cache directory first and then returns the absolute path.

Examples:

  • list_nms_guides to inspect all currently published versions and guides
  • list_nms_guides with {"version":"25.12"}
  • get_nms_guide_pdf with {"version":"25.12","guide":"installation guide"}
  • get_nms_guide_pdf with {"version":"25.12","guide":"nms-installation-guide","refresh":true}

Policy files

The server loads ssh-mcp-policy.json by default. You can point to a different file with MCP_SSH_POLICY_FILE.

Current policy file model:

  • Top-level fields apply to shell command policy
  • Nested sqlPolicy fields apply to Oracle SQL policy
  • denyRules always win over allowRules
  • blockedCategories are for commands or SQL you want MCP to hard-refuse
  • approvalCategories are for categories that should always require confirmation
  • approvedScratchPaths define the only scratch paths MCP will treat as explicitly approved write targets
  • diagnosticsProfiles enable exact built-in read-only command bundles such as the Oracle NMS diagnostics profile
  • allowRules are for narrow exceptions you want MCP to recognize explicitly

Default files:

Policy file shape

{
  "blockedCategories": [
    "privilege-escalation",
    "password-change"
  ],
  "approvalCategories": [
    "session-state",
    "privileged-command"
  ],
  "approvedScratchPaths": [
    "/tmp",
    "/var/tmp"
  ],
  "diagnosticsProfiles": [
    "oracle-nms-readonly"
  ],
  "allowRules": [],
  "denyRules": [
    {
      "name": "block-service-restarts",
      "regex": "\\b(systemctl|service)\\b.*\\b(start|stop|restart|reload)\\b",
      "reason": "Hard-block service interruption through MCP."
    }
  ],
  "sqlPolicy": {
    "blockedCategories": [
      "ddl-destructive",
      "lock-control"
    ],
    "approvalCategories": ["session-state"],
    "allowRules": [],
    "denyRules": [
      {
        "name": "block-delete",
        "regex": "^delete\\b",
        "reason": "Hard-block row deletion through MCP."
      }
    ]
  }
}

Recommended agent behavior

Use these tools anytime they would help NMS development, debugging, runtime validation, issue analysis, or environment checks.

Good uses:

  • SSH tools for host state, WebLogic status, log reading, process inspection, .nmsrc setup, and NMS utility checks
  • Oracle DB tools for safe read-only queries, counts, data checks, schema context checks, and troubleshooting evidence
  • review_command for custom project commands when MCP is not fully certain
  • review_command_batch and execute_command_batch for a human-style sequence of related standalone checks on the same host
  • review_sql for any SQL beyond a plain safe SELECT

Required behavior:

  1. Show the exact command or SQL to the user before asking for confirmation.
  2. Include the simple consequence summary from MCP in that prompt.
  3. Never self-supply CONFIRM.
  4. Treat POLICY_BLOCKED as final unless a human intentionally changes the policy file.
  5. Check the audit log when you need proof of what MCP reviewed or executed.
  6. Prefer standalone checks over bundled shell scripts whenever possible. Run smsReport, then grep, then find, instead of one giant quoted shell command that has to be mentally unpacked later.

Run

On Windows PowerShell, use npm.cmd and codex.cmd. The .ps1 shims may be blocked by execution policy on locked-down machines.

Install dependencies:

npm.cmd install

Build:

npm.cmd run build

Start over stdio:

npm.cmd start

Start over SSE:

$env:MCP_TRANSPORT = "sse"
$env:MCP_SSE_PORT = "3000"
npm.cmd start

Codex setup

Build the project first:

cd C:\ProjectNMS\NMS_MCP
npm.cmd install
npm.cmd run build

Register the server with Codex:

codex.cmd mcp add nms-mcp `
  --env MCP_SSH_DEFAULT_TIMEOUT_MS=120000 `
  --env MCP_SSH_IDLE_TIMEOUT_MS=3600000 `
  --env MCP_SSH_APPROVAL_TTL_MS=600000 `
  --env MCP_SSH_POLICY_FILE=C:\ProjectNMS\NMS_MCP\ssh-mcp-policy.json `
  --env MCP_SSH_MAX_SESSIONS=10 `
  --env MCP_DB_DEFAULT_TIMEOUT_MS=60000 `
  --env MCP_DB_IDLE_TIMEOUT_MS=3600000 `
  --env MCP_DB_MAX_SESSIONS=5 `
  --env MCP_DB_MAX_ROWS=200 `
  --env MCP_AUDIT_LOG_FILE=C:\ProjectNMS\NMS_MCP\mcp-audit.ndjson `
  -- node C:\ProjectNMS\NMS_MCP\dist\index.js

Verify it is registered:

codex.cmd mcp list

Notes:

  • Replace C:\ProjectNMS\NMS_MCP with your actual checkout path if it is different
  • Do not store SSH passwords or DB passwords in the Codex MCP registration; pass them when calling ssh_connect or oracle_connect
  • Tell Codex to review first, show the exact command or SQL to the user, and only continue after exact CONFIRM

Cline setup

Build the project first if you have not already:

cd C:\ProjectNMS\NMS_MCP
npm.cmd install
npm.cmd run build

Open Cline and add a local stdio MCP server using this shape:

{
  "mcpServers": {
    "nms-mcp": {
      "command": "node",
      "args": ["C:\\ProjectNMS\\NMS_MCP\\dist\\index.js"],
      "env": {
        "MCP_SSH_DEFAULT_TIMEOUT_MS": "120000",
        "MCP_SSH_IDLE_TIMEOUT_MS": "3600000",
        "MCP_SSH_APPROVAL_TTL_MS": "600000",
        "MCP_SSH_POLICY_FILE": "C:\\ProjectNMS\\NMS_MCP\\ssh-mcp-policy.json",
        "MCP_SSH_MAX_SESSIONS": "10",
        "MCP_DB_DEFAULT_TIMEOUT_MS": "60000",
        "MCP_DB_IDLE_TIMEOUT_MS": "3600000",
        "MCP_DB_MAX_SESSIONS": "5",
        "MCP_DB_MAX_ROWS": "200",
        "MCP_AUDIT_LOG_FILE": "C:\\ProjectNMS\\NMS_MCP\\mcp-audit.ndjson"
      },
      "disabled": false
    }
  }
}

Notes:

  • Do not store SSH passwords or DB passwords in the Cline config; pass them when calling ssh_connect or oracle_connect
  • Ask Cline to never self-confirm and to show the exact command or SQL plus the consequence summary in the chat before proceeding

First use

SSH:

  1. Call ssh_connect.
  2. Call review_command for anything outside the obvious safe list or when you want MCP to explain the risk before asking the user.
  3. Use execute_command for one-shot commands, execute_command_batch for a related set of standalone checks, or start_interactive_command for prompt-driven commands.
  4. If MCP returns CONFIRMATION_REQUIRED, show the exact command or command set plus the summary, then retry with the same approvalId and userConfirmation: "CONFIRM".
  5. For interactive runs, inspect read_interaction_state and continue with send_interaction_input.

Oracle DB:

  1. Call oracle_connect with DB credentials and either connectString or host plus serviceName or sid.
  2. Call review_sql for anything beyond a plain safe SELECT.
  3. Run execute_sql.
  4. If MCP returns CONFIRMATION_REQUIRED, show the exact SQL and the summary, then retry with the same approvalId and userConfirmation: "CONFIRM".

Example flows

Safe shell command:

{
  "sessionId": "abc123",
  "command": "ps -ef | grep -i nms_1 | grep -v grep"
}

Custom project command that requires confirmation:

{
  "sessionId": "abc123",
  "command": "smsReport"
}

Interactive prompt-driven command:

{
  "sessionId": "abc123",
  "command": "python3 -q",
  "waitForOutputMs": 1500
}

Follow-up interactive input:

{
  "sessionId": "abc123",
  "input": "print(2 + 2)\\n",
  "waitForOutputMs": 1000
}

Safe SQL query:

{
  "dbSessionId": "db123",
  "sql": "select count(*) as class_count from classes"
}

SQL that requires confirmation:

{
  "dbSessionId": "db123",
  "sql": "alter session set current_schema = NMS"
}

PTY recovery flow

If a long-running command times out or an interactive program appears stuck, the PTY session stays attached on purpose so the agent can recover it instead of losing shell state.

Recommended recovery steps:

  1. Call read_output to inspect the latest PTY output.
  2. Call read_interaction_state when you want prompt classification instead of raw output alone.
  3. Call interrupt_session with ctrlC to bring the shell back to a prompt.
  4. Call read_output again if you want to capture the interrupt output.
  5. Run a safe command such as pwd to confirm the shell is ready again.

This is safer than blindly starting a new session because the existing working directory, sourced environment, and any confirmed elevation state remain visible and auditable.

Smoke test

The smoke harness verifies the SSH path end-to-end, exercises the review flow for shell and SQL, and checks PTY recovery with interrupt_session. It auto-confirms inside the local harness only so the test can complete; production agents must not do that.

SSH smoke test:

$env:SSH_TEST_HOST = "your-ssh-host"
$env:SSH_TEST_PORT = "2222"
$env:SSH_TEST_USER = "your_ssh_user"
$env:SSH_TEST_PASSWORD = "your_ssh_password"
node scripts\mcp_smoke_test.mjs

Optional direct Oracle DB smoke test:

$env:DB_TEST_USER = "your_db_user"
$env:DB_TEST_PASSWORD = "your_db_password"
$env:DB_TEST_CONNECT_STRING = "db-host:1521/your_service"
node scripts\mcp_smoke_test.mjs

Audit file example:

Get-Content C:\ProjectNMS\NMS_MCP\mcp-audit.ndjson -Tail 20

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured