Skip to main content
Deploying to Vercel? Consider Vercel KV for edge-compatible storage without managing Redis infrastructure.

Requirements

Development Setup

Projects created with frontmcp create --target node include Docker files in the ci/ folder:
When running inside Docker, use redis (the service name) as REDIS_HOST, not localhost. Projects created with frontmcp create include a ci/.env.docker file with Docker-specific values.

Option 2: Local Installation

Configuration

Already configuring the top-level redis block (or redis.provider: 'vercel-kv') on @FrontMcp? Set CachePlugin.init({ type: 'global-store' }) so the plugin automatically reuses that store without duplicating credentials.
For complete CachePlugin API documentation, see the Cache Plugin Guide.

Production Setup

Redis is required in production. Without Redis, session data will be lost on restart and caching will not persist across instances.

Self-Hosted Production

For self-hosted Redis in production:

Security Best Practices

  1. Authentication: Always set REDIS_PASSWORD in production
  2. Network: Run Redis in private network, not exposed to internet
  3. TLS: Enable TLS for encrypted connections
  4. Persistence: Use AOF for durability (appendonly yes)

Configuration Example

Switch the redis block to { provider: 'vercel-kv' } when deploying on Vercel KV—the Cache Plugin will keep reusing the same store without code changes.

Running more than one instance

Redis lets several instances share sessions, but each instance still signs and encrypts with its own secrets. Give every instance the same values: An anonymous session minted by one instance is honored by any instance with the same MCP_SESSION_SECRET: the instance that receives the request recreates the transport from the stored session (in distributed mode it relays to, or takes over from, the node recorded with that session).

When Redis is unreachable at startup

Not every Redis consumer reacts the same way when Redis is down as the server starts:
  • redis and transport.persistence log the failure ([TransportService] Failed to connect to redis - session persistence disabled) and the server starts. The connection is retried in the background with exponential backoff (1s doubling to 30s); once Redis is reachable, sessions are persisted again and /readyz turns healthy without a restart. Until then, sessions live on the instance that created them.
  • Every Redis connection FrontMCP opens reconnects on its own and logs connection errors at a rate-limited interval (with a count of suppressed repeats) rather than once per retry.
  • throttle.storage fails closed: rate limits are a security control, so startup aborts with GuardStorageUnavailableError (throttle.storage (redis) is unavailable: …). This is the default in production, where storage fallback defaults to 'error'. If Redis goes away while the server is running, a rate-limited call is refused with the same GuardStorageUnavailableError rather than an internal error. To keep serving with per-instance counters instead, opt in explicitly (a mid-run outage then logs one warning, uses per-instance counters, and returns to Redis once it answers):
throttle.storage takes the @frontmcp/utils storage shape ({ type: 'redis', redis: { config } } or { type: 'redis', redis: { url } }), not the top-level redis shape.

Environment Variables

Redis Configuration

Plugin Secrets

In development, REMEMBER_SECRET is auto-generated and stored in .frontmcp/remember-secret.json. Add this file to .gitignore. In production, always set REMEMBER_SECRET explicitly to ensure consistent encryption across instances.

Health Checks

Troubleshooting

Connection Refused

  • Verify Redis is running: redis-cli ping
  • Check firewall rules
  • Verify host/port configuration
  • If startup fails, or rate-limited calls are refused, with GuardStorageUnavailableError, the throttle.storage backend is down; see When Redis is unreachable at startup

Clients keep re-initializing or tools repeat their questions

  • A 404 for a session the client just used, on a load-balanced deployment, means the instances run with different MCP_SESSION_SECRET values
  • A 2026-07-28 tool that asks its first question again after it was answered, with mcp-20260728: rejected requestState and reason: 'bad-signature' in the log, means VAULT_SECRET (or JWT_SECRET) is unset or differs between instances

Authentication Failed

  • Ensure REDIS_PASSWORD matches server config
  • Check for special characters in password (may need URL encoding)

Memory Issues

  • Set maxmemory and maxmemory-policy in Redis config
  • Monitor with redis-cli INFO memory

Docker Network Issues

When using Docker Compose, the app container should use redis as the hostname (the service name), not localhost: