- Default-deny. Sensitive and dangerous tool tiers are off until explicitly
enabled. The shell tool is ON by default with a wildcard allowlist; use
exec.shell_deny_patternsto block specific commands if needed. - Never expose without a token. Binding a non-loopback address without
auth.tokenis a startup error, not a warning. Tunnels additionally requireauth.require: true(tunnel traffic arrives from loopback, which is exempt by default);termux-mcp tunnel startrefuses to run otherwise. - Least privilege per path. File tools run inside a resolved-path sandbox; every command runs with a timeout and an output cap.
| Concern | Control |
|---|---|
| Transport auth | Bearer token, constant-time comparison (internal/auth) |
| Tool gating | Permission tiers + per-tool allow/deny (internal/registry) |
| Shell | Regex allow/deny; must be explicitly enabled (exec.shell_allowed) |
| Files | Path sandbox under tools.file_roots, symlink resolution |
| Command safety | Timeouts (default 30s), output caps (1 MiB), retry-once JSON validation |
| Observability | JSONL audit log with argument redaction (internal/audit) |
| Secrets | Never logged; config chmod 600; termux-mcp get_config is sanitized |
| DoS | Max body size, max sessions, rate-limit-ready middleware |
Arguments named like text, content, message, token, password,
secret, key, pin, otp, authorization, body are replaced with
[REDACTED] in the audit trail; values over 200 chars are truncated.
termux-mcp token new --writeand keep the config file private.- Keep
tools.enable_sensitiveandtools.enable_dangerousoff unless needed; prefer narrowtools.allowlists. - Restart the server after any config change.
- Check
audit.jsonlperiodically. - OAuth 2.1 + PKCE is a planned future upgrade for public deployments.
Any exposed device on a public tunnel without a token is a misconfiguration — the server refuses to start in that state. If you find a bug, open an issue in the repository.