MentisDB works well as a local daemon, but the more interesting deployment is a remote memory server: one EC2 instance, many coding agents, shared durable chains, and MCP clients connecting from laptops or other hosts.
A remote deployment changes the security model. If the MCP port is reachable from the internet, every request must authenticate before it can read or mutate memory. This guide walks through a simple Ubuntu EC2 setup, the AWS security group rules, the systemd service, and global or chain-scoped bearer tokens.
Short version: expose only TLS ports, restrict security-group sources to your own
IPs, set MENTISDB_BEARER_TOKEN_ACCESS=true, create scoped tokens for
users and agents, and keep global tokens for administrators.
| Surface | Default Port | Expose Publicly? | Use |
|---|---|---|---|
| SSH | 22 | Admin IP only | Server maintenance |
| HTTPS MCP | 9473 | Client IPs only | Remote MCP clients such as Codex, Claude Code, or mcp-remote |
| HTTPS REST | 9474 | Optional, trusted IPs only | Direct REST integrations |
| HTTPS Dashboard | 9475 | Admin IP only | Chains, agents, skills, bearer tokens, settings |
| HTTP MCP | 9471 | No | Local-only or private-network use |
| HTTP REST | 9472 | No | Local-only or private-network use |
You can run HTTP and HTTPS at the same time, but on a public cloud host the security group should normally expose only the TLS ports you actually need.
SSH into the instance:
ssh -i ~/.ssh/your-key.pem ubuntu@YOUR_EC2_PUBLIC_IP
In the EC2 console, open the instance security group and add inbound rules like this. Replace the source CIDRs with your real office, home, VPN, or client IPs.
| Type | Protocol | Port | Source | Why |
|---|---|---|---|---|
| SSH | TCP | 22 | YOUR_ADMIN_IP/32 | Admin access |
| Custom TCP | TCP | 9473 | YOUR_CLIENT_IP/32 | HTTPS MCP |
| Custom TCP | TCP | 9475 | YOUR_ADMIN_IP/32 | HTTPS dashboard |
| Custom TCP | TCP | 9474 | TRUSTED_API_IP/32 | Optional HTTPS REST |
Do not open 9471 or 9472 to 0.0.0.0/0. If you need
wide access while traveling, put a VPN or SSH tunnel in front of the instance
instead of publishing unauthenticated local-development ports.
Install Rust and MentisDB from crates.io:
sudo apt-get update
sudo apt-get install -y build-essential pkg-config libssl-dev curl
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
cargo install mentisdb --features local-embeddings
Install the binary somewhere systemd can find it:
sudo install -m 0755 "$HOME/.cargo/bin/mentisdb" /usr/local/bin/mentisdb
mentisdb --version
sudo useradd -r -s /usr/sbin/nologin -m -d /var/lib/mentisdb mentisdb || true
sudo mkdir -p /var/lib/mentisdb /etc/mentisdb
sudo chown -R mentisdb:mentisdb /var/lib/mentisdb
Create /etc/mentisdb/mentisdb.env. The important remote-server settings are
MENTISDB_BIND_HOST=0.0.0.0, the TLS MCP/dashboard ports, and
MENTISDB_BEARER_TOKEN_ACCESS=true.
sudo tee /etc/mentisdb/mentisdb.env > /dev/null <<'EOF'
MENTISDB_DIR=/var/lib/mentisdb
MENTISDB_DEFAULT_CHAIN_KEY=mentisdb
MENTISDB_BIND_HOST=0.0.0.0
# Keep HTTP available only if the security group blocks it from the internet.
MENTISDB_MCP_PORT=9471
MENTISDB_REST_PORT=9472
# Expose these through the security group.
MENTISDB_HTTPS_MCP_PORT=9473
MENTISDB_HTTPS_REST_PORT=9474
MENTISDB_DASHBOARD_PORT=9475
MENTISDB_DASHBOARD_PIN=change-this-admin-pin
# Required for remote or multi-user MCP servers.
MENTISDB_BEARER_TOKEN_ACCESS=true
MENTISDB_VERBOSE=true
MENTISDB_AUTO_FLUSH=true
RUST_LOG=info
EOF
sudo chown root:mentisdb /etc/mentisdb/mentisdb.env
sudo chmod 640 /etc/mentisdb/mentisdb.env
If you do not need REST from remote clients, set MENTISDB_HTTPS_REST_PORT=0
and omit port 9474 from the security group.
sudo tee /etc/systemd/system/mentisdb.service > /dev/null <<'EOF'
[Unit]
Description=MentisDB Daemon - Durable Semantic Memory Engine
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=mentisdb
Group=mentisdb
EnvironmentFile=/etc/mentisdb/mentisdb.env
ExecStart=/usr/local/bin/mentisdb
Restart=always
RestartSec=10
WorkingDirectory=/var/lib/mentisdb
StandardOutput=journal
StandardError=journal
SyslogIdentifier=mentisdb
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/mentisdb /etc/mentisdb
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable mentisdb
sudo systemctl start mentisdb
sudo systemctl status mentisdb --no-pager
MentisDB generates a self-signed TLS certificate if one does not already exist.
For production browser ergonomics you can later replace it with your own
certificate and set MENTISDB_TLS_CERT and MENTISDB_TLS_KEY.
sudo journalctl -u mentisdb -n 80 --no-pager
ss -tlnp | grep -E '9471|9472|9473|9474|9475'
curl -k https://127.0.0.1:9473/health
From your laptop, test the remote TLS MCP health endpoint:
curl -k https://YOUR_EC2_PUBLIC_DNS:9473/health
With MENTISDB_BEARER_TOKEN_ACCESS=true, MCP requests must include an
active token. Tokens are shown only once at creation time, so paste them into
your password manager or MCP client config immediately.
A global token can access every chain and server-wide MCP tools such as chain listing. Use it for administrators and trusted automation.
sudo -u mentisdb env MENTISDB_DIR=/var/lib/mentisdb \
mentisdb bearertoken create --global admin-laptop
A chain-scoped token can only interact with the chains it was granted. Use this when each user or agent should work inside a dedicated memory chain.
sudo -u mentisdb env MENTISDB_DIR=/var/lib/mentisdb \
mentisdb bearertoken create --chain alice alice-agent
A single token can also allow more than one chain. Pass --chain more
than once.
sudo -u mentisdb env MENTISDB_DIR=/var/lib/mentisdb \
mentisdb bearertoken create team-agent --chain alice --chain shared
sudo -u mentisdb env MENTISDB_DIR=/var/lib/mentisdb mentisdb bearertoken list
sudo -u mentisdb env MENTISDB_DIR=/var/lib/mentisdb mentisdb bearertoken list --chain alice
sudo -u mentisdb env MENTISDB_DIR=/var/lib/mentisdb mentisdb bearertoken remove alice-agent
Removing a token revokes it. Existing MCP clients using that token should fail on their next request.
Open the dashboard at https://YOUR_EC2_PUBLIC_DNS:9475. The header includes:
Chains | Agents | Skills | Bearer Tokens | Settings
On the Bearer Tokens page you can:
The Settings page also shows MENTISDB_BEARER_TOKEN_ACCESS
alongside the other daemon environment variables, plus a restart button for settings
that require a process restart.
In your local Codex config.toml, point the MCP server at the HTTPS MCP
endpoint and include the bearer token in the request headers.
[mcp_servers.mentisdb]
url = "https://YOUR_EC2_PUBLIC_DNS:9473"
headers = { Authorization = "Bearer mentisdb_replace_me" }
Use a global token for an administrator Codex profile. Use a chain-scoped or multi-chain token for agents that should only see particular memory chains.
Any remote MCP client must be able to send this HTTP header:
Authorization: Bearer mentisdb_replace_me
Prefer native streamable-HTTP MCP clients that support request headers directly. Here are the common harness shapes.
claude mcp add-json mentisdb \
'{"type":"http","url":"https://YOUR_EC2_PUBLIC_DNS:9473","headers":{"Authorization":"Bearer mentisdb_replace_me"}}' \
--scope user
qwen mcp add --scope user --transport http mentisdb https://YOUR_EC2_PUBLIC_DNS:9473 \
--header "Authorization: Bearer mentisdb_replace_me"
Or edit ~/.qwen/settings.json:
{
"mcpServers": {
"mentisdb": {
"httpUrl": "https://YOUR_EC2_PUBLIC_DNS:9473",
"headers": {
"Authorization": "Bearer mentisdb_replace_me"
}
}
}
}
Edit ~/.copilot/mcp-config.json:
{
"mcpServers": {
"mentisdb": {
"type": "http",
"url": "https://YOUR_EC2_PUBLIC_DNS:9473",
"headers": {
"Authorization": "Bearer mentisdb_replace_me"
},
"tools": ["*"]
}
}
}
Edit .vscode/mcp.json or your user-level mcp.json:
{
"servers": {
"mentisdb": {
"type": "http",
"url": "https://YOUR_EC2_PUBLIC_DNS:9473",
"headers": {
"Authorization": "Bearer mentisdb_replace_me"
}
}
}
}
Edit ~/.config/opencode/opencode.json:
{
"mcp": {
"mentisdb": {
"type": "remote",
"url": "https://YOUR_EC2_PUBLIC_DNS:9473",
"enabled": true,
"oauth": false,
"headers": {
"Authorization": "Bearer mentisdb_replace_me"
}
}
}
}
Edit ~/.hermes/config.yaml:
mcp_servers:
mentisdb:
url: "https://YOUR_EC2_PUBLIC_DNS:9473"
headers:
Authorization: "Bearer mentisdb_replace_me"
If your client uses a stdio bridge such as mcp-remote, confirm the bridge
version and client configuration support custom headers before giving that client
access to a bearer-token-protected remote server. With MentisDB's self-signed
certificate, Node-based bridges may also need the MentisDB certificate trusted by
the operating system or certificate verification disabled for that bridge process
only.
9473 for remote clients.MENTISDB_BEARER_TOKEN_ACCESS=true for remote and multi-user servers./var/lib/mentisdb before upgrades.sudo journalctl -u mentisdb -f.That is the whole shape: an Ubuntu service, tight firewall rules, TLS for remote transport, and bearer tokens as the MCP authorization boundary. From there you can add DNS, a trusted certificate, backups, monitoring, and eventually per-token usage stats as the deployment grows.