Platter MCP server
Commit 10. Nov. 2026Exposes filesystem, bash, and JavaScript execution tools to AI agents via stdio or HTTP transports.
Auch bekannt als ScriptSmith/platter
- Stars
- 0
- Tools
- 3
- Downloads, 30 Tage
- —
- Neueste Version
- 2.0.2-rc7
- Letzter Commit
- 10. Nov. 2026
- Lizenz
- MIT
Was ist Platter MCP?
Platter ist ein MCP server. Exposes filesystem, bash, and JavaScript execution tools to AI agents via stdio or HTTP transports. Er stellt 3 Tools bereit, etwa bearer, jwks, none.
Zusammenfassung generiert aus dem README des Projekts
Über Platter MCP server
Platter provides a way for AI agents to interact with a computer through a set of specialized tools. It exposes capabilities for reading, writing, and editing files, as well as executing bash commands and JavaScript. The server is built with Bun and can be deployed as a standalone executable or via Docker. It supports both stdio and HTTP transports, making it suitable for local use or for browser-based agents like Hadrian.
Security and control are central to the design. Developers can restrict access to specific filesystem paths using the allow-path flag or limit bash execution to certain commands via regex patterns. The server offers several authentication modes, including OAuth 2.1, bearer tokens, and JWKS for integrating with external identity providers like Auth0 or Okta. For more isolated environments, a bash sandbox can be enabled to manage filesystem and network access.
Was du damit machen kannst
- 1Automated file manipulationAn AI agent can search for specific patterns in a codebase and apply changes using find-and-replace.
- 2Dynamic code evaluationAn agent can run TypeScript code within a persistent context to perform complex calculations or data processing.
- 3Restricted environment executionYou can limit an agent so it only interacts with a specific project directory.
Geschrieben aus dem README des Projekts. Jeder Use Case wurde gegen ein Zitat daraus geprüft.
So installierst du Platter MCP
Formate geprüft am 10. Nov. 2026Platter MCP in Claude Code installieren
$ claude mcp add platter -- docker run -i --rm ghcr.io/scriptsmith/platter:2.0.2-rc7Platter MCP in Cursor installieren
~/.cursor/mcp.json
{
"mcpServers": {
"platter": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/scriptsmith/platter:2.0.2-rc7"
]
}
}
}Platter MCP in VS Code installieren
.vscode/mcp.json
{
"servers": {
"platter": {
"type": "stdio",
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/scriptsmith/platter:2.0.2-rc7"
]
}
}
}Platter MCP in Claude Desktop installieren
claude_desktop_config.json
{
"mcpServers": {
"platter": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/scriptsmith/platter:2.0.2-rc7"
]
}
}
}Platter MCP in Codex installieren
~/.codex/config.toml
[mcp_servers.platter] command = "docker" args = ["run", "-i", "--rm", "ghcr.io/scriptsmith/platter:2.0.2-rc7"]
Platter MCP in Gemini CLI installieren
~/.gemini/settings.json
{
"mcpServers": {
"platter": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/scriptsmith/platter:2.0.2-rc7"
]
}
}
}Platter MCP tools 3
Erkannt aus dem READMEbearerjwksnone
| bearer | — | |
| jwks | — | |
| none | — |
Automatisierte Checks
Geluften am 13. Nov. 2026Vollständiger Bericht →Noch nicht verifiziert. Ein Server benötigt einen Score von 80, keine kritischen Befunde und genug Daten für unsere Prüfung. Wie die Checks funktionieren
- Source Repository verknüpft und erreichbarscriptsmith/platter is public and reachablegithub.com/scriptsmith/platter ↗Bestanden
- Paket nennt dieses Repository als QuelleNicht geprüft
- Build-Herkunft (Sigstore-Attestierung)Nicht geprüft
- Open Source Lizenz (OSI)MITspdx.org/licenses/MIT.html ↗Bestanden
- Commit oder Release im letzten JahrLast commit or release 2026-11-10github.com/scriptsmith/platter ↗Bestanden
- OpenSSF ScorecardNicht geprüft
- Package-Name ähnelt keinem populären PackageNicht geprüft
- Kein kritischer Hinweis im Paket oder seinen AbhängigkeitenNicht geprüft
- Keine versteckten Anweisungen an das Modell3 tool descriptions and the README read; no override phrases, credential paths or hidden charactersBestanden
- Destruktive Tools sind markiertNo tool named like delete, drop or execBestanden
- Remote-Endpoint beantwortet den MCP-HandshakeNicht geprüft
README
Auf GitHub ansehenplatter
Your computer, served on a platter.
MCP server that exposes Read, Write, Edit, Bash, Glob, Grep, and JS tools over Stdio and StreamableHTTP transports. Built with Bun, compiles to standalone executables.
Designed to be used by browser-based (or any MCP-compatible) agents, like Hadrian, to control a computer.
Tools
| Tool | Description |
|---|---|
| read | Read file contents with pagination (offset/limit). Detects image files (JPEG, PNG, GIF, WebP) and returns metadata. Truncates text to 2000 lines or 50KB. |
| write | Create or overwrite files. Auto-creates parent directories. |
| edit | Find-and-replace with exact or fuzzy matching (normalizes smart quotes, dashes, and Unicode whitespace). Requires a unique match, or use replace_all for every occurrence (exact matches only). Returns a unified diff. |
| bash | Execute shell commands. Commands are killed at a timeout, and an optional warn returns control early while the command keeps running. Output truncated to last 2000 lines or 50KB. |
| glob | Fast file pattern matching. Returns up to 500 paths matching a glob pattern (e.g. **/*.ts). |
| grep | Search file contents using ripgrep. Supports regex, file filtering, context lines, and multiple output modes. Requires rg to be installed. |
| js | Evaluate JavaScript/TypeScript in a persistent Node.js vm context. State persists across calls within a session. Supports await, console.log, and loading packages from unpkg.com via await load("package"). Auto-returns the last expression. Not a security sandbox — see Security below. |
Quick start
From a release binary
Download the latest binary for your platform from Releases, or grab it with curl:
# Download (replace the filename for your platform)
# Available: platter-linux-x64, platter-linux-arm64, platter-darwin-x64, platter-darwin-arm64
curl -fsSL https://github.com/hadriangateway/platter/releases/latest/download/platter-linux-x64 -o platter
chmod +x platter
./platter # stdio mode
./platter -t http # HTTP mode on :3100
Docker
docker run --rm -i ghcr.io/hadriangateway/platter # stdio mode
docker run --rm -p 3100:3100 ghcr.io/hadriangateway/platter -t http --host 0.0.0.0 # HTTP mode
See Docker below for mounting paths, networking, installing extra software, and building custom images.
From source
bun install
bun run dev # run directly from TypeScript
bun run compile # build standalone binary for current platform
Usage
platter v1.x.x
Your computer, served on a platter.
Usage: platter [options]
Options:
-t, --transport <stdio|http> Transport mode (default: stdio)
--tray Run the HTTP server with a Linux system tray
(implies --transport=http, persists state
across restarts in ~/.config/platter)
-p, --port <number> HTTP port (default: 3100)
--host <address> HTTP bind address (default: 127.0.0.1)
--cwd <path> Working directory for tools (default: current directory)
--cors-origin <origin> Allowed CORS origin (default: *)
--auth <mode> Auth mode: oauth, bearer, jwks, none (default: oauth)
--auth-token <token> Bearer token for HTTP auth (auto-generated if omitted)
--tls-cert <path> TLS certificate file (PEM) — enables HTTPS
--tls-key <path> TLS private key file (PEM)
External JWKS / OIDC (--auth jwks — verify tokens from an external IdP):
--oauth-issuer <url> Issuer URL; OIDC-discovers the JWKS endpoint
--jwks-url <url> Explicit JWKS endpoint (overrides discovery)
--oauth-audience <aud> Expected token audience (strongly recommended)
--jwks-scope-grants Map tools:<name> token scopes to tool access
(fail closed: a token with no tools:<name>
scopes is granted no tools)
Process management:
--max-processes <number> Max concurrent bash processes per session (default: 20)
--max-sessions <number> Max concurrent HTTP sessions (default: unlimited)
--bash-timeout <seconds> Kill bash commands that run longer than this, unless
the tool call sets its own timeout (default: 120)
--bash-max-timeout <seconds>
Upper limit on how long a bash command may run,
whatever the tool call asks for (default: none)
Restrictions:
--tools <list> Comma-separated tools to enable (default: all)
Valid: read, write, edit, bash, glob, grep, js
--allow-path <path> Restrict read/write/edit/glob/grep to this path (repeatable)
Does not restrict bash or js
--allow-command <regex> Allow bash commands matching this pattern (repeatable)
Pattern must match the entire command string
Applies to bash only; does not restrict js
Sandbox (applies to bash only; the js tool is never sandboxed):
--sandbox Use just-bash sandbox instead of native bash
--sandbox-fs <mode> Filesystem backend: memory, overlay, readwrite (default: readwrite)
--sandbox-allow-url <url> Allow network access to URL prefix (repeatable)
-h, --help Show this help message
-v, --version Show version number
Restrictions
You can limit which tools are registered, which filesystem paths file tools can access, and which commands the bash tool can execute.
Tool selection
Only register specific tools. Unregistered tools are completely hidden from MCP clients:
platter --tools read,glob,grep # read-only server
platter --tools read,write,edit # no bash/search/js
Path restrictions
Restrict file-accessing tools (read, write, edit, glob, grep) to one or more directory trees. Paths are resolved to absolute form and symlinks are resolved via realpath to prevent escaping:
platter --allow-path /home/user/project
platter --allow-path /home/user/project --allow-path /tmp
Command restrictions
Only allow bash commands whose entire command string matches at least one regex pattern:
platter --allow-command "git( .*)?" # git only
platter --allow-command "git( .*)?" --allow-command "npm( .*)?" # git or npm
platter --allow-command "ls( .*)?" --allow-command "cat .*" # ls or cat
Patterns are anchored: --allow-command "git( .*)?" compiles to ^(?:git( .*)?)$, so git status matches but rm -rf / && git status does not.
Combined example
# Locked-down: read-only tools, scoped to one directory
platter --tools read,glob,grep --allow-path /home/user/project
# Full tools, but bash restricted to git/npm, files restricted to project
platter --allow-path ./my-project --allow-command "git( .*)?" --allow-command "npm( .*)?"
Active restrictions are logged to stderr at startup.
Bash timeout
A bash command that is still running when its timeout expires is killed, and the call returns an error with the output so far. This works the same way with native bash and with --sandbox. Two flags set the limits, both in seconds:
--bash-timeout(default: 120) applies to commands started without atimeoutargument.--bash-max-timeout(default: no limit) is an optional upper limit on how long a command may run. A largertimeoutrequested in a tool call is reduced to this value, and so is--bash-timeoutif it is set higher.
platter --bash-timeout 30 --bash-max-timeout 300
The agent controls two arguments per call:
timeoutreplaces the default for that command, up to the limit.warnreturns control early. If the command is still running afterwarnseconds, the call returns its pid and the command keeps running until it finishes or reaches its timeout. The agent can call again with the pid to keep waiting, pass a newtimeoutto set a new limit counted from that call, or kill the command.
With native bash a warn return includes the output so far. In sandbox mode output is only available once the command finishes.
Authentication
Controlled by --auth <mode>:
| Mode | Description |
|---|---|
oauth (default) |
OAuth 2.1 Authorization Code + PKCE, with a static bearer token as fallback |
bearer |
Static bearer token only |
jwks |
Resource-server mode: verifies JWT access tokens issued by an external OAuth/OIDC issuer (Auth0, Keycloak, Okta, Entra) via JWKS |
none |
No authentication |
OAuth 2.1 (--auth oauth)
MCP clients that support RFC 9728 (Protected Resource Metadata) can discover platter's OAuth endpoints automatically and authenticate without manual token copying.
The flow:
- Client discovers
/.well-known/oauth-authorization-serverand/.well-known/oauth-protected-resource/mcp - Client registers via
POST /register(RFC 7591 dynamic client registration) - Client initiates Authorization Code + PKCE flow via
/authorize - A confirmation code is displayed out-of-band (printed to stderr, or shown as a desktop notification in tray mode)
- User sees a consent page, enters the confirmation code, selects which tools to grant, and approves or denies the request
- Client exchanges the authorization code for tokens at
/token - Subsequent requests use
Authorization: Bearer <access_token>
The confirmation code proves that the person approving the request has access to the platter process — a remote attacker who can reach the consent page cannot approve without it. Codes are single-use and expire after 5 minutes, with a maximum of 5 attempts.
Access tokens expire after 1 hour and can be refreshed. Client registrations are persisted to ~/.config/platter/clients.json. A static bearer token is also accepted as a fallback for clients that don't support OAuth.
Bearer token (--auth bearer)
A random bearer token is generated at startup and printed to stderr (or stored in the system keyring in tray mode). Every request must include Authorization: Bearer <token>. You can provide your own:
platter -t http --auth bearer --auth-token my-secret-token
No authentication (--auth none)
Disable authentication entirely (e.g. behind a reverse proxy that handles auth):
platter -t http --auth none
External JWKS / OIDC (--auth jwks)
In jwks mode platter acts as a pure resource server: it does not mint its own tokens. Instead it verifies JWT access tokens issued by an external OAuth/OIDC authorization server (Auth0, Keycloak, Okta, Microsoft Entra) — validating the signature against the issuer's JWKS, plus the iss, aud, and exp claims. This lets you put platter behind your existing IdP without a reverse proxy.
# Auth0 (root issuer)
platter -t http --auth jwks \
--oauth-issuer https://YOUR_TENANT.auth0.com/ \
--oauth-audience https://platter.example.com/mcp
# Keycloak (realm issuer)
platter -t http --auth jwks \
--oauth-issuer https://kc.example.com/realms/myrealm \
--oauth-audience platter-api
# Skip discovery / point at a JWKS endpoint directly
platter -t http --auth jwks \
--jwks-url https://idp.example.com/.well-known/jwks.json \
--oauth-audience platter-api
Audience validation (strongly recommended). Set --oauth-audience to the API identifier configured in your IdP. If you omit it, platter accepts any valid token from the issuer — including tokens minted for a different resource server (a confused-deputy risk). platter prints a warning at startup when audience validation is disabled.
Discovery. With --oauth-issuer, platter fetches the issuer's /.well-known/openid-configuration (falling back to /.well-known/oauth-authorization-server) at startup to find the jwks_uri and re-advertise the authorization server to RFC 9728-capable MCP clients (at /.well-known/oauth-protected-resource/mcp). Pass --jwks-url to skip discovery, or if the IdP isn't reachable at startup. If discovery fails but --jwks-url is set, token verification still works — only the RFC 9728 auto-advertisement is skipped.
Authorization (what a token can do). By default a verified token gets admin-level access, bounded only by the operator's CLI restrictions (--tools, --allow-path, --allow-command, --sandbox) — the IdP controls who gets in, the CLI flags control what they can do. Pass --jwks-scope-grants to additionally honor tools:<name> scopes in the token (e.g. tools:read tools:bash), which further narrow the granted tools (they can only narrow, never widen the operator's ceiling). The scope claim and Entra-style scp claim are both supported. In this mode access is fail closed: a token carrying no tools:* scope is granted no tools at all, so a token must explicitly request the tools it needs.
No static fallback. Unlike oauth mode, jwks mode accepts only externally-issued JWTs — --auth-token is rejected.
Note:
MCP_DANGEROUSLY_ALLOW_INSECURE_ISSUER_URLis unrelated to this mode. It only concerns platter serving its own issuer over http in--auth oauthmode. An externalhttpsissuer needs no such flag. If you point--auth jwksat a plain-httpissuer (e.g. a localhost Keycloak), platter warns and skips RFC 9728 metadata advertisement, but token verification still works.
TLS (HTTPS)
To serve over HTTPS, provide a PEM-encoded certificate and private key:
platter -t http --tls-cert cert.pem --tls-key key.pem
Both --tls-cert and --tls-key are required together. When provided, the server listens over HTTPS instead of plain HTTP.
To generate a self-signed certificate for development or trusted internal use:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj '/CN=myserver'
platter -t http --tls-cert cert.pem --tls-key key.pem
Stdio mode
For use with Claude Desktop, Cursor, and other MCP clients that spawn a subprocess:
{
"mcpServers": {
"platter": {
"command": "/path/to/platter"
}
}
}
HTTP mode (StreamableHTTP)
For browser-based agents and remote connections:
platter -t http -p 3100
The server exposes a single endpoint at /mcp that handles:
POST /mcp- JSON-RPC messages (initialize, tool calls)GET /mcp- SSE notification streamDELETE /mcp- session teardown
CORS is enabled for all origins by default (reflects the request Origin). To restrict to a specific origin:
platter -t http --cors-origin https://myapp.example.com
Sessions are managed via the Mcp-Session-Id header per the StreamableHTTP spec.
The server validates the Host header to prevent DNS rebinding attacks. When --cors-origin is set, the Origin header is also validated server-side (not just via CORS response headers).
Tray mode (Linux)
Run platter as a persistent background service with a system tray icon:
platter --tray
This implies --transport=http and adds:
- System tray icon via DBus (StatusNotifierItem protocol), compatible with KDE, GNOME (with AppIndicator extension), and other desktop environments.
- Persistent configuration in
~/.config/platter/config.json— auth token, enabled tools, port, host, and working directory survive restarts. - Dynamic tool toggling — enable or disable individual tools at runtime from the tray menu. Changes are persisted and take effect immediately.
- Auth token management — copy the server URL or auth token to clipboard, or regenerate the token. Tokens are stored in the system keyring when available, falling back to the config file.
- Server controls — start, stop, and restart the HTTP server from the tray menu.
Linux installer
The linux/install.sh script performs a user-level install (no sudo required):
./linux/install.sh # install
./linux/install.sh --uninstall # remove
This installs:
~/.local/bin/platter— the binary~/.local/share/applications/platter.desktop— desktop launcher entry~/.local/share/icons/hicolor/scalable/apps/platter.svg— application icon~/.config/systemd/user/platter.service— systemd user unit for autostart
Security
Network (HTTP mode)
- TLS (HTTPS) - optional transport encryption via
--tls-certand--tls-key. Uses Node.jshttpsmodule with PEM-encoded certificate and key files. - OAuth 2.1 + PKCE (
--auth oauth, default) - MCP clients authenticate via Authorization Code flow with PKCE (RFC 7636). Supports dynamic client registration (RFC 7591) and token revocation (RFC 7009). - External JWKS / OIDC (
--auth jwks) - resource-server mode: platter verifies JWT access tokens from an external issuer (Auth0, Keycloak, Okta, Entra) against the issuer's JWKS, validating signature,iss,aud, andexp. Asymmetric algorithms only (alg: noneand HMAC are rejected). See the External JWKS / OIDC section under Authentication for configuration. - Out-of-band consent confirmation - the OAuth consent page requires a confirmation code that is only displayed to the platter operator (via stderr or desktop notification). This prevents CSRF and cross-origin attacks from auto-approving authorization requests. The consent page is also protected with
X-Frame-Options: DENY,Sec-Fetch-Sitevalidation, andOriginheader checking. - Bearer token authentication - a static bearer token (RFC 6750) is available as a fallback in
oauthmode and as the sole method inbearermode. A random 256-bit token is generated at startup unless you provide--auth-tokenor set--auth none. - Host header validation - prevents DNS rebinding attacks. Localhost binds accept only
127.0.0.1,localhost, and::1; remote binds accept only the specified--host. - Origin validation - when
--cors-originis set to a specific origin, requests with a mismatchedOriginheader are actively rejected with 403 (not just filtered by CORS response headers).
Restrictions (best-effort)
--tools, --allow-path, and --allow-command are defense-in-depth controls. They raise the bar significantly but are not a sandbox. The limitations below should be understood before relying on them in a threat model.
What they do well
- Tool selection is enforced at registration time. Disabled tools are never exposed via the MCP protocol. There is no way for a client to invoke or discover them.
- Path validation resolves symlinks via
realpath()on both the target and each allowed path before comparison, preventing traversal via../or symlinked directories. For write targets that don't exist yet, the nearest existing ancestor is resolved instead. - Command validation anchors regex patterns to match the full command string, preventing trivial bypasses like appending
&& malicious-command.
Known limitations and bypasses
- Bash is inherently unrestricted. When the bash tool is enabled, a sufficiently creative command can bypass
--allow-pathentirely (e.g.cat /etc/passwd). If you set--allow-pathwithout also setting--allow-commandor removing bash from--tools, a warning is printed at startup. For strong file-access control, either disable bash (--tools read,write,edit,glob,grep) or pair--allow-pathwith a tight--allow-commandallowlist. - The
jstool is not a security sandbox. It runs code in a Node.jsvmcontext, which Node's own documentation explicitly states is not a security mechanism — untrusted code can escape the context via known techniques. Even without an escape, the runtime exposesfetch(arbitrary network access, including private/loopback addresses),Buffer, and aload()helper that downloads and executes arbitrary code fromunpkg.comor any other URL. None of--allow-path,--allow-command,--sandbox, or--sandbox-allow-urlapply to thejstool — these flags only affect the file and bash tools. If thejstool is enabled, treat the server as having roughly the same blast radius as unrestricted bash. To disable it:--tools read,write,edit,bash,glob,grep. For strong isolation, run platter inside a container or VM. - Command regex operates on the raw string. It does not parse shell syntax. Patterns like
--allow-command "git( .*)?"blockrm && git status(because the full string doesn't match), but a determined attacker could construct commands that the regex matches yet that execute unintended code, for example if an allowed pattern is too broad. Write patterns as narrowly as possible. - Symlink TOCTOU. Path validation resolves symlinks at check time. If a symlink target is changed between the check and the actual file operation, the validation can be bypassed. This is a fundamental limitation of userspace path checking.
- Glob/grep search scope.
--allow-pathvalidates the search directory for glob and grep, but results within that directory tree may include symlinks pointing outside it. The content of those symlink targets could be returned in grep output or listed by glob. - No process-level sandboxing. All restrictions are enforced in application code within the platter process. They do not use OS-level mechanisms (seccomp, namespaces, pledge, etc.). A vulnerability in platter itself, Bun, or a dependency could bypass all restrictions.
For stronger isolation, use the just-bash sandbox, a Docker container, or both.
Sandbox mode (just-bash)
Opt into just-bash, a TypeScript reimplementation of bash with a virtual filesystem, for sandboxed command execution. No native processes are spawned; the shell runs entirely in the Bun runtime.
platter --sandbox # readwrite fs, no network
platter --sandbox --sandbox-fs memory # pure in-memory fs
platter --sandbox --sandbox-fs overlay # reads from disk, writes ephemeral
platter --sandbox --sandbox-allow-url "https://api.example.com" # allow network to prefix
Filesystem modes
| Mode | Reads | Writes | Use case |
|---|---|---|---|
memory |
Virtual only | Virtual only | Maximum isolation, no disk access at all |
readwrite (default) |
Real disk | Real disk | Sandboxed execution with real file access |
overlay |
Real disk | In-memory (ephemeral) | Explore files without risk of modification |
Network access
Network access is disabled by default. Use --sandbox-allow-url (repeatable) to allow access to specific URL prefixes. Private/loopback IPs are always denied.
platter --sandbox --sandbox-allow-url "https://api.github.com" --sandbox-allow-url "https://registry.npmjs.org"
Platter MCP Fragen
Wie füge ich Platter MCP zu Claude Code hinzu?
Führe claude mcp add platter -- docker run -i --rm ghcr.io/scriptsmith/platter:2.0.2-rc7 in deinem Terminal aus. Füge --scope user hinzu, damit der Server in jedem Projekt verfügbar ist.
Wie füge ich Platter MCP zu Cursor hinzu?
Öffne ~/.cursor/mcp.json und füge den Server unter mcpServers hinzu, mit der Cursor-Config aus dem Installationsabschnitt oben.
Welche Tools bietet Platter MCP?
Er stellt 3 Tools bereit, darunter bearer, jwks, none.
Is the JavaScript tool sandboxed?
No, the JavaScript tool is never sandboxed and is not a security sandbox.
How can I restrict file access?
You can use the --allow-path flag to restrict file-accessing tools to specific directory trees.
What authentication modes are supported?
Platter supports OAuth 2.1, Bearer tokens, JWKS (external OIDC), and no authentication.