Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ release:
prerelease: auto
mode: replace
header: |
{{ .ProjectName }} {{ .Tag }} is a cross-platform terminal system monitor with JSON output, a web dashboard, network diagnostics, and embeddable Go APIs.
{{ .ProjectName }} {{ .Tag }} is a cross-platform terminal system monitor with JSON output, a web dashboard, a read-only local MCP server, network diagnostics, and embeddable Go APIs.

## Changes
footer: |
Expand All @@ -84,13 +84,13 @@ release:

Download archives and Linux packages from the assets below. Verify downloads against `checksums.txt` before installation.

[Documentation](https://vminfo.bestcheapvps.org) · [Quick start](https://vminfo.bestcheapvps.org/guide/quick-start) · [Command reference](https://vminfo.bestcheapvps.org/commands/) · [Compare releases](https://github.com/cloudapp3/vminfo/releases)
[Documentation](https://vminfo.bestcheapvps.org) · [MCP setup](https://vminfo.bestcheapvps.org/commands/mcp) · [Quick start](https://vminfo.bestcheapvps.org/guide/quick-start) · [Command reference](https://vminfo.bestcheapvps.org/commands/) · [Compare releases](https://github.com/cloudapp3/vminfo/releases)

nfpms:
- id: packages
package_name: vminfo
maintainer: cloudapp3
description: Terminal system monitor with JSON output and a web dashboard
description: Terminal system monitor with JSON, web dashboard, and read-only MCP tools
homepage: https://vminfo.bestcheapvps.org
license: MIT
formats:
Expand Down
73 changes: 65 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# vminfo - cross-platform terminal system monitor, web dashboard, and Go library
# vminfo - cross-platform terminal system monitor, web dashboard, MCP server, and Go library

> A single-binary system monitoring toolkit for Linux, macOS, and Windows. Inspect CPU, memory, disk, network, and load in a live terminal UI, export JSON for automation, open a browser dashboard, or embed host metrics in Go. No background agent or configuration is required for local monitoring.
> A single-binary system monitoring toolkit for Linux, macOS, and Windows. Inspect CPU, memory, disk, network, and load in a live terminal UI, export JSON for automation, open a browser dashboard, connect an MCP client, or embed host metrics in Go. No background agent or configuration is required for local monitoring.

[![CI](https://github.com/cloudapp3/vminfo/actions/workflows/ci.yml/badge.svg)](https://github.com/cloudapp3/vminfo/actions/workflows/ci.yml)
[![Latest release](https://img.shields.io/github/v/release/cloudapp3/vminfo?display_name=tag)](https://github.com/cloudapp3/vminfo/releases/latest)
[![GitHub Downloads](https://img.shields.io/github/downloads/cloudapp3/vminfo/total.svg)](https://github.com/cloudapp3/vminfo/releases)
[![Go Reference](https://pkg.go.dev/badge/github.com/cloudapp3/vminfo.svg)](https://pkg.go.dev/github.com/cloudapp3/vminfo)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

Documentation: [vminfo documentation](https://vminfo.bestcheapvps.org) · [中文说明](https://vminfo.bestcheapvps.org/zh/) · [HTTP API reference](https://vminfo.bestcheapvps.org/api) · [Docs source](https://github.com/cloudapp3/vmdocs)
Documentation: [vminfo documentation](https://vminfo.bestcheapvps.org) · [中文说明](https://vminfo.bestcheapvps.org/zh/) · [MCP server](https://vminfo.bestcheapvps.org/commands/mcp) · [HTTP API reference](https://vminfo.bestcheapvps.org/api) · [Docs source](https://github.com/cloudapp3/vmdocs)

[Preview](#preview) · [Quick start](#quick-start) · [Why vminfo](#why-vminfo) · [Commands](#commands) · [Platform support](#platform-support) · [FAQ](#faq) · [Contributing](#contributing)
[Preview](#preview) · [Quick start](#quick-start) · [Why vminfo](#why-vminfo) · [Commands](#commands) · [MCP](#mcp-server) · [Platform support](#platform-support) · [FAQ](#faq) · [Contributing](#contributing)

## Preview

Expand Down Expand Up @@ -74,13 +74,15 @@ Use vminfo when you need to:
- inspect and manage Linux processes without switching tools
- export stable JSON snapshots or JSON Lines for scripts, CI, and automation
- open a lightweight browser dashboard with `vminfo --web`
- let a local MCP client inspect host state and run bounded network diagnostics
- embed host metrics collection or the TUI into your own Go tools

The same binary provides four interfaces:
The same binary provides five interfaces:

- **Terminal UI** - full-screen, live-updating overview and process views
- **JSON and text CLI** - one-shot or streaming output for automation
- **Web dashboard** - browser UI with REST and WebSocket endpoints
- **MCP server** - read-only stdio tools for local AI clients
- **Go library** - public collection APIs plus an embeddable TUI package

Collected metrics include CPU per core, memory, swap, disk, disk I/O, network, load, TCP/UDP counts, TCP state distribution, conntrack usage, interface rates, processes, temperatures, uptime, and host metadata.
Expand Down Expand Up @@ -162,6 +164,7 @@ vminfo net ping vminfo.bestcheapvps.org --tcp-port 443 # TCP ping (default; cr
vminfo net ping vminfo.bestcheapvps.org --mode icmp # real ICMP ping (needs privileges)
vminfo net ip # your public IP + ASN / geo
vminfo net ip 8.8.8.8 # lookup a specific IP
vminfo mcp # read-only MCP server over stdio
vminfo update # check + install the latest tagged release
vminfo update --check # check without installing
vminfo update --version vX.Y.Z
Expand All @@ -175,18 +178,72 @@ Built-in languages: `en`, `zh`, `de`, `es`, `fr`, `ja`, `ko`, `pt`, `ru`.
are accepted. CLI ping count is limited to 1-100 and probe timeouts must be
positive and no greater than 10 seconds.

## MCP server

`vminfo mcp` starts a foreground, tools-only MCP server over stdio. It does not
listen on a network port, run the web dashboard, or perform background update
checks. The process exits when its MCP client disconnects.

Available tools:

| Tool | Purpose |
| --- | --- |
| `get_system_snapshot` | Current host, CPU, memory, disk, network, load, process-count, and health data |
| `list_processes` | Filtered and sorted Linux process data, limited to 200 results |
| `resolve_dns` | DNS lookup with the system or a selected resolver |
| `check_port` | Bounded TCP connectivity and latency check |
| `ping_host` | Bounded TCP or ICMP reachability probes |
| `lookup_ip` | Public IP / ASN / geo lookup through `ip.bestcheapvps.org` |
| `get_version` | Version, build, repository, and schema metadata |

Claude Desktop configuration:

```json
{
"mcpServers": {
"vminfo": {
"command": "/usr/local/bin/vminfo",
"args": ["mcp"]
}
}
}
```

Codex configuration:

```toml
[mcp_servers.vminfo]
command = "/usr/local/bin/vminfo"
args = ["mcp"]
```

Example prompt after connecting an MCP client:

> Check this host's CPU, memory, disk, and network health, then list the five
> processes using the most memory. Do not make any changes.

The MCP server is read-only: it does not expose `kill`, `update`, shell
execution, file writes, prompts, or resources. Process command lines are hidden
unless a call explicitly sets `include_command` to `true`; command arguments
can contain credentials or other secrets. While command lines are hidden, the
process filter does not search them. Snapshot and process results are sent to
the model configured by the MCP client. Network tools contact the requested
target, and `lookup_ip` makes an explicit outbound request to
`ip.bestcheapvps.org`.

## Platform support

| Capability | Linux | macOS | Windows |
| --- | --- | --- | --- |
| `summary` / `watch` | ✅ | ✅ | ✅ |
| TUI | ✅ | ✅ | ✅ |
| Web dashboard | ✅ | ✅ | ✅ |
| MCP server | ✅ | ✅ | ✅ |
| `ps` / `kill` | ✅ | ⚠️ stub | ⚠️ stub |
| `update --check` | ✅ | ✅ | ✅ |
| `update` install | ✅ | ✅ | ⚠️ check-only |

TUI requires a real TTY. `ps` and `kill` are Linux-only by design.
TUI requires a real TTY. `ps`, `kill`, and the MCP `list_processes` tool are Linux-only by design.

## Web dashboard

Expand Down Expand Up @@ -331,15 +388,15 @@ Status badges: `LIVE` · `PAUSED` · `LOADING` · `ERROR` · `STALE`

### Does vminfo require a daemon or configuration file?

No background service or configuration file is required for the TUI, `summary`, `watch`, or network diagnostics. Web mode starts a foreground HTTP server only when you request `vminfo --web`.
No background service or configuration file is required for the TUI, `summary`, `watch`, or network diagnostics. Web mode starts a foreground HTTP server only when you request `vminfo --web`; MCP mode starts a foreground stdio server only when an MCP client runs `vminfo mcp`.

### Does vminfo require root privileges?

Normal monitoring commands do not require root. Installing into a protected directory, sending signals to other users' processes, and ICMP ping may require elevated OS permissions.

### Which features work on Windows and macOS?

The TUI, `summary`, `watch`, web dashboard, and update checks are cross-platform. `ps` and `kill` are Linux-only, and Windows self-update is currently check-only. See [Platform support](#platform-support).
The TUI, `summary`, `watch`, web dashboard, MCP server, and update checks are cross-platform. `ps`, `kill`, and the MCP process-list tool are Linux-only, and Windows self-update is currently check-only. See [Platform support](#platform-support).

### Can I use vminfo in scripts and CI?

Expand Down
6 changes: 6 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/charmbracelet/bubbletea v1.3.10
github.com/charmbracelet/lipgloss v1.1.0
github.com/gorilla/websocket v1.5.3
github.com/modelcontextprotocol/go-sdk v1.6.1
github.com/shirou/gopsutil/v3 v3.24.5
github.com/tklauser/go-sysconf v0.3.12
golang.org/x/net v0.56.0
Expand All @@ -24,6 +25,7 @@ require (
github.com/clipperhouse/uax29/v2 v2.5.0 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/google/jsonschema-go v0.4.3 // indirect
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
Expand All @@ -34,10 +36,14 @@ require (
github.com/muesli/termenv v0.16.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/segmentio/asm v1.1.3 // indirect
github.com/segmentio/encoding v0.5.4 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
golang.org/x/oauth2 v0.35.0 // indirect
golang.org/x/sys v0.46.0 // indirect
golang.org/x/text v0.38.0 // indirect
)
20 changes: 18 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@ github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/jsonschema-go v0.4.3 h1:/DBOLZTfDow7pe2GmaJNhltueGTtDKICi8V8p+DQPd0=
github.com/google/jsonschema-go v0.4.3/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag=
Expand All @@ -43,6 +47,8 @@ github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2J
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/modelcontextprotocol/go-sdk v1.6.1 h1:0zOSupjKUxPKSocPT1Wtago+mUHU2/uZ4xSOY0FGReU=
github.com/modelcontextprotocol/go-sdk v1.6.1/go.mod h1:kzm3kzFL1/+AziGOE0nUs3gvPoNxMCvkxokMkuFapXQ=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
Expand All @@ -55,6 +61,10 @@ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc=
github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg=
github.com/segmentio/encoding v0.5.4 h1:OW1VRern8Nw6ITAtwSZ7Idrl3MXCFwXHPgqESYfvNt0=
github.com/segmentio/encoding v0.5.4/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
Expand All @@ -69,12 +79,16 @@ github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+F
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand All @@ -85,6 +99,8 @@ golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4=
golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8=
golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
34 changes: 34 additions & 0 deletions internal/app/mcp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package app

import (
"context"
"fmt"
"io"
"strings"

"github.com/cloudapp3/vminfo/internal/i18n"
"github.com/cloudapp3/vminfo/internal/mcpserver"
)

func runMCP(ctx context.Context, stdin io.Reader, stdout io.Writer, args []string, tr *i18n.Translator) error {
if len(args) == 1 && isHelpAlias(args[0]) {
_, err := io.WriteString(stdout, mcpHelpText(tr))
return err
}
if len(args) != 0 {
return fmt.Errorf("%w: mcp does not accept arguments: %s", ErrUsage, strings.Join(args, " "))
}
if err := mcpserver.RunStdio(ctx, stdin, stdout); err != nil {
return fmt.Errorf("MCP server error: %w", err)
}
return nil
}

func mcpHelpText(tr *i18n.Translator) string {
return strings.Join([]string{
tr.T("Usage:"),
" vminfo mcp " + tr.T("start read-only MCP server over stdio"),
"",
tr.T("MCP mode reserves stdout for protocol messages and stops when the client disconnects."),
}, "\n") + "\n"
}
Loading