
An MCP server that enables a remote AI to take full control of a Linux server: command execution, file management, service administration, and more.
Remote Execution
Execute any shell command on the remote server with full output capture and timeout control.
File Management
Read, write, edit, move, copy, and delete files. Binary transfer via base64.
Service Control
Start, stop, restart, and inspect systemd services directly through MCP.
Dual Auth
Bearer API key for simplicity, OAuth 2.0 for standard flows. Both coexist seamlessly.
Dual Transport
Streamable HTTP and legacy SSE. Compatible with Claude Code, Claude Desktop, LM Studio, and more.
Skills System
Extend the server's context with custom SKILL.md files for domain-specific knowledge.
Transports
| Transport | Endpoint | Clients |
|---|---|---|
| Streamable HTTP | /mcp | Claude Code, LM Studio, Claude Desktop (via mcp-remote) |
| SSE (legacy) | /sse + /messages/ | Older clients |
| File Upload | POST /upload | Any HTTP client (curl, scripts) |
Installation
One-liner Install (Recommended)
Install directly on your server with a single command:
# Simple HTTP installation (by IP)
curl -sSfL https://raw.githubusercontent.com/servagent/servagent/main/install-remote.sh | sudo bash
# HTTPS installation with Let's Encrypt
curl -sSfL https://raw.githubusercontent.com/servagent/servagent/main/install-remote.sh | sudo bash -s -- your-domain.com
# HTTPS + full sudo privileges
curl -sSfL https://raw.githubusercontent.com/servagent/servagent/main/install-remote.sh | sudo bash -s -- --full-access your-domain.com
# Specific version
curl -sSfL https://raw.githubusercontent.com/servagent/servagent/main/install-remote.sh | sudo bash -s -- --version v0.2.0
Install from Git Clone
# Clone the repository
git clone https://github.com/Servagent/servagent.git
cd servagent
# Simple HTTP
sudo bash install.sh
# HTTPS with Let's Encrypt
sudo bash install.sh your-domain.com
# Full sudo privileges + HTTPS
sudo bash install.sh --full-access your-domain.com
The script automatically:
- Creates a
servagentsystem user - Installs in
/opt/servagentwith a virtualenv - Generates an API key (displayed once — save it!)
- Creates and enables the systemd service
- If a domain is provided: obtains a Let's Encrypt certificate with auto-renewal
Development Install
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
cp .env.example .env
# Edit .env to set SERVAGENT_API_KEY
servagent
Prerequisites
- Linux (Ubuntu/Debian, RHEL/CentOS, etc.)
- Python ≥ 3.10
- Root access for service installation
Quick Start
After installation, the server starts automatically:
- Without domain:
http://<server-ip>:8765/mcp - With domain:
https://your-domain.com/mcp
# Check status
servagent status
# View live logs
sudo journalctl -u servagent -f
# Test with curl
curl -X POST https://your-domain.com/mcp \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
CLI Commands
servagent # Start the MCP server (default)
servagent run # Explicit start
servagent status # Show service status & config
servagent --version # Show version
servagent --help # Show all subcommands
# API Key management
servagent apikey setup # Generate API key
servagent apikey renew # Regenerate (invalidates current)
servagent apikey remove # Disable API key
# OAuth management
servagent oauth setup # Generate OAuth credentials
servagent oauth renew # Regenerate credentials
servagent oauth remove # Disable OAuth
# Maintenance
servagent update # Update to latest
servagent uninstall # Uninstall
The servagent status command displays: systemd service state, PID, uptime, and configuration summary. API keys and OAuth secrets are masked (only the last 6 characters are shown).
MCP Tools
Servagent exposes 18 tools, each annotated with MCP ToolAnnotations (read-only, destructive, idempotent) to guide AI clients.
| Tool | Description |
|---|---|
execute_command | Execute any shell command (bash, python, etc.) |
read_file | Read a text file |
write_file | Write content to a text file |
edit_file | Edit a file (find & replace) |
read_file_binary | Read a binary file (base64) |
write_file_binary | Write a binary file (base64) |
upload_file | Copy a file on the remote server |
list_directory | List directory contents |
move_path | Move a file or directory |
copy_path | Copy a file or directory |
delete_path | Delete a file or directory |
list_processes | List running processes |
kill_process | Kill a process by PID |
tail_file | Tail/follow log files or journalctl |
system_info | System information |
network_info | Network information |
service_action | Systemd service management (start/stop/restart/status) |
get_environment | Environment variables |
By default, execute_command, read_file, write_file, and edit_file are exposed (to save context window tokens). Set SERVAGENT_TOOLS=all to expose all 6 tools.
Configuration
All options are configurable via environment variables (prefixed with SERVAGENT_) or in the .env file:
| Variable | Default | Description |
|---|---|---|
SERVAGENT_HOST | 0.0.0.0 | Listen interface |
SERVAGENT_PORT | 8765 | Listen port |
SERVAGENT_API_KEY | empty | API key (Bearer token). Required in production. |
SERVAGENT_WORK_DIR | cwd | Default working directory |
SERVAGENT_COMMAND_TIMEOUT | 300 | Command timeout (seconds) |
SERVAGENT_MAX_OUTPUT_SIZE | 1000000 | Maximum output size (bytes) |
SERVAGENT_UPLOAD_MAX_SIZE | 100000000 | Max upload file size (100 MB) |
SERVAGENT_TLS_CERTFILE | empty | Path to TLS certificate |
SERVAGENT_TLS_KEYFILE | empty | Path to TLS private key |
SERVAGENT_TOOLS | execute_command,read_file,write_file,edit_file | Tools to expose (all for all 6) |
SERVAGENT_LOG_LEVEL | INFO | Log level |
SERVAGENT_OAUTH_ISSUER_URL | empty | OAuth issuer URL (include /mcp) |
SERVAGENT_OAUTH_CLIENT_ID | empty | Operator OAuth Client ID |
SERVAGENT_OAUTH_CLIENT_SECRET | empty | Associated Client Secret |
SERVAGENT_OAUTH_DB_PATH | ~/.servagent/oauth.db | OAuth SQLite database path |
Skills
Skills allow you to enrich the context sent to the LLM with information specific to your server: hosted domains, SMTP credentials, available services, etc.
Each skill is a directory containing a SKILL.md file whose content is injected into the MCP instructions:
skills/
├── webserver/
│ └── SKILL.md
├── smtp/
│ └── SKILL.md
└── docker/
└── SKILL.md
Example: webserver skill
# webserver
Domain: myserver.com (points to this server)
Web root: /var/www/myserver.com
Nginx config: /etc/nginx/sites-available/myserver.com
SSL: Let's Encrypt, auto-renew via certbot timer
Example: SMTP skill
# smtp
This server can send emails via SMTP.
- Host: smtp.gmail.com
- Port: 587
- User: bot@myserver.com
- Password: xxxx-xxxx-xxxx
- Use: `msmtp` or `swaks` CLI (already installed)
The skills/ directory content is git-ignored as it may contain sensitive, server-specific information.
Connecting MCP Clients
Claude Code natively supports remote MCP servers via Streamable HTTP:
{
"mcpServers": {
"servagent": {
"type": "streamable-http",
"url": "https://your-domain.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
Claude Desktop only supports local MCP servers via stdio. Use mcp-remote as a bridge:
{
"mcpServers": {
"servagent": {
"command": "npx",
"args": [
"mcp-remote",
"https://your-domain.com/mcp",
"--header",
"Authorization: Bearer YOUR_API_KEY"
]
}
}
}
mcp-remote creates a local stdio server that relays requests to the remote HTTP server. Requires Node.js.
Clients that natively support Streamable HTTP (LM Studio, etc.):
{
"mcpServers": {
"servagent": {
"url": "https://your-domain.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
For older clients that only support SSE:
{
"mcpServers": {
"servagent": {
"url": "https://your-domain.com/sse",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
File Upload
The POST /upload endpoint allows sending files to the remote server via multipart/form-data:
curl -X POST https://your-domain.com/upload \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@my-file.tar.gz" \
-F "path=/opt/app/my-file.tar.gz" \
-F "create_dirs=true"
| Field | Required | Description |
|---|---|---|
file | Yes | The file to send |
path | Yes | Destination path on the remote server |
create_dirs | No | Create parent directories (default: true) |
Authentication
Servagent supports two authentication mechanisms that coexist:
| Mechanism | Protects | Configuration |
|---|---|---|
Bearer token (API_KEY) | /mcp, /sse, /messages/, /upload | SERVAGENT_API_KEY |
| OAuth 2.0 | /mcp (access token), /mcp/register (Basic Auth) | SERVAGENT_OAUTH_* |
Authentication Matrix
| Endpoint | Bearer API_KEY | OAuth access_token | Basic CLIENT:SECRET |
|---|---|---|---|
/.well-known/* | — | — | public |
/mcp | ✓ | ✓ | — |
/mcp/register | — | — | required |
/sse | ✓ | — | — |
/messages/ | ✓ | — | — |
/upload | ✓ | — | — |
API Key Management
servagent apikey setup # Generate API key and write to .env
servagent apikey renew # Regenerate (invalidates current)
servagent apikey remove # Comment out API key in .env
OAuth 2.0
The server supports OAuth 2.0 for the /mcp endpoint, enabling compatible MCP applications to connect via the standard OAuth protocol (authorization code + PKCE).
Enabling OAuth
# Auto-detects the issuer URL
servagent oauth setup
# Explicit issuer URL
servagent oauth setup --issuer-url https://your-domain.com/mcp
Connecting from Claude.ai
- Go to Settings → Connectors → Add a custom connector
- Fill in: Name, Remote MCP server URL (
https://your-domain.com/mcp), OAuth Client ID, OAuth Client Secret - Confirm — Claude.ai automatically performs the OAuth flow
Connecting from ChatGPT
- Go to Settings → Connectors → Add a custom connector
- Fill in: Name, MCP server URL, Client ID, Client Secret
- Confirm — ChatGPT performs the OAuth flow with its redirect URI
OAuth Endpoints
| Endpoint | Description |
|---|---|
/.well-known/oauth-authorization-server | OAuth metadata (RFC 8414) |
/.well-known/oauth-protected-resource | Protected resource metadata (RFC 9728) |
/authorize | Authorization endpoint |
/token | Code/refresh token exchange |
/register | Dynamic client registration (RFC 7591) |
/revoke | Token revocation (RFC 7009) |
Dual Purpose of CLIENT_ID / CLIENT_SECRET
- Static OAuth client: Pre-registered at startup for Claude.ai, ChatGPT, and similar UIs that use credentials directly without calling
/mcp/register. - /mcp/register protection: HTTP Basic Auth for dynamic client registration by scripts and SDKs.
Managing OAuth
servagent oauth renew # Regenerate credentials
servagent oauth remove # Disable OAuth
servagent oauth remove --keep-db # Disable but keep database
HTTPS / TLS
TLS is built directly into the installation script. Pass the domain as an argument to enable HTTPS with Let's Encrypt:
# During installation
sudo bash install.sh your-domain.com
# Or after installation
sudo bash setup-tls.sh your-domain.com
The domain must point to the server's IP and port 80 must be open for the Let's Encrypt HTTP-01 challenge.
Nginx Reverse Proxy (Alternative)
Useful when other web services run on the same server:
sudo apt install nginx certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com
sudo cp nginx.conf.example /etc/nginx/sites-available/servagent
sudo ln -s /etc/nginx/sites-available/servagent /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Behind a reverse proxy, set SERVAGENT_HOST=127.0.0.1 to automatically disable DNS-rebinding protection.
Security Notes
This server gives full control over the host machine. Secure it properly.
- Always set
SERVAGENT_API_KEYin production - Always use TLS in production
- Restrict port access via firewall (
ufw,iptables) - The service runs under a dedicated user (
servagent) - By default, the user has no sudo privileges (
NoNewPrivileges=true) - The
--full-accessoption grantssudo NOPASSWD: ALL
Update
servagent update # Update from current branch
servagent update develop # Update from a specific branch
servagent update --force # Force reinstallation
The script: pulls latest changes, copies sources, reinstalls the package, restarts the service, and verifies it’s running. If no changes are detected, it stops without restarting.
Uninstall
servagent uninstall # Interactive
servagent uninstall -y # Non-interactive
servagent uninstall --keep-certs # Keep Let's Encrypt certificates
Removes: systemd service, certbot timer, Nginx config, sudoers file, /opt/servagent, system user, and Let's Encrypt certificates (unless --keep-certs).
Contributing
Contributions are welcome! Here is the recommended workflow:
- Fork the repository and create a branch:
feat/new-tool,fix/auth-bug,docs/improve-readme - Install in development mode:
pip install -e . - Make your changes, test locally
- Update documentation (README, CLAUDE.md) if needed
- Submit a pull request against
main
Adding a New MCP Tool
- Define the tool function in
tools.pywithToolAnnotations - Add the tool name to
ALL_TOOL_NAMES - Register it in
register_tools() - Document it in
README.mdand.env.example
Commit Convention
Use imperative mood: Add tail_file tool, Fix Bearer token validation, Update README
Architecture
cli.py
CLI entry point (click). Subcommands: run, status, update, uninstall, apikey, oauth.
server.py
Starlette ASGI app. Dual transport (Streamable HTTP + SSE). Dynamic instructions builder.
tools.py
18 MCP tool definitions with ToolAnnotations. Conditional registration via register_tools().
config.py
Configuration via pydantic-settings. Lazy loading. SERVAGENT_* env vars.
auth.py
Authentication middleware. Bearer token + Basic Auth + OAuth pass-through. HMAC timing-safe.
oauth_provider.py
OAuth 2.0 server with SQLite. Static client pre-registration. Auto-approve model.
Project Structure
servagent/
src/servagent/
__init__.py # Version
cli.py # CLI entry point (click)
config.py # Configuration (pydantic-settings)
auth.py # Authentication middleware
oauth_provider.py # OAuth 2.0 provider + SQLite
tools.py # All MCP tools
server.py # Server module + transports
skills/ # Skills directory (.gitignored)
pyproject.toml # Metadata and dependencies
install.sh # Production installation
install-remote.sh # One-liner install (curl | bash)
uninstall.sh # Complete uninstallation
setup-tls.sh # HTTPS setup
generate-oauth-credentials.sh
nginx.conf.example # Nginx config template
.env.example # Configuration template
Resources
MCP Protocol
modelcontextprotocol.io — Official documentation, guides, and specification.
Agent Skills
agentskills.io — Agent Skills documentation and specification.
GitHub Repository
github.com/servagent/servagent — Source code, issues, and releases.