A local-first MCP layer for scoped access to files, vaults, and tools.
mvmt runs as a local MCP server between your data sources and your clients. You choose which folders, vaults, memory palaces, and tools are exposed, with read/write access controlled per source.
- One server, every client — Claude, Cursor, Codex, VS Code, and any MCP-compatible tool connect to a single local endpoint.
- Read-only by default — write access is opt-in per connector. Nothing writes unless you said so.
- Scoped, not open — choose exact folders, Obsidian vaults, and MemPalace paths. No full-disk access, no guessing.
- Secure out of the box — bearer-token auth, origin checks, environment scrubbing, audit log, and an optional pattern-based redactor for configured patterns.
- Tunnel-ready — expose mvmt to cloud clients like claude.ai over public HTTPS, with OAuth/PKCE for web clients.
Warning
Remote access is authenticated, but it still exposes your configured local tools beyond your machine. Keep connector scopes narrow before exposing mvmt over a tunnel.
npm install -g mvmt
mvmt serve -iOn first run, mvmt serve walks you through folders, connectors, plugins, and local-only vs tunnel access, then starts mvmt in the foreground.
For a one-off read-only folder without touching your saved config:
mvmt serve --path ~/Documents -iFor source installs, connector setup, client tokens, and troubleshooting, see the Setup Guide.
| Area | Status |
|---|---|
| Local filesystem folders | supported, read-only by default |
| Native Obsidian connector | supported, read-only by default |
| MemPalace connector setup | supported as stdio proxy, read-only by default |
| Local Streamable HTTP | supported |
| Stdio mode | supported |
| Interactive start mode | supported |
| Built-in pattern-based redactor plugin | supported, opt-in during mvmt config setup or first mvmt serve |
| Tunnel mode | supported for personal remote access; quick tunnel URLs are temporary |
| Managed remote relay / per-client remote access | not in v0 |
| HTTP proxy write gates | incomplete; advanced/manual config only |
| Client | Transport | Status | Auth method | Known issues |
|---|---|---|---|---|
| Claude Desktop | stdio | supported | process launch, no HTTP bearer token | Runs its own mvmt process per config |
| Claude Code | Streamable HTTP | supported | bearer token header | Refresh only after mvmt token rotate |
| Codex CLI | Streamable HTTP | supported | bearer token env var | Start Codex from a shell where the token env var is set |
| Cursor | Streamable HTTP | expected | bearer token header | Client behavior may vary by Cursor MCP version |
| VS Code / Copilot | Streamable HTTP | expected | bearer token header | Client behavior may vary by MCP extension/version |
| claude.ai / ChatGPT web | public HTTPS tunnel | supported remote mode | OAuth/PKCE over tunnel | Requires a public HTTPS URL; the client must either use dynamic client registration or have its exact redirect_uri pre-registered |
| Raw HTTP/curl | Streamable HTTP | debug only | bearer token header | Must follow MCP session initialization rules |
Every file and data access in mvmt is gated. There is no open mode.
- HTTP mode binds to
127.0.0.1, not0.0.0.0. - HTTP requests to
/mcpand/healthrequire a bearer token. - The bearer token is stored at
~/.mvmt/.session-token, reused across restarts, and rotated explicitly withmvmt token rotate. - Browser requests from non-localhost origins are rejected unless allowlisted.
- Write access is opt-in per connector.
- Stdio child processes receive a scrubbed environment.
- Optional pattern-based redactor can warn, redact, or block configured regex matches in tool results.
- Tool calls are appended to
~/.mvmt/audit.log.
Not yet enforced: TLS on localhost, per-client tokens, rate limiting, and full write gates for HTTP proxy connectors.
- Setup guide
- Client setup
- Configuration
- Connectors
- Plugins
- Remote access
- Audit log
- Troubleshooting
- Architecture
- Security policy
- Security memo
- Personal memo
- Contributing
- Changelog
Most MCP clients let you add servers through their settings UI. You need two things:
- URL:
http://127.0.0.1:4141/mcp - Authorization header:
Bearer <token from mvmt token>
Claude Desktop is the exception — it uses stdio mode and launches mvmt directly, so no token is needed.
Remote web clients (ChatGPT, claude.ai) authenticate with OAuth 2.1 + PKCE. mvmt implements RFC 7591 Dynamic Client Registration as the primary path, and OpenAI's auth guide says ChatGPT supports it. In practice, if a web client does not call /register, you can still pre-register its exact redirect_uri manually. mvmt persists registrations to ~/.mvmt/.clients.json. The issued access token is bound to the resource via the aud claim, so a token minted for one mvmt instance cannot be replayed against another.
If your web client does not support DCR, pre-register it manually by POSTing to /register once (see Client Setup for the curl example). Either way, an /authorize request with an unknown redirect_uri is rejected.
See Client Setup for step-by-step instructions for Claude Desktop, Claude Code, Codex CLI, Cursor, VS Code, and raw HTTP.
mvmt config setup writes ~/.mvmt/config.yaml, and the first mvmt serve run creates it automatically if it does not exist yet. The config controls four things:
server— port, allowed origins, and whether to start a tunnel for public access.proxy— external MCP servers that mvmt proxies (e.g. filesystem and MemPalace).obsidian— the native Obsidian vault connector.plugins— security plugins that inspect tool results before they reach clients (e.g. the pattern-based redactor).
You should not need to write this file by hand. To re-run setup, use mvmt config setup. To inspect it, run mvmt config. To validate it, run mvmt doctor.
See Configuration for the full schema reference, field descriptions, and editing instructions.
| Command | Description |
|---|---|
mvmt serve |
Configure mvmt if needed, then start the MCP server |
mvmt doctor |
Validate config and check connector health |
mvmt config |
Show the saved mvmt config |
mvmt config setup |
Run guided setup and save mvmt config |
mvmt token |
Show the current bearer token and age |
mvmt token rotate |
Generate a new bearer token and print it |
mvmt tunnel |
Show tunnel status |
mvmt tunnel config |
Choose a different tunnel and save it to config |
mvmt tunnel start |
Start the configured tunnel for the running mvmt process |
mvmt tunnel refresh |
Restart the configured tunnel and print the new URL |
mvmt tunnel stop |
Stop public tunnel exposure without stopping mvmt |
mvmt tunnel logs |
Show recent tunnel output |
mvmt tunnel logs stream |
Stream live tunnel output |
mvmt --version |
Print version and check for updates |
Prints the installed version and runs a best-effort npm update check.
mvmt --version
mvmt --version --no-update-checkUpdate checks never install anything. They are skipped when MVMT_NO_UPDATE_CHECK=1 or CI is set. Notices are written to stderr so JSON stdout stays usable.
Starts the hub.
mvmt serve
mvmt serve -i
mvmt serve --path ~/Documents
mvmt serve --port 4142
mvmt serve --config ~/.mvmt/config.yaml
mvmt serve --stdioOptions:
| Flag | Description |
|---|---|
--port <n> |
Override config.server.port |
--config <p> |
Use a specific config file |
--path <dir> |
Temporarily expose a filesystem folder as read-only for this run only (repeatable) |
--stdio |
Serve MCP over stdio instead of HTTP |
--interactive, -i |
Start an interactive control prompt |
--verbose |
Print more startup details |
Behavior:
- If no saved config exists,
mvmt serveruns guided setup first, saves config, then starts. - If a saved config exists,
mvmt servestarts immediately. mvmt serve --path ...uses a temporary read-only filesystem config for that run only and does not modify the saved config.
HTTP mode:
- Binds to
127.0.0.1. - Reuses the existing bearer token if one already exists.
- Writes the token to
~/.mvmt/.session-tokenwith mode600. - Requires the token for
/mcpand/health.
Stdio mode:
- Used by clients that launch mvmt directly.
- Does not use bearer-token auth because there is no HTTP listener.
- Skips update checks because stdout is reserved for MCP protocol messages.
Interactive mode:
- Run
mvmt serve -i. - Keeps mvmt in the foreground with a prompt at the bottom.
- Uses the same grouped commands as the top-level CLI for config, token, and tunnel operations.
- Live logs show connector, tool name, argument keys, duration, and error state without printing full argument values.
Interactive command shape:
> config
> config setup
> token
> token rotate
> tunnel
> tunnel config
> tunnel start
> tunnel refresh
> tunnel stop
> tunnel logs
> tunnel logs stream
> logs
> logs on
> logs off
Shows the saved mvmt config in a readable summary.
mvmt config
mvmt config --config ~/.mvmt/config.yamlUse mvmt config setup to rerun guided setup and overwrite the saved config explicitly.
Validates the local install, config, and enabled connectors.
mvmt doctor
mvmt doctor --json
mvmt doctor --config ~/.mvmt/config.yaml
mvmt doctor --timeout-ms 20000Checks include:
- Package version and update availability.
- Config file existence.
- Config schema validation.
- Config file permissions.
- Server port and allowed origins.
- Enabled filesystem connector startup and tool listing.
- Enabled Obsidian connector startup and tool listing.
mvmt doctor exits with status 0 when config is valid and all enabled connectors are healthy. It exits with status 1 when config is missing, invalid, or any enabled connector fails health checks.
Manages the HTTP bearer token used by /mcp and /health.
mvmt token
mvmt token rotatemvmt token prints the current token, age, and file path. mvmt token rotate writes a new token to ~/.mvmt/.session-token and prints it. Running HTTP servers validate against the token file on each request, so rotation takes effect immediately. Any connected client that stored the old token must be updated, and existing OAuth access tokens are revoked immediately.
Normal mvmt serve restarts reuse the same root token. OAuth access tokens minted from that root token remain valid across restart as long as the advertised resource URL stays the same; they still expire normally, and mvmt token rotate revokes them immediately.
mvmt token show remains a hidden compatibility alias for raw token output.
Shows tunnel config and live runtime status.
mvmt tunnel
mvmt tunnel config
mvmt tunnel start
mvmt tunnel refresh
mvmt tunnel stop
mvmt tunnel logs
mvmt tunnel logs streammvmt tunnel config updates the saved tunnel config and, if mvmt is already running, applies it immediately. mvmt tunnel logs prints recent buffered tunnel output. mvmt tunnel logs stream follows live tunnel output from the running mvmt process.
A connector is the code that gives mvmt access to one local data source or tool surface. It owns discovery, permissions, tool definitions, tool execution, and cleanup for that source.
mvmt currently supports three connector setups. All are read-only by default with opt-in write access.
Obsidian — native connector that reads markdown files directly from a vault. Tools: search_notes, read_note, list_notes, list_tags, and append_to_daily (write, opt-in). Path traversal is blocked; symlinks are skipped.
Filesystem — proxies the official @modelcontextprotocol/server-filesystem MCP server as a stdio child process. When writeAccess: false, mvmt hides write tools from listTools and rejects them at callTool.
MemPalace — proxies the local MemPalace MCP server as a stdio child process. Guided setup tries to detect your mempalace command and palace path. When writeAccess: false, mvmt hides known MemPalace write tools such as drawer creation, tunnel deletion, KG mutation, hook settings, and diary writes.
Tools from all connectors are prefixed with the connector ID (e.g. obsidian__search_notes, proxy_filesystem__read_file, proxy_mempalace__mempalace_search) to avoid name collisions.
To add a native connector in v0, implement the Connector interface, add config schema for its scope, wire it into startup, and add tests for path/scope/write behavior. See Connectors for the implementation checklist.
A plugin is a post-processing hook that runs after a connector returns a tool result and before that result is sent back to the MCP client. Plugins can inspect, annotate, transform, or block outbound tool results.
The built-in pattern-redactor plugin scans text tool results with regex patterns and can warn, redact, or block matches. Default patterns cover common API keys (OpenAI, Anthropic, AWS, GitHub, Slack) and JWT-looking strings.
Warning
This is a best-effort pattern matcher, not a security control. If data must not reach AI tools, scope the connector to exclude it.
To add a plugin in v0, implement the ToolResultPlugin interface, add config schema, register it in the plugin factory, and make audit events explicit when it changes output. See Plugins for the implementation checklist.
Every file and data access in mvmt is gated. There is no open mode.
- Localhost bind — HTTP listens on
127.0.0.1only. - Bearer token — 256-bit, stored at
~/.mvmt/.session-token, reused across restart, constant-time validation, rotatable without restart. - Origin allowlist — browser requests from non-localhost origins are rejected unless explicitly allowed.
- Environment scrubbing — stdio child processes receive only an allowlist of env vars.
- Write gates — read-only by default per connector; write tools are hidden and rejected unless enabled.
- Pattern redactor — opt-in regex scrubbing of tool results before they reach clients.
- Audit log — every tool call appended to
~/.mvmt/audit.logas JSONL with mode600.
Not yet enforced: TLS on localhost, per-client connector scoping, and write gates for HTTP proxy connectors.
See Security Memo for design notes and Audit Log for log format and queries.
mvmt is local-first. Cloud clients like claude.ai cannot reach 127.0.0.1 directly. mvmt config setup and mvmt tunnel config can configure a tunnel that gives you a public HTTPS URL.
Quick tunnels are temporary, which means you lose the URL when mvmt is shut down. Use a named tunnel or reserved domain to keep the same URL.
Recommended quick tunnel: Cloudflare. For stable hostnames such as pnee.example.com, use a Cloudflare named tunnel; mvmt tunnel config and interactive tunnel config can save that custom command and public URL.
Warning
Remote web clients authorize with OAuth/PKCE. Direct HTTP clients use bearer tokens. Auth controls who connects; connector scope controls what they can access.
Important
mvmt only redirects OAuth authorization codes to registered callback URLs and binds issued tokens to the requested resource via the aud claim. Dynamic Client Registration is the preferred path; if a web client does not call /register in practice, pre-register its exact redirect_uri first.
Remote access checklist:
- Use Cloudflare Tunnel when possible.
- Expose the smallest useful folder, vault, or connector scope.
- Keep write access disabled unless you explicitly need it.
- Do not expose secrets, credential folders, home directories, production databases, or browser profiles.
- Watch the audit log when using remote clients.
- Stop the tunnel when you are done with remote access.
See Remote Access for tunnel providers, runtime management, and safety guidelines.
See Troubleshooting for common issues: port conflicts, connector failures, missing tools, vault detection, and token rejection.
Planned work is focused on safer long-running use and better local data coverage:
- Fast file indexer with Chroma's embedded JS/TS version.
- Full key management: named keys, rotation, revocation, expiration.
- Per-client permissions and connector scoping.
- Runtime permission changes for folders, vaults, and connector write access.
- Remote access hardening guides for Cloudflare Named Tunnels, Cloudflare Access, and rate limiting.
- SQLite connector with per-table read/write permissions.
- Atomic writes and optional
--previewmode. - Git connector for local history, diffs, blame, and branch-aware search.
Contributions are welcome while the project is early. Keep changes focused and security-conscious. Read CONTRIBUTING.md and report vulnerabilities through SECURITY.md.
MIT
