mcp-shell-server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-shell-serverRundf -hon the host and tell me what's using the most disk."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-shell-server
A self-hosted MCP server that gives an MCP client one tool: run a shell command on the host and get back the exit code, stdout and stderr.
It is meant to be reached over the public internet through a tunnel or reverse proxy, so most of the code is not the shell tool (that part is short) but the authentication and audit machinery around it.
Read this before you run it
This grants shell access as the user the service runs as. Anyone who gets a valid token gets that shell. Treat the auth path as the whole security boundary, because it is.
Two things are your responsibility and cannot be fixed in this code:
Set
MCP_ALLOWED_REDIRECT_URIS. Nothing registers without it, which is the intended failure mode.Do not let the shell run as this service's own user. By default it does, which means an authorized command can rewrite the auth database, the trusted keys, this code, and the logs, and can outlive any token you revoke. Set
MCP_EXEC_USERto a separate account and use the hardening inmcp-shell.service.example.
Related MCP server: dynamic-shell-server
What it does
One tool,
run_command(command, cwd, timeout_seconds), executed viabash -lc, with a timeout capped server-side.OAuth 2.0 authorization server built on the MCP SDK's provider interface. Bearer tokens are stored only as SHA-256 hashes, so the database never holds a usable token.
Registration allowlist. Dynamic client registration is open by protocol. On its own that means anyone can register a client with their own callback, send you its authorize link, and receive the code when you sign in on your own real domain. A signature proves who you are, never who you are granting to, so
MCP_ALLOWED_REDIRECT_URISpins the exact callbacks that may register, checked again at authorize and once more before a code is issued. Matching is exact, since a prefix ofhttps://good.examplealso matcheshttps://good.example.attacker.invalid. Unset means no client can register.Named grants on the login page. Before you sign anything the page tells you which client is asking, where the code will be sent, and that continuing hands over shell access.
Two login methods at the authorize step:
SSH signature. The server issues a challenge; you sign it with
ssh-keygen -Y signon a device you control and paste the signature back. Verified against anallowed_signersfile.WebAuthn / passkey, registered through
/webauthn/setup.
Grant-scoped tokens. Every token descended from one login shares a grant id. Revoking any of them revokes all of them, rotation retires the access token it replaces, and replaying an already-rotated refresh token is treated as a compromise and ends the grant. Tokens are bound to this server's resource and refused elsewhere.
Write-only audit log. Each entry's detail is encrypted to an X25519 public key whose private half lives off the box, so a compromise of the host does not hand over the command history.
decrypt_log.pyreads it back with the offline key. Commands are recorded before they run as well as after. SetMCP_REQUIRE_AUDIT_KEY=1to refuse to start rather than fall back to plaintext.Bounded execution. Output is streamed with a hard byte ceiling instead of being buffered whole, and a timeout kills the entire process group rather than just the direct child. Cancelling the request kills the child too.
Commands do not block the server. The MCP SDK calls a synchronous tool function directly on the event loop, so a blocking implementation stops every other request, auth included, for as long as the command runs. Execution is offloaded to a worker thread under its own capacity limiter (
MCP_MAX_CONCURRENT_COMMANDS, default 8).Bounded public state. Body size limits are enforced against bytes actually received, not a
Content-Lengthheader that a chunked request simply omits. Unauthenticated endpoints are rate limited and expired rows are swept.DNS rebinding protection left on, with the public hostname explicitly allowed so tunnelled requests are not rejected.
Layout
File | Purpose |
| MCP server, HTTP routes, the |
| OAuth provider: clients, codes, tokens, SQLite storage |
| Passkey registration and authentication |
| Encrypt-on-append audit logging |
| Offline reader for the audit log |
| Checks for the WebAuthn setup path |
| Loads |
| Integration tests against a throwaway instance |
Install
git clone <this repo> && cd mcp-shell-server
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python server.pyThe first run has nothing to go on, so it asks. It walks through the public URL,
the callbacks allowed to register, the signing principal, the bind address, and
whether commands should run as a separate user. Then it offers to write your SSH
public key into data/allowed_signers with the matching principal, and to
generate an audit key pair, showing the private half once so you can store it off
the machine.
Answers land in .env, owner-readable only. Re-run the questions any time with
.venv/bin/python server.py --setup, or edit the file directly; .env.example
documents every setting including the few setup does not ask about.
Nothing assumes a particular hostname, username, or account name. .env is the
whole configuration.
.env is read by the server itself and by systemd's EnvironmentFile, so the
same file works either way. Real environment variables win over the file, so a
single setting can be overridden for one run without editing anything.
Under systemd there is no terminal to ask at, so a missing configuration exits
with an explanation rather than hanging on a prompt at boot. Run setup once from
a shell first. Install mcp-shell.service.example as a unit after editing the
paths and user.
Bind to loopback and put a tunnel or reverse proxy in front for TLS. The server
expects to be reached at MCP_BASE_URL.
Signing a login challenge
ssh-keygen -Y sign -f ~/.ssh/id_ed25519 -n mcp-login challenge.txtPaste the resulting signature block into the login page.
License
Unlicense. Public domain, see LICENSE.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
111Remote MCP for Android CLI agent build gate, structured receipts, audit logs, and reviewer-ready evi
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
Scoped, audited SSH exec, sessions, and SFTP on your saved servers without exposing credentials
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables secure execution of shell commands via MCP with multiple security layers including command whitelisting and directory restrictions.22MIT
- AlicenseNot gradedqualityFmaintenanceA Model Context Protocol (MCP) server that enables secure execution of shell commands with a dynamic approval system, audit logging, and command revocation.41Apache 2.0

terminal-toolkit-mcpofficial
AlicenseNot gradedqualityCmaintenanceEnables LLM clients to execute shell commands safely through the MCP protocol, with features like session management, safe mode, and process control.1Apache 2.0- AlicenseNot gradedqualityCmaintenanceEnables executing shell commands on the host system via an MCP tool, with JWT/OAuth authentication and audit logging for secure remote access.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/CurrenlyDying/7shell'
If you have feedback or need assistance with the MCP directory API, please join our Discord server