server-admin-mcp
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., "@server-admin-mcpcheck the status of all containers in the docker-compose stack"
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.
server-admin-mcp
An MCP server that administers a Debian 13 stage host over SSH: monitoring, Docker Compose, deployment, PostgreSQL, logs, Nginx/TLS, firewall and scheduled automation — 82 tools and 4 workflow prompts.
Stage environments only. This server gives an assistant broad, real access to a machine. Everything destructive sits behind an explicit confirmation step, and a denylist rejects unrecoverable commands outright, but neither is a substitute for pointing it at a host you can afford to rebuild. See Security warnings.
Contents
Installation
Requires Node.js 20 or newer on the machine running the MCP client (not on the server).
npm install
npm run buildThis produces dist/index.js, which is the entry point your MCP client launches. The server speaks MCP over stdio; it never opens a port of its own.
Available scripts:
Script | Purpose |
| Compile TypeScript to |
|
|
| Unit tests for the safety layer (no server needed) |
| Call every read-only tool against the real server and report |
| ESLint |
| Prettier |
| Launch the MCP Inspector against the built server |
Configuration
Every setting is an environment variable prefixed SRVMCP_. Copy .env.example and fill it in, then pass the values through your client's env block.
Optionally, a JSON file with the same keys in camelCase can be pointed at with SRVMCP_CONFIG_FILE (default ./config.json when it exists). Environment variables always win over the file.
SSH connection
Variable | Required | Default | Description |
| yes | — | Hostname or IP of the stage server |
| no |
| SSH port |
| yes | — | SSH login user (e.g. |
| yes | — | Private key used to authenticate. Must exist; |
| no | — | Passphrase, if the key is encrypted |
| no | — |
|
| no |
| Disables host-key verification. Throwaway lab hosts only |
Project layout on the server
Variable | Required | Default | Description |
| no |
| Directory holding the compose file. Always writable; writes here need no extra confirmation |
| no |
| Relative to |
| no |
| Comma-separated roots for file operations. |
PostgreSQL
Reached by running psql on the server, so SRVMCP_PG_HOST is resolved from the server's point of view (localhost or 127.0.0.1 for a container publishing 5432).
Variable | Required | Default | Description |
| no |
| Database host, as seen from the server |
| no |
| Database port |
| for | — | Read-only role used by every read tool |
| no | — | Password for that role |
| for | — | Default database |
| no | — | Write role. Leave unset to make every database write impossible |
| no | — | Password for the write role |
Limits and behaviour
Variable | Required | Default | Description |
| no |
| Line cap per command; excess is removed from the middle |
| no |
| Default command timeout. The process is killed on the server when it expires |
| no |
| JSONL audit trail (local to the client machine) |
| no |
| When |
| no |
| Optional JSON config file |
Configuration is validated at startup with zod. A missing or wrong value produces a message naming the variable and how to fix it, and the process exits before the transport opens — so the client shows the error instead of hanging.
Preparing the server
The server should connect as a dedicated, restricted user — not root.
1. Create the deploy user
sudo adduser --disabled-password --gecos "" deploy
sudo mkdir -p /home/deploy/.ssh
sudo chmod 700 /home/deploy/.sshAdd the MCP server's public key:
echo 'ssh-ed25519 AAAA... server-admin-mcp' | sudo tee -a /home/deploy/.ssh/authorized_keys
sudo chmod 600 /home/deploy/.ssh/authorized_keys
sudo chown -R deploy:deploy /home/deploy/.ssh2. Grant Docker access
sudo usermod -aG docker deployGroup membership only applies to new sessions — restart the MCP server afterwards so it reconnects.
3. Give the project directory to deploy
sudo chown -R deploy:deploy /opt/stage4. A narrow sudoers file
Only the binaries the tools actually need, with no password prompt (an interactive prompt would hang a non-interactive session):
sudo visudo -f /etc/sudoers.d/deploy-mcpdeploy ALL=(root) NOPASSWD: /usr/bin/systemctl, /usr/sbin/nginx, /usr/bin/journalctl, \
/usr/bin/apt-get, /usr/sbin/ufw, /usr/bin/certbot, /usr/bin/install, \
/usr/bin/crontab, /usr/sbin/logrotate, /usr/bin/systemd-analyze, \
/usr/bin/fail2ban-client, /bin/ln, /bin/rm, /bin/cat, /usr/bin/opensslsudo chmod 440 /etc/sudoers.d/deploy-mcp
sudo visudo -c # verify before logging outGrant only what you need. Dropping /usr/bin/apt-get disables package upgrades; dropping /usr/sbin/ufw disables firewall changes. Each affected tool then returns an actionable "this needs a sudoers entry" error rather than failing obscurely.
To read logs without sudo, add the user to adm instead:
sudo usermod -aG adm deploy # /var/log/nginx, journal5. Create a read-only PostgreSQL role
CREATE ROLE mcp_ro LOGIN PASSWORD 'choose-a-strong-password';
GRANT CONNECT ON DATABASE stage_db TO mcp_ro;
GRANT USAGE ON SCHEMA public TO mcp_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO mcp_ro;The ALTER DEFAULT PRIVILEGES line matters: without it, tables created by future migrations are invisible to mcp_ro. It applies to objects created by the role that runs it, so run it as the role owning your migrations. pg_fix_schema_permissions applies this whole set for you.
Optionally, a separate write role for pg_write, pg_maintenance, pg_restore_db and pg_fix_schema_permissions:
CREATE ROLE mcp_rw LOGIN PASSWORD 'another-strong-password';
GRANT CONNECT ON DATABASE stage_db TO mcp_rw;
GRANT USAGE, CREATE ON SCHEMA public TO mcp_rw;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO mcp_rw;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO mcp_rw;Leaving SRVMCP_PG_WRITE_USER unset makes every database write structurally impossible, which is a good default until you need one.
psql must be installed on the server: sudo apt-get install -y postgresql-client.
6. Record the host key
ssh-keyscan -p 22 stage.example.com >> ~/.ssh/known_hostsVerify the fingerprint out of band before trusting it, then point SRVMCP_KNOWN_HOSTS_PATH at that file.
Connecting a client
Claude Desktop / Claude Code
claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\):
{
"mcpServers": {
"server-admin": {
"command": "node",
"args": ["/absolute/path/to/server-admin-mcp/dist/index.js"],
"env": {
"SRVMCP_HOST": "stage.example.com",
"SRVMCP_USER": "deploy",
"SRVMCP_PRIVATE_KEY_PATH": "/home/you/.ssh/id_ed25519",
"SRVMCP_KNOWN_HOSTS_PATH": "/home/you/.ssh/known_hosts",
"SRVMCP_PROJECT_ROOT": "/opt/stage",
"SRVMCP_ALLOWED_PATHS": "/opt/stage,/etc/nginx,/var/log",
"SRVMCP_PG_HOST": "localhost",
"SRVMCP_PG_USER": "mcp_ro",
"SRVMCP_PG_PASSWORD": "...",
"SRVMCP_PG_DATABASE": "stage_db",
"SRVMCP_AUDIT_LOG_PATH": "/var/log/server-admin-mcp/audit.log"
}
}
}
}Use absolute paths — the client's working directory is not yours.
A read-only instance, useful for giving an assistant visibility without any ability to change anything:
{
"mcpServers": {
"stage-readonly": {
"command": "node",
"args": ["/absolute/path/to/server-admin-mcp/dist/index.js"],
"env": { "SRVMCP_READ_ONLY": "true", "SRVMCP_HOST": "...", "SRVMCP_USER": "deploy" }
}
}
}Safety model
Four independent layers, applied in this order:
1. Denylist — absolute, cannot be overridden
Checked on the fully assembled command string inside the SSH layer, so no tool can route around it, and confirm: true does not help. It targets commands that are unrecoverable on a remote box with no console:
Rule | Blocks |
|
|
| Wildcard deletion of a home directory |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Writing over |
| Deleting or truncating |
|
|
The error names the rule that fired, so it is obvious what triggered and why.
Beyond the denylist there is one more hard guard: sec_firewall_rule refuses to deny or delete the SSH port, because applying that rule would disconnect the server permanently.
2. Confirmation — preview, then execute
Destructive tools take confirm: boolean. Without confirm: true the tool executes nothing and instead returns a preview: the exact command, the resulting state change, what is irreversible, and what to check first.
PREVIEW — nothing has been executed.
Command that would run:
$ docker volume prune -f
Effect: Deletes every Docker volume not currently attached to a container.
Irreversible: YES — volume data cannot be recovered. A stopped database
container makes its data volume look unused.
Before approving:
- Run compose_ps first: every stack service must exist, otherwise its
volume counts as unused.
- Take a database backup with pg_backup and copy it off the server first.
To execute, call docker_prune again with the same arguments plus confirm: true.Tools requiring confirmation: sys_service_control (stop only), sys_run_command (when the command mutates state), docker_exec (same), compose_action (down/stop/rm), docker_prune, docker_volume_remove, git_reset, deploy_run, migration_run, pg_write, pg_kill_query, pg_maintenance, pg_restore_db, pg_fix_schema_permissions, nginx_write_config, nginx_enable_site, nginx_disable_site, ssl_renew, sec_firewall_rule, sec_package_upgrade, env_set, all five auto_* tools, and file_write/file_patch outside PROJECT_ROOT.
For free-form commands (sys_run_command, docker_exec) confirmation is demanded when the command contains rm, mv, truncate, kill/pkill, chmod/chown, apt, an overwriting redirect (>, but not 2>&1), a Docker removal, or destructive SQL.
3. Path allowlist — checked twice
Every file operation normalises the path (resolving ..), then verifies it is inside one of SRVMCP_ALLOWED_PATHS. A second check runs on the server after readlink -f, so a symlink planted inside an allowed root cannot be used to reach outside it. A sibling with a shared prefix (/opt/stagemore against /opt/stage) is correctly excluded.
4. Audit log — every call, JSONL
Every invocation is appended to SRVMCP_AUDIT_LOG_PATH, successful or not:
{"ts":"2026-07-25T10:00:00.000Z","tool":"compose_action","args":{"action":"restart","services":["api"],"confirm":true},"status":"ok","command":"docker compose -f /opt/stage/docker-compose.yml restart api","exitCode":0,"durationMs":1234,"confirmed":true}Writes are queued so concurrent calls cannot interleave, and a failure to write warns on stderr without aborting the tool. Credentials are masked before anything is written.
Read-only mode
With SRVMCP_READ_ONLY=true, tools whose readOnlyHint is false are never registered — 49 tools are exposed instead of 82, and a write tool is not merely refused but absent from tools/list entirely. There is no runtime flag an assistant could flip.
Secret masking
Everything leaving the process — tool text, structured content and audit records — passes through a masker covering password/secret/token/api_key/auth/credential-style keys, Bearer/Basic headers, credentials embedded in URLs, JWTs, PEM private-key blocks and PGPASSWORD=. docker_inspect masks environment values by key name, and env_read masks every value unless a single revealKey is named explicitly.
Database credentials are never placed on a command line: a ~/.srvmcp.pgpass file (mode 0600) is written once and referenced through PGPASSFILE, keeping the password out of ps output entirely.
Tool reference
82 tools. RO marks read-only (available in read-only mode); ! marks tools requiring confirm.
System — sys_* (10)
Tool | Description | |
| RO | CPU, load, RAM, swap, every filesystem, uptime — one structured snapshot |
| RO | Heaviest processes by CPU or memory |
| RO | Directory sizes under a path, largest first |
| RO | Listening TCP/UDP sockets with the owning process |
| RO | systemd units and their state; |
| ! | start / stop / restart / reload / status a unit ( |
| RO | Uptime, recent reboots, OOM kills from the kernel log |
| ! | Arbitrary shell command, subject to the denylist |
| Start a long command detached; returns PID and log path | |
| RO | Status and log tail of a background job |
Docker — docker_*, compose_* (13)
Tool | Description | |
| RO | Containers with state, health, ports, uptime |
| RO | Per-container CPU / memory / network / block I/O sample |
| RO | Container logs with |
| RO | Restart count, exit code, OOM flag, health, mounts, networks, masked env |
| ! | Run a command inside a container |
| RO | Compose service states |
| ! |
|
| RO | Fully resolved compose configuration; validates the file |
| RO | Images with size and age |
| ! | Reclaim space: images / volumes / builder / containers / system |
| RO | Networks and the containers attached to each |
| RO | Volumes with size and whether anything uses them |
| ! | Delete one named volume |
Deployment and git — git_*, deploy_*, migration_* (9)
Tool | Description | |
| RO | Branch, HEAD, ahead/behind (fetches first), working-tree changes |
| Fast-forward-only pull | |
| Switch to a branch, tag or commit | |
| RO | Recent commits |
| ! | Rollback to a ref; returns the previous SHA so it can be undone |
| RO | Request URLs from the server; status code and response time |
| ! | pull → build → up -d → settle → container check → health check, stopping at the first failure |
| ! | Apply EF Core / Django / Alembic / custom migrations in a container |
| RO | Applied vs shipped migrations, reporting pending and drift |
PostgreSQL — pg_* (13)
Tool | Description | |
| RO | Read-only SQL as the read-only role; auto- |
| ! | INSERT / UPDATE / DELETE / DDL as the write role |
| RO | Databases with owner, encoding and size |
| RO | Tables with estimated rows, table and index size |
| RO | Columns, indexes and foreign keys of one table |
| RO | Active backends, query age, lock waits |
| ! | Cancel (default) or terminate a backend |
| RO | Slowest statements via |
| ! | VACUUM / VACUUM FULL / ANALYZE / REINDEX |
|
| |
| ! | Restore a custom-format dump |
| RO | Roles, schema ACL and table grants |
| ! | Apply the standard grant set incl. |
Logs — log_* (6)
Tool | Description | |
| RO | journalctl with unit/time/priority/grep filters, repeated messages grouped |
| RO | Tail a log file with optional (invertible) grep |
| RO | Nginx errors grouped by message, upstream failures isolated |
| RO | Requests by status, busiest paths, noisiest IPs, slowest requests, error rate |
| RO | grep across several files with context |
| RO | POST a search body to Elasticsearch from the server |
Nginx and TLS — nginx_*, ssl_* (9)
Tool | Description | |
| RO | vhosts with enabled state, server names, listens, upstreams |
| RO | Read a config file from |
| ! | Backup → write → |
| RO |
|
| Test, then reload only if the test passes | |
| ! | Symlink into |
| ! | Remove the symlink; the vhost file is untouched |
| RO | Certificate issuer, domains, expiry, days remaining |
| ! |
|
Security — sec_* (9)
Tool | Description | |
| RO | ufw / nftables / iptables rules, plus an SSH-reachability sanity check |
| ! | allow / deny / delete a ufw rule (refuses to touch the SSH port) |
| RO | Jails, failure counts, banned addresses |
| RO | Failed logins grouped by source, successful logins listed separately |
| RO | Accounts, shells, sudo membership, last login, locked state |
| RO | authorized_keys per account — fingerprints and comments only |
| RO | Upgradable packages, security ones flagged, reboot-required state |
| ! | Non-interactive apt upgrade, keeping existing config files |
| RO | User crontabs, |
Files — file_*, env_* (8)
Tool | Description | |
| RO | Read a file over SFTP (1 MB cap), optionally a line range |
| ! | Atomic write with automatic timestamped backup |
| ! | Replace one unique string; ambiguous matches are refused |
| RO | Directory listing with size, owner, permissions, mtime |
| RO | Find files by name glob and/or content regex |
| RO | Metadata for one path, including symlink target |
| RO | dotenv keys with masked values unless one |
| ! | Add or update one key, preserving comments and ordering |
Automation — auto_* (5)
Tool | Description | |
| ! | Add a cron job (schedule validated first), tagged |
| ! | Remove matching cron lines and their marker comment |
| ! | Write a unit, |
| ! | pg_dump script + retention + cron, test-run once before scheduling |
| ! | logrotate config, validated with a dry run and removed if invalid |
Prompts
Prompt | Arguments | What it does |
|
| State → history → logs → resources → connectivity → external health, ending in a stated root cause with evidence |
| — | Full read-only sweep, reported by urgency rather than by category |
|
| Disk, git cleanliness, incoming commits, current health, compose validity, database, backups → GO / NO-GO plus the rollback SHA |
|
| Correlates Nginx 5xx with backend logs, resources and database over one window |
Testing
Unit tests — no server required
npm test134 assertions covering the denylist (each dangerous command individually, plus a set of safe ones that must not be blocked), the path allowlist including traversal and shared-prefix cases, middle-out truncation, control-character sanitising, secret masking, shell quoting, read-only SQL classification (including SELECT 1; DROP TABLE users), and CSV parsing.
Schema inspection
npm run inspectConfirms all 82 tools list with valid input and output schemas and complete annotations.
Smoke test — read-only, against the real server
npm run smoke # every read-only tool
npm run smoke -- sys_ pg_ # only these prefixesCalls each read-only tool in turn and prints a pass/fail table. It never invokes a tool whose readOnlyHint is false, so it is safe against a live stage box.
Security warnings
This server grants an assistant broad, real access to a machine. Treat it accordingly.
Stage only. Do not point it at production. Nothing here distinguishes the two for you.
Never connect as
root. Use a dedicated user with the narrow sudoers file above. The safety layers are defence in depth, not a replacement for least privilege.Prefer read-only.
SRVMCP_READ_ONLY=trueremoves 33 write tools from the interface entirely. Run a second, writable instance only when you need it.Leave
SRVMCP_PG_WRITE_USERunset until a database write is genuinely required — that makespg_write,pg_restore_dbandpg_maintenancestructurally unavailable.Set
SRVMCP_KNOWN_HOSTS_PATH. Without it the first connection is trusted blindly, which makes a man-in-the-middle attack possible on the first connect.Review the audit log. It records every call with arguments and exit codes. It is the only record of what was actually done:
tail -f audit.log | jq 'select(.confirmed == true)' # everything executed with confirmation jq 'select(.status == "error")' audit.log # everything that failed jq -r '[.ts, .tool, .command] | @tsv' audit.log # a readable timelineKeep
SRVMCP_ALLOWED_PATHStight. Every added root widens what can be read and written. Adding/defeats the mechanism.The private key is the whole boundary. Anyone who can read it, and the environment holding the passphrase, has the same access this server does.
Backups made by
pg_backupandauto_setup_backupstay on the same host as the database. They protect against a bad migration, not against losing the server. Arrange an off-box copy separately.
Troubleshooting
SSH authentication to deploy@host:22 failed (permission denied)
The key is wrong or not authorised. Reproduce outside the MCP server:
ssh -i ~/.ssh/id_ed25519 -p 22 deploy@stage.example.comCheck the public half is in /home/deploy/.ssh/authorized_keys, and that modes are 700 on ~/.ssh and 600 on authorized_keys — sshd silently refuses looser permissions.
Host key verification failed
Either the host is not in known_hosts yet, or its key changed. Verify the fingerprint out of band, then:
ssh-keyscan -p 22 stage.example.com >> ~/.ssh/known_hostsA changed key on a host you have connected to before deserves investigation before you clear the old entry.
Cannot talk to the Docker daemon: permission denied on /var/run/docker.sock
sudo usermod -aG docker deployThen restart the MCP server — group membership only applies to new sessions.
The command needs sudo but the account cannot use it without a password
The binary is missing from /etc/sudoers.d/deploy-mcp. Add it, then sudo visudo -c to verify. A prompting sudo hangs a non-interactive session, which is why sudo -n is used throughout.
The command timed out after 60s
Either raise timeoutMs for that call, or start the work in the background:
sys_run_background(command: "...") -> sys_check_background(pid: 1234)Builds, migrations, large upgrades and pg_dump on a big database are the usual candidates. deploy_run already allows 30 minutes for the build step.
Cannot reach PostgreSQL at localhost:5432
SRVMCP_PG_HOST is resolved from the server's point of view. If the database runs in Docker, check docker_ps for the published port — usually 127.0.0.1:5432. If it is not published at all, run queries inside the container with docker_exec instead.
Refused: path "/etc/shadow" is outside the configured allowlist
Working as intended. Add the root to SRVMCP_ALLOWED_PATHS only if you genuinely want it reachable.
permission denied for schema public after upgrading to PostgreSQL 15
PostgreSQL 15 removed the implicit CREATE grant on public from PUBLIC. Fix it in one call:
pg_fix_schema_permissions(user: "app_user", schema: "public", confirm: true)A tool is missing from tools/list
Check whether SRVMCP_READ_ONLY=true — write tools are not registered in that mode. The server logs N tools registered, M withheld (read-only mode) to stderr at startup.
Nginx logs are unreadable
They are root-owned by default:
sudo usermod -aG adm deployThe audit log is not being written
The server warns once on stderr and keeps working. Check that the directory exists and is writable by whoever runs the MCP client.
Design decisions
Choices made where the specification left room, recorded here as required.
Project at the repository root, not in a server-admin-mcp/ sub-directory. The working directory was already the project root; nesting would have added a level for no benefit. The package is still named server-admin-mcp.
Two extra source files beyond the specified layout. src/utils/shell.ts holds shell quoting, and src/safety/paths.ts holds the path allowlist — both are separate concerns that would otherwise have been duplicated across nine tool modules. src/tools/registry.ts, src/tools/types.ts and src/tools/context.ts hold the shared registration, envelope and dependency plumbing that keeps each tool module free of boilerplate. src/ssh/knownHosts.ts implements host-key verification, which ssh2 leaves to the caller.
Manual POSIX quoting instead of shell-quote. Single-quoting is five lines; for a server with this much reach, one fewer dependency to audit was worth more than the package.
PGPASSFILE instead of PGPASSWORD. The specification asked for the password to be passed by environment rather than visibly in the command. Because the environment is exported inside the remote sh -c string, PGPASSWORD would still appear in ps output. A ~/.srvmcp.pgpass file at mode 0600, referenced through PGPASSFILE, keeps it out of process listings entirely.
Uniform output envelope. Every tool's outputSchema carries status and message alongside its own fields, with tool-specific fields optional. That is what lets a confirm preview validate against the same schema as a successful run, so previews are ordinary results rather than errors.
Statement batching rejected in pg_query. Checking only the first keyword would let SELECT 1; DROP TABLE users through. String literals and comments are stripped before keyword matching so a value like 'delete from users' is not mistaken for a write.
Remote timeout(1) plus a local timer. Killing the SSH channel alone leaves the remote process running. The command is wrapped in timeout -k 5s, so it dies on the server; the local timer is only a backstop for a wedged channel.
Atomic writes and double path checking. Files are written to a temporary sibling and renamed, so an interrupted transfer cannot leave a half-written config. Paths are checked textually and again on the server after readlink -f, so a symlink inside an allowed root cannot escape it.
ssl_renew defaults to dryRun: true. Let's Encrypt rate-limits real issuance; a dry run costs nothing and catches a broken challenge setup.
sec_firewall_rule will not touch the SSH port. Not a confirmation — a refusal. Applying such a rule would disconnect the server with no way back in, so it must be done from a console session.
auto_setup_backup test-runs the script before scheduling it. A backup that only fails at 3 a.m. is worse than no backup, so nothing is added to cron until one real dump has succeeded.
Extra tools beyond the specification. file_stat (metadata for a single path, useful when diagnosing permissions) and migration_status support for Alembic alongside EF Core and Django.
docker_exec requires confirmation for mutating commands, matching the rule the specification set for sys_run_command; it is the same class of escape hatch.
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.
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/shahinnr/server_mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server