Skip to main content
Glama
HaokaiLau

mysql-readonly-mcp

by HaokaiLau

mysql-readonly-mcp

本项目是面向个人本机的只读 MySQL MCP Server 首版实现,默认通过 stdio 提供 6 个工具。

工具说明

工具

作用

主要参数

返回内容

mysql_get_server_info

查看当前连接的数据库和 MySQL 服务信息

数据库名、MySQL 版本、字符集、时区及当前安全限制

mysql_list_tables

列出当前数据库中的表和视图

keywordoffsetlimit

表名、对象类型、注释、存储引擎和估算行数

mysql_describe_table

查看指定表或视图的结构

table

字段顺序、字段名、类型、可空性、默认值、主键标识、注释和外键关系

mysql_list_indexes

查看指定表的索引

table

索引名、是否唯一、索引类型、字段顺序和前缀长度

mysql_query

执行一条安全的只读查询

sql

列信息、二维数据、返回行数、耗时和是否被截断

mysql_explain

查看安全只读查询的 JSON 执行计划

sql

MySQL EXPLAIN FORMAT=JSON 执行计划

查询工具限制

  • mysql_querymysql_explainsql 只允许单条 SELECT 或只读 CTE。

  • 拒绝 INSERTUPDATEDELETE、DDL、CALLSET、跨库引用、多语句、锁定读取、文件导出、用户变量和危险函数。

  • 未指定 LIMIT 时,服务端自动追加 最大返回行数 + 1,用于判断结果是否截断;实际返回不超过配置的最大行数。

  • 已有 LIMIT 超过最大返回行数时直接拒绝,不自动改写查询语义。

  • 成功和失败结果都包含版本化 JSON 结构;同时通过 MCP structuredContent 和精简 JSON 文本返回。

Related MCP server: MySQL MCP Server

连接与调用流程

服务启动和一次工具调用的流程如下:

启动 MCP 进程
    │
    ├─ 读取 .env / 进程环境变量并校验配置
    ├─ 创建 MySQL 连接池(启动时不主动查询业务数据)
    └─ 通过 stdio 等待 MCP 客户端握手
         │
         ├─ 客户端执行 initialize 和 tools/list
         └─ 客户端调用具体工具
              │
              ├─ 校验工具参数
              ├─ mysql_query / mysql_explain:解析并校验只读 SQL
              ├─ 从连接池获取连接
              ├─ START TRANSACTION READ ONLY
              ├─ 设置服务端查询超时并执行 SQL
              ├─ 成功或失败后执行 ROLLBACK
              └─ 返回 structuredContent 和 JSON 文本结果

元数据工具使用参数化 SQL 查询 information_schemamysql_querymysql_explain 使用用户提交的 SQL,但必须先通过 AST 安全策略。查询超时或连接异常时,连接会被销毁而不会放回连接池。服务收到 SIGINTSIGTERM 后关闭连接池。

从项目目录启动开发模式:

Set-Location "C:\Users\77384\WorkProject\mcp\mysql\mysql-readonly-mcp"
npm run dev

以 Codex 连接为例

本项目采用 MCP stdio 传输模式。仍然是“本地运行 MCP,Codex 使用 MCP”,但启动动作由 Codex 完成:Codex 作为父进程启动 node dist/index.js,再通过子进程的 stdin/stdout 交换 MCP JSON-RPC 消息。因此,使用 Codex 时不需要提前单独执行 npm run dev

Codex Desktop、Codex CLI 和 IDE 扩展共享 Codex 配置。完成构建后,在 C:\Users\77384\.codex\config.toml 中配置 MCP,让 Codex 直接启动编译产物:

  1. 在项目目录执行 npm installnpm run build

  2. 打开 C:\Users\77384\.codex\config.toml,参考 docs/codex-mcp-config.example.toml 增加 MCP 配置。

  3. env 中的 MYSQL_HOSTMYSQL_PORTMYSQL_DATABASEMYSQL_USERMYSQL_PASSWORD 改为本机测试库配置;密码只保存在本机配置中,不要提交到仓库。

  4. 重启或重新加载 Codex 的 MCP 配置。Codex 会启动 node dist/index.js,通过 stdin/stdout 完成 MCP 握手和工具调用。

两种启动方式的区别:

  • npm run dev:你手动启动 MCP,适合本地调试、协议测试或使用 MCP Inspector;该服务只监听当前进程的 stdin/stdout,不会开放端口,Codex 不能再通过端口连接到它。

  • Codex 配置启动:Codex 自动启动 MCP 子进程,并独占这组 stdin/stdout;这是当前项目接入 Codex 的推荐方式。

如果希望“先手动启动 MCP,再由 Codex 连接”,就需要把服务改造成 Streamable HTTP 等网络传输模式,这不是当前项目的实现方式。

config.toml 中的 env 内容写在 [mcp_servers.mysql_readonly.env] 节点下,示例:

[mcp_servers.mysql_readonly]
command = "node"
args = ["C:/Users/77384/WorkProject/mcp/mysql/mysql-readonly-mcp/dist/index.js"]

[mcp_servers.mysql_readonly.env]
MYSQL_HOST = "127.0.0.1"
MYSQL_PORT = "3306"
MYSQL_DATABASE = "erp_0808"
MYSQL_USER = "erp_0808_readonly_user"
MYSQL_PASSWORD = "<只保存在本机配置中的密码>"

直接执行 npm run dev 时,才使用项目根目录 .env;Codex 配置中的 env 用于 Codex 通过 stdio 启动 MCP 服务。两者同时存在时,进程环境变量优先于 .env

示例配置的连接链路是:

Codex
  └─ 启动 node <项目绝对路径>/dist/index.js
       └─ 通过 config.toml 的 env 传入 MySQL 配置
            └─ MCP Server 等待 initialize / tools/list
                 └─ Codex 调用 mysql_query 等工具
                      └─ MCP Server 使用只读账号连接 erp_0808

Codex 调用工具时,MCP Server 才从连接池获取 MySQL 连接;工具执行完成后回滚只读事务并释放或销毁连接。若只修改源码,需要重新执行 npm run build,再让 Codex 重新加载 MCP Server。

安全边界

服务端只接受单条 SELECT 或只读 CTE。SQL 先经过 node-sql-parser 的 MySQL AST 校验,再在独立 START TRANSACTION READ ONLY 事务中执行。服务端拒绝写操作、管理语句、多语句、跨库引用、锁定读取、文件导出、用户变量赋值和高风险函数。

MySQL 只读账号是最终安全边界。请先参考 docs/mysql-readonly-account.sql,再复制 .env.example.env 填写本机配置。密码不应写入源码、日志或提交记录。

开发与验证

npm install
npm run check
npm test
npm run build
npm start

日志只写入 stderr;stdout 保留给 MCP JSON-RPC。Codex 接入配置见 docs/codex-mcp-config.example.toml;JSON 示例仍保留在 docs/codex-mcp-config.example.json,供使用 JSON 格式的其他 MCP 客户端参考。

当前仓库包含不依赖 MySQL 的单元测试。真实 MySQL 8.4 集成测试需要用户提供本机测试库、只读账号和测试数据后执行;本项目默认不会修改数据库。

Available Tools

6 tools
mysql_describe_tableB

Describe columns and foreign-key relationships for one table or view.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It usefully discloses the return content (columns plus foreign-key relationships), which matters since there is no output schema, but it says nothing about error behavior for missing tables, required database context, or read-only nature.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero filler; every clause earns its place by naming the resource and the two things returned.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read-only introspection tool with no output schema, the description covers what is returned and what identifier is accepted. Minor gaps remain around qualification of the table name and error handling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter 'table' has 0% schema description coverage, so the schema gives no help. The description partially compensates by indicating the parameter accepts a table or view name, which is genuine added semantics, but it omits whether the name must be schema/database qualified.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (describe) and resource (columns and foreign-key relationships for one table or view), which is clearly distinct from sibling tools like mysql_list_indexes or mysql_list_tables. It does not, however, explicitly contrast itself with those siblings, so it falls just short of the 5 bar.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use or when-not-to-use guidance, and no naming of alternatives such as mysql_query or mysql_list_indexes. The purpose hints at schema-introspection usage, but no explicit guidance is offered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mysql_explainA

Return the JSON execution plan for a safe read-only SELECT query.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose that only read-only SELECT input is accepted, implying safety and rejection of other statement types. It omits whether the query is ever executed, what happens on non-SELECT input, and required privileges.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, no waste, with the return type and the input constraint front-loaded. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The return value (JSON execution plan) is stated, which matters since no output schema exists, and the single parameter's constraint is given. Still missing is guidance on choosing this over mysql_query and any note on how the plan is produced (plain EXPLAIN vs execution).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and the lone parameter 'sql' is undescribed in the schema, so the description must compensate. It adds that the value must be a read-only SELECT, which is useful, but says nothing about formatting, placeholders, or statement termination.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Return') and resource ('JSON execution plan'), plus the accepted input type ('safe read-only SELECT query'). It does not differentiate from siblings like mysql_query, which an agent might otherwise pick to run the same SQL.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied: reach for this when you want a plan rather than results. There is no explicit statement of when to prefer mysql_explain over mysql_query, nor any prerequisite or exclusion noted.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mysql_get_server_infoA

Return the configured MySQL database, server version, charset, timezone, and safety limits.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavioral traits. The verb 'Return' implies a read-only, side-effect-free operation, but the description does not explicitly confirm this, nor does it mention authentication requirements, rate limits, or whether any server state is affected.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence that lists the returned fields without waste. Every element earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple no-argument read tool with no output schema, the description enumerates the key return values (database, version, charset, timezone, safety limits), which is sufficient for an agent to understand the tool's output. It could additionally state that no arguments are needed, but the schema already conveys that.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With zero parameters and complete schema coverage, the description need not discuss parameters. The baseline of 4 applies because no parameter information is missing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Return') and enumerates the exact server-level resources (database, version, charset, timezone, safety limits). This clearly differentiates it from sibling tools that deal with tables, indexes, queries, or execution plans, though no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides no guidance on when to call this tool versus alternatives, no prerequisites, and no exclusions. It only describes what the tool returns, leaving the agent to infer that it is used for server configuration inspection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mysql_list_indexesA

List indexes and ordered indexed columns for one table.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableYes

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full behavioral burden. It conveys read-only intent implicitly via 'List' but does not state that this is a read operation, whether it requires database selection, or what happens on a missing table.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, front-loaded verb, zero wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-param read tool with no output schema, the description adequately conveys purpose but lacks the behavioral context (read-only nature, auth/db prerequisites) an agent would benefit from given no annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter with 0% schema description coverage. The description names the scope ('one table') which maps to the single table param, but adds no syntax or format detail; with 0 params this baseline would be higher, but the param is undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (indexes and ordered indexed columns) scoped to one table, which cleanly distinguishes it from siblings like mysql_describe_table and mysql_list_tables.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'for one table' scoping implies this is the index-inspection tool versus describe_table for columns, but no explicit when/when-not guidance or named alternatives are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mysql_list_tablesC

List tables and views in the configured database.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
offsetNo
keywordNo

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden, yet it says nothing about read-only safety, default pagination (limit defaults to 50), or the fact that results may be truncated at 200. For a listing tool whose output can be silently bounded, that omission matters.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler or repetition. It is tight and immediately readable, which is the one dimension where this definition performs well.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with three undocumented parameters, no annotations, and no output schema, one sentence is not enough. Pagination behavior, filtering, and the shape of the returned list are all left to inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across three parameters, and the description does not mention limit, offset, or keyword at all. The keyword filter in particular is entirely undiscoverable from the definition text, so an agent may never learn it can filter results.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and resource ('tables and views') with scope ('in the configured database'). It is distinguishable from mysql_describe_table and mysql_list_indexes, but it never explicitly names those siblings or contrasts its role with them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance, no prerequisites, and no mention of alternatives such as mysql_describe_table or mysql_query. The agent must infer from the name alone that this is the discovery step before describing or querying a table.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mysql_queryB

Execute one safe, read-only SELECT or read-only CTE against the configured database.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden; it does disclose that execution is read-only and limited to a single statement ('one safe'), which is real behavioral value. It omits row limits, timeouts, permission requirements, and error behavior for rejected SQL.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no waste; the read-only restriction appears immediately after the verb. The adjective 'safe' adds little beyond 'read-only', a minor redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema and no annotations, so the description must cover everything. It establishes the read-only contract but leaves return shape (result rows), limits, and failure modes unspecified, which is a meaningful gap for an arbitrary-SQL tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for the single 'sql' parameter, so the description must compensate. It adds the useful constraint that the SQL must be a SELECT or read-only CTE, but says nothing about quoting, trailing semicolons, multi-statement rejection, or placeholders.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (execute) plus the resource and scope (SELECT / read-only CTE against the configured database). This cleanly separates it from the metadata siblings (list_tables, describe_table, list_indexes), though it never names them explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The read-only constraint is stated, which implicitly tells an agent when this tool is valid, but there is no explicit when-to-use guidance and no routing to siblings such as mysql_explain for plan inspection. Usage must be inferred from the constraint alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv0.1.0
    • First observedmysql_describe_table
    • First observedmysql_explain
    • First observedmysql_get_server_info
    • First observedmysql_list_indexes
    • First observedmysql_list_tables
    • First observedmysql_query

TDQS

A3.6/5.0

Scored across 6 tools

Disambiguation5/5

Each tool targets a clearly distinct introspection or query concern: server metadata, table listing, column/FK description, index listing, query execution, and plan explanation. The describe_table vs list_indexes boundary is clear (columns vs indexes), so an agent can reliably select the right tool.

Naming Consistency5/5

All six tools use a consistent mysql_verb_noun snake_case pattern (get_server_info, list_tables, describe_table, list_indexes, query, explain). Predictable and uniform throughout.

Tool Count5/5

Six tools is well-scoped for a read-only database server. Each tool earns its place across discovery (info, tables, describe, indexes) and querying (query, explain) with no redundancy.

Completeness4/5

The read-only surface covers introspection plus querying and plan analysis, which is solid for the stated purpose. Minor gaps like listing databases or schema-level search exist but are workable given the server targets a single configured database.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables safe querying and optional writing to MySQL databases via MCP tools, with support for schema inspection, connection management, and read-only mode.
    16 npm
    3
    MIT
  • A
    license
    C
    quality
    C
    maintenance
    Connects MCP-compatible clients like Claude to a MySQL database, enabling schema inspection and read/write queries via stdio transport.
    5
    317 npm
    1
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides read-only access to MySQL databases, enabling schema exploration, table inspection, and safe SELECT query execution via MCP.
    1
    -
  • F
    license
    A
    quality
    C
    maintenance
    Read-only MySQL database access via MCP. Enables listing databases, tables, schemas, running SELECT queries, and EXPLAIN plans.
    6
    -