Skip to main content
Glama
Redis MCP Server

Redis MCP Server

by minivv
README.md
# Redis MCP Server

A Model Context Protocol (MCP) server for Redis that keeps every command honest about *where* it runs and *what* it is allowed to do there. Three tools, an environment tag on every connection, and a web console for everything that does not belong in a chat.

---

## English

### Why This Server?

Every command an agent sends lands in a specific Redis instance — a development cache it is free to flush, or the one a running service depends on. This server makes that context part of the protocol:

1. **Where am I?** Every connection carries a `test` or `prod` tag, and every tool response reports it.
2. **What am I allowed to do here?** Four permission switches per tag — write, delete, admin, dangerous — enforced before the command reaches Redis. Reads are never gated.
3. **What about commands that are unsafe no matter where they run?** A small deny list that no template can unlock, plus a hard cap on how much a single call can return.

The parts that do not belong in a chat — connection management, permission templates, a command console, and a live view of what the server exposes — live in a web console.

### Features

- **Three focused tools** — `redis_query`, `redis_execute`, `redis_context`. Reads, gated writes, and context switching. Nothing else is exposed.
- **Environment tags** — every connection is `test` or `prod`; production ships read-only by default.
- **Command classification** — every command is parsed into an argv and sorted into read / write / delete / admin / dangerous, and that category decides how it is handled before anything reaches Redis.
- **Self-describing responses** — every result says which connection and environment produced it, and how much was truncated.
- **Bounded output** — results are capped at 200 items by default, `limit` goes up to 2000, so a wide `SCAN` or `LRANGE` cannot blow up a context window.
- **Always-denied commands** — `KEYS`, subscriptions, transaction blocks, and `MONITOR` are refused with a reason and an alternative.
- **Web console** — connection CRUD, permission templates, a command tester, and the live policy in four tabs. Chinese / English switch included.
- **Password encryption** — saved passwords are AES-256-GCM encrypted with a per-installation key.

### Quick Start

```bash
git clone https://github.com/minivv/redis-mcp-server.git
cd redis-mcp-server
npm install
npm run build
node build/index.js
```

The server speaks MCP over stdio and starts a web console on `http://localhost:3457`.

### Configure Your MCP Client

```json
{
  "mcpServers": {
    "redis": {
      "command": "node",
      "args": ["/absolute/path/to/redis-mcp-server/build/index.js"],
      "env": {
        "REDIS_HOST": "127.0.0.1",
        "REDIS_PORT": "6379",
        "REDIS_ENV": "test"
      }
    }
  }
}
```

Any connection you add through the web console is available to the MCP process immediately — no restart. The MCP process re-reads `~/.redis-mcp/connections.json` on every call and reconnects when the active connection, its credentials, its database, **or its environment tag** changes.

### Tools

#### `redis_query`

Read-only channel.

```json
{ "command": "SCAN 0 MATCH user:* COUNT 50", "limit": 100 }
```

A command that is not read-only is rejected here with the note to use `redis_execute` instead — the tool tells you the category it was classified into.

```json
{
  "connection": "cache-dev",
  "env": "test",
  "envLabel": "测试库",
  "readOnly": false,
  "allowedOps": ["write", "delete", "admin"],
  "database": 2,
  "command": "SCAN",
  "operation": null,
  "count": 3,
  "truncated": false,
  "maxItems": 200,
  "result": ["4", ["user:42", "user:43", "user:44"]]
}
```

#### `redis_execute`

Write, delete, admin, and dangerous commands — gated by the active connection's environment template.

```json
{ "command": "SET session:42 active" }
```

```json
{
  "connection": "cache-prod",
  "env": "prod",
  "envLabel": "正式库",
  "readOnly": true,
  "allowedOps": [],
  "database": 0,
  "command": "SET",
  "operation": "write",
  "result": "OK"
}
```

When the template does not allow it, the call fails with an explanation instead of reaching Redis:

```
正式库(env=prod)不允许 写入(SET / HSET / LPUSH / ZADD / RENAME 等) 操作,已拦截命令 "SET"。
如需放开,请到 Web UI 的「权限配置」中调整该标识对应的模板。
```

#### `redis_context`

Look around, switch database, or switch connection.

```json
{}
```

```json
{
  "connection": "cache-dev",
  "env": "test",
  "envLabel": "测试库",
  "readOnly": false,
  "allowedOps": ["write", "delete", "admin"],
  "host": "127.0.0.1",
  "port": 6379,
  "database": 2,
  "databases": 16,
  "savedConnections": [
    { "name": "cache-dev", "host": "127.0.0.1", "port": 6379, "db": 2, "env": "test" }
  ]
}
```

- `{ "database": 0 }` — switch the database index (the count comes from the instance's `databases` config, not a hardcoded 0–15).
- `{ "connection": "cache-dev" }` — switch to a saved connection and reconnect. The environment tag travels with the connection, and only the calling MCP process is affected.

### Web Console

| Tab | What it does |
| --- | --- |
| Connections | Add, edit, rename, test, activate, delete. Each card shows the host, database, and environment badge. |
| Permissions | Two templates (test / prod) × four switches. Change a template once and every connection with that tag follows. |
| Query | Run one command per line and see every result. Same validation as a tool call. |
| Tools & Policy | The three tool signatures, the operation categories, the deny list, and the result limits, read live from the server. |

![Connection management](assets/console.png)

![Permission templates](assets/permissions.png)

### Environment Permissions

Permissions are bound to the environment tag, not to a single connection.

| Category | Example commands | `test` default | `prod` default |
| --- | --- | :---: | :---: |
| read | `GET` `HGETALL` `LRANGE` `SMEMBERS` `SCAN` `INFO` | always | always |
| write | `SET` `HSET` `LPUSH` `ZADD` `RENAME` | on | off |
| delete | `DEL` `UNLINK` `EXPIRE` `LPOP` `ZREM` | on | off |
| admin | `CONFIG` `CLIENT` `CLUSTER` `SAVE` `REPLICAOF` | on | off |
| dangerous | `FLUSHALL` `FLUSHDB` `SHUTDOWN` `EVAL` `FUNCTION` `DEBUG` | **off** | off |

`dangerous` is off even in `test`: a wiped development cache still costs someone an afternoon.

#### Always denied

These are refused regardless of template, because they are unsafe in a one-command-per-call protocol:

| Command | Why |
| --- | --- |
| `KEYS` | Blocks the event loop. Use `SCAN` with a cursor. |
| `SUBSCRIBE` `PSUBSCRIBE` `SSUBSCRIBE` `UNSUBSCRIBE` `PUNSUBSCRIBE` | Puts the shared connection into subscriber mode, after which ordinary commands fail. |
| `MULTI` `EXEC` `DISCARD` `WATCH` `UNWATCH` | The server issues one command per call; a half-open transaction would poison the connection. |
| `MONITOR` `HELLO` `RESET` `AUTH` | Never appropriate for a tool call — use the connection settings instead. |

### Configuration Files

| File | Contents |
| --- | --- |
| `~/.redis-mcp/connections.json` | Saved connections, each with `env`, and the active connection. |
| `~/.redis-mcp/permissions.json` | The two permission templates. Created on first run. |
| `~/.redis-mcp/.key` | AES-256-GCM key for saved passwords (mode `0600`). |

All three are written atomically: a temporary file replaces the old one, so an interrupted write leaves the previous configuration intact.

### Environment Variables

| Variable | Default | Purpose |
| --- | --- | --- |
| `REDIS_HOST` | `localhost` | Host for the fallback connection. |
| `REDIS_PORT` | `6379` | Port. |
| `REDIS_PASSWORD` | — | Password. |
| `REDIS_USERNAME` | — | ACL username. |
| `REDIS_DB` | `0` | Database index. |
| `REDIS_TLS` | `false` | Enable TLS. |
| `REDIS_ENV` | `prod` | Environment tag for the fallback connection. Unknown values are treated as `prod`. |
| `MCP_WEB_PORT` | `3457` | Web console port. |
| `MCP_OPEN_BROWSER` | `false` | Open the console in a browser on start. |

### Security

- Read the environment matrix as a safety rail, not a sandbox. The real boundary is Redis ACLs: give the account it uses only the commands it needs.
- The deny list is enforced in code and is not configurable through any tool.
- A second MCP instance started while the console port is taken still works — it prints a notice and keeps following the active connection from the config file.
- Passwords are encrypted at rest; tool responses never contain credentials.

### Development

```bash
npm run dev    # build and run
npm run build  # type-check and emit to build/
```

The whole server lives in `src/index.ts`: command classification, permission model, MCP tool handlers, HTTP API, and the embedded console.

### License

MIT

---

## 中文

### 为什么用它

agent 发出的每一条命令都落在某个具体的 Redis 上——它可以随手清空的开发缓存,或者线上服务正在依赖的那一个。这个服务把「在哪儿」变成协议的一部分:

1. **我在哪?** 每个连接带 `test` / `prod` 标识,每次工具返回都会报出当前所处环境。
2. **这里允许我做什么?** 每个标识四项权限开关——写入、删除、管理、高危——在命令到达 Redis 之前就拦下。只读命令永远不受限制。
3. **有些命令在哪跑都不该允许,怎么办?** 一份任何模板都解不开的拒绝清单,加上单次调用结果的硬性上限。

不适合塞进对话里的东西——连接管理、权限模板、命令控制台、当前到底暴露了什么——都放在 Web 控制台里。

### 功能特性

- **三个聚焦的工具** —— `redis_query`、`redis_execute`、`redis_context`,分别是只读通道、受门控的写入通道、上下文切换。除此之外不暴露任何入口。
- **环境标识** —— 每个连接都是 `test` 或 `prod`,正式库默认只读。
- **按命令归类** —— 每条命令先解析成 argv,判定为 read / write / delete / admin / dangerous,再由这个类别决定怎么处理,然后才发往 Redis。
- **自描述的返回** —— 每次结果都说明是哪个连接、哪个环境、截断了多少。
- **结果有上限** —— 默认最多 200 项,`limit` 上限 2000,`SCAN`、`LRANGE` 不会撑爆上下文。
- **始终拒绝的命令** —— `KEYS`、订阅、事务块、`MONITOR` 会被拒绝,并给出原因和替代方案。
- **Web 控制台** —— 连接增删改、权限模板、命令测试、实时策略,四个标签页,中英切换。
- **密码加密** —— 保存的密码用每套安装独立的密钥做 AES-256-GCM 加密。

### 快速开始

```bash
git clone https://github.com/minivv/redis-mcp-server.git
cd redis-mcp-server
npm install
npm run build
node build/index.js
```

服务通过 stdio 提供 MCP,同时在 `http://localhost:3457` 启动 Web 控制台。

### 配置 MCP 客户端

```json
{
  "mcpServers": {
    "redis": {
      "command": "node",
      "args": ["/绝对路径/redis-mcp-server/build/index.js"],
      "env": {
        "REDIS_HOST": "127.0.0.1",
        "REDIS_PORT": "6379",
        "REDIS_ENV": "test"
      }
    }
  }
}
```

在 Web 控制台里新建的连接对 MCP 进程立即可用,不用重启。MCP 进程每次调用都会重新读取 `~/.redis-mcp/connections.json`,当激活连接、账号密码、库序号**或环境标识**发生变化时自动重连。

### 工具

#### `redis_query`

只读通道。

```json
{ "command": "SCAN 0 MATCH user:* COUNT 50", "limit": 100 }
```

非只读命令会在这里被拒绝,并提示改用 `redis_execute`,同时告诉你它被归到了哪一类。

```json
{
  "connection": "cache-dev",
  "env": "test",
  "envLabel": "测试库",
  "readOnly": false,
  "allowedOps": ["write", "delete", "admin"],
  "database": 2,
  "command": "SCAN",
  "operation": null,
  "count": 3,
  "truncated": false,
  "maxItems": 200,
  "result": ["4", ["user:42", "user:43", "user:44"]]
}
```

#### `redis_execute`

写入、删除、管理、高危命令——受当前连接的环境模板门控。

```json
{ "command": "SET session:42 active" }
```

模板不允许时,调用直接失败并说明原因,命令不会到达 Redis:

```
正式库(env=prod)不允许 写入(SET / HSET / LPUSH / ZADD / RENAME 等) 操作,已拦截命令 "SET"。
如需放开,请到 Web UI 的「权限配置」中调整该标识对应的模板。
```

#### `redis_context`

查看上下文、切库、切换连接。

- 不带参数:返回当前连接、环境标识、库序号、该环境放行的操作类别、已保存连接列表。
- `{ "database": 0 }`:切换库序号(范围取自实例的 `databases` 配置,不是写死的 0–15)。
- `{ "connection": "cache-dev" }`:切换到已保存的连接并重连。环境标识跟着连接走,且只影响当前 MCP 进程。

### Web 控制台

| 标签页 | 用途 |
| --- | --- |
| 连接管理 | 新增、编辑、重命名、测试、激活、删除。卡片上直接显示地址、库序号和环境徽章。 |
| 权限配置 | 测试库 / 正式库两套模板 × 四项开关。改一次模板,所有使用该标识的连接立即生效。 |
| 查询测试 | 一行一条命令,逐条显示结果。校验规则与工具调用完全一致。 |
| 工具与策略 | 三个工具的参数、操作类别、拒绝清单、结果上限,全部从服务端实时读取。 |

![连接管理](assets/console.png)

![权限模板](assets/permissions.png)

### 环境权限

权限绑在环境标识上,不是绑在单个连接上。

| 类别 | 示例命令 | `test` 默认 | `prod` 默认 |
| --- | --- | :---: | :---: |
| 读取 | `GET` `HGETALL` `LRANGE` `SMEMBERS` `SCAN` `INFO` | 总是允许 | 总是允许 |
| 写入 | `SET` `HSET` `LPUSH` `ZADD` `RENAME` | 开 | 关 |
| 删除 | `DEL` `UNLINK` `EXPIRE` `LPOP` `ZREM` | 开 | 关 |
| 管理 | `CONFIG` `CLIENT` `CLUSTER` `SAVE` `REPLICAOF` | 开 | 关 |
| 高危 | `FLUSHALL` `FLUSHDB` `SHUTDOWN` `EVAL` `FUNCTION` `DEBUG` | **关** | 关 |

`高危` 在测试库也默认关闭:清掉一个开发缓存,同样会让人搭进去一下午。

#### 始终拒绝的命令

无论模板怎么配,这些命令都会被拒绝,因为它们在「一次调用一条命令」的协议里本身就不安全:

| 命令 | 原因 |
| --- | --- |
| `KEYS` | 阻塞 Redis 主线程。改用 `SCAN` 游标遍历。 |
| `SUBSCRIBE` `PSUBSCRIBE` `SSUBSCRIBE` `UNSUBSCRIBE` `PUNSUBSCRIBE` | 会把共享连接切进订阅模式,之后的普通命令都会失败。 |
| `MULTI` `EXEC` `DISCARD` `WATCH` `UNWATCH` | 服务一次调用只发一条命令,半开的事务会污染连接。 |
| `MONITOR` `HELLO` `RESET` `AUTH` | 不适合出现在工具调用里,请改用连接配置。 |

### 配置文件

| 文件 | 内容 |
| --- | --- |
| `~/.redis-mcp/connections.json` | 已保存的连接(每个都带 `env`)以及当前激活的连接。 |
| `~/.redis-mcp/permissions.json` | 两套权限模板,首次运行自动创建。 |
| `~/.redis-mcp/.key` | 保存密码用的 AES-256-GCM 密钥(权限 `0600`)。 |

三者都是原子写入——临时文件直接替换旧文件,写到一半中断也不会损坏原有配置。

### 环境变量

| 变量 | 默认值 | 用途 |
| --- | --- | --- |
| `REDIS_HOST` | `localhost` | 兜底连接的主机。 |
| `REDIS_PORT` | `6379` | 端口。 |
| `REDIS_PASSWORD` | — | 密码。 |
| `REDIS_USERNAME` | — | ACL 用户名。 |
| `REDIS_DB` | `0` | 库序号。 |
| `REDIS_TLS` | `false` | 启用 TLS。 |
| `REDIS_ENV` | `prod` | 兜底连接的环境标识,无法识别的值一律按 `prod` 处理。 |
| `MCP_WEB_PORT` | `3457` | Web 控制台端口。 |
| `MCP_OPEN_BROWSER` | `false` | 启动时自动打开浏览器。 |

### 安全

- 把环境矩阵当成安全带,不是沙箱。真正的边界是 Redis ACL:给这个账号只发它需要的命令。
- 拒绝清单写死在代码里,任何工具都改不了。
- 控制台端口被占用时再启动一个实例仍然可用:它会打印提示,并继续跟随配置文件里的激活连接。
- 密码加密存储,工具返回里不会出现凭据。

### 开发

```bash
npm run dev    # 构建并运行
npm run build  # 类型检查并输出到 build/
```

整个服务都在 `src/index.ts` 里:命令归类、权限模型、MCP 工具处理、HTTP API、以及内嵌的控制台。

### License

MIT

TDQS

A4.1/5.0

Scored across 3 tools

Disambiguation5/5

The three tools have clearly distinct roles: redis_query is strictly read-only, redis_execute handles writes/deletes/admin/high-risk commands, and redis_context manages connection/database context. Boundary is reinforced by server-side read-only enforcement and rejection messages directing callers to the right tool.

Naming Consistency4/5

All tools use the redis_ prefix and are readable, giving a predictable grouping. However, query and execute are verbs while context is a noun, so the convention is slightly mixed but still intuitive.

Tool Count5/5

Three tools are well-scoped for a Redis MCP server: read, write/admin, and context management cover the main interaction modes without redundancy. Each tool earns its place and there is no obvious tool bloat.

Completeness4/5

The surface covers read-only queries, write/admin commands, and context switching/listing, which are the core Redis operations an agent needs. Minor gaps exist around saved-connection lifecycle management (create/delete saved connections) and possibly transaction/pipeline workflows, but agents can work around these.

Maintenance

ActivityMaintained
ResponsivenessOutdated data