secure-mcp-database-crud
Provides a MySQL-backed task management system with secure CRUD operations, including list, get, create, update, and delete tasks with audit events and confirmation tokens.
Provides a SQLite-backed task management system with secure CRUD operations, including list, get, create, update, and delete tasks with audit events and confirmation tokens.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@secure-mcp-database-crudCreate a new task called 'Finish report' with due date tomorrow."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Secure MCP Database CRUD
English | 日本語
SQLiteまたはMySQLへ接続し、安全なタスクCRUDだけを公開するMCPサーバーです。 任意SQLを公開せず、入力検証、パラメータ化クエリ、最小権限、監査イベント、 トランザクション、署名付き削除確認を一つの実行可能なサンプルにまとめています。
このリポジトリは記事 「データベースに接続するMCPサーバー:SQLiteとMySQLで安全なCRUD Toolを作る」 の完成形コードです。
5分で試す(SQLite)
前提は uv のみです。uvがPython 3.12も用意します。
git clone https://github.com/yunosuke-github/secure-mcp-database-crud.git
cd secure-mcp-database-crud
cp .env.example .env
uv sync
uv run mcp-db-init
uv run mcp-database-crud最後のコマンドはstdioで待機します。これは正常です。MCPクライアントには次のように登録します。
/absolute/path/... は実際の絶対パスへ置き換えてください。
{
"mcpServers": {
"secure-task-database": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/secure-mcp-database-crud",
"run",
"mcp-database-crud"
]
}
}
}動作をすぐ確認する場合はテストを実行します。
uv run pytestRelated MCP server: SQLite MCP Server
公開するTool
Tool | 種別 | 役割 |
| 読み取り | ステータス、件数、オフセット、許可済みソートで一覧取得 |
| 読み取り | IDで1件取得。不存在も正常な結果として返す |
| 更新 | タスクと |
| 更新 | 許可済み項目だけを更新し、必要なら楽観ロックを適用 |
| 読み取り | 対象と短時間有効な署名済みトークンを返す |
| 破壊的操作 | 対象・版・期限・nonceを検証して削除 |
execute_sqlのようなToolはありません。モデルが選べるのは用途が限定された操作だけです。
MySQLで動かす
Docker ComposeはMySQL 8.4、スキーマ、読み取り専用ユーザー、更新専用ユーザーを用意します。
cp .env.example .env
# .env の DATABASE_BACKEND を mysql へ変更
docker compose up -d --wait mysql
uv run mcp-database-crudローカル用パスワードは公開されたデモ値です。本番では必ず変更してください。アプリケーションの ユーザーにはDDL権限がないため、MySQLのスキーマ作成は起動時処理から分離しています。
MySQL統合テストはサービス起動後に明示的に実行します。
RUN_MYSQL_TESTS=1 uv run pytest -m mysql
docker compose down安全性の境界
flowchart LR
U[ユーザー] --> C[AIクライアント]
C -->|Tool名と構造化引数| M[MCPサーバー]
M --> V[Pydantic検証]
V --> R[TaskRepository]
R -->|固定SQLとバインド値| D[(SQLite / MySQL)]
M -.->|SQL・認証情報は返さない| C値はすべてプレースホルダーへバインドします。
ソート列と方向はEnumから固定SQL断片へ変換します。
SQLiteの読み取りは
mode=roとquery_onlyを併用します。MySQLはreader/writerのユーザーと接続プールを分けます。
タスク更新と
task_events追加は同じトランザクションです。更新時は取得した
updated_atをWHERE条件へ含めます。削除トークンはHMAC署名され、操作、ID、版、有効期限、nonceへ結び付きます。
成功済みnonceのハッシュを削除トランザクション内で一意保存し、再利用を拒否します。
ToolエラーにはSQL、ファイルパス、ホスト名、認証情報を含めません。
ディレクトリ構成
src/mcp_database_crud/
├── config.py # 環境変数とSecretStr設定
├── confirmation.py # HMAC確認トークン
├── models.py # Toolの入力・出力Schema
├── server.py # FastMCPの組み立てとstdio起動
├── database/
│ ├── protocol.py # SQLite/MySQL共通契約
│ ├── sqlite_repository.py # 呼び出し単位の接続とトランザクション
│ ├── mysql_repository.py # reader/writer接続プール
│ └── sqlite_schema.sql
└── tools/
├── handlers.py # 安全な結果とエラー変換
├── read_tools.py # 読み取りTool登録
└── write_tools.py # 更新・削除Tool登録
docker/mysql/init/001_schema.sql # MySQLスキーマと最小権限GRANT
tests/ # セキュリティ特性とRepository契約設定
.env.exampleを.envへコピーして使います。.envはGit管理対象外です。
変数 | 用途 | 既定値 |
|
|
|
| SQLiteファイル |
|
| 削除トークンのHMAC鍵(32文字以上) | 必須 |
| 削除確認の有効秒数 |
|
| ホスト、DB、reader/writer認証情報 | ローカルCompose用 |
| reader/writer各プールの接続数 |
|
| DB接続・SQLiteロック待機秒数 |
|
安全な署名鍵は、例えば次のように生成できます。
python -c 'import secrets; print(secrets.token_urlsafe(48))'開発
uv run ruff format --check .
uv run ruff check .
uv run mypy
uv run pytest --cov=mcp_database_crud --cov-report=term-missingテストでは、SQLインジェクション風文字列がデータとして保存されること、監査INSERT失敗時に 更新が戻ること、読み取り専用SQLiteが書き込みを拒否すること、改変・期限切れ・別タスク用・ 古い版・再利用トークンが拒否されることを確認します。
本番導入前の注意
このサンプルはローカルstdioサーバーを対象としています。リモート公開する場合は、Tool入力の
user_idを信用せず、認証コンテキストから主体を取得して各タスクへの認可を追加してください。
既存の業務APIが認可、通知、イベント発行を担っているなら、DBへ直接接続せずAPI経由を優先します。
レート制限、監視、バックアップ、マイグレーション、シークレット管理も環境に合わせて追加してください。
トラブルシューティング
unable to open database file:uv run mcp-db-initを先に実行してください。confirmation_signing_keyの検証エラー:.envを作り、32文字以上の鍵を設定してください。MySQLへ接続できない:
docker compose psでmysqlがhealthyか確認してください。MySQLスキーマを作り直したい: このComposeはtmpfsです。
docker compose down後に再起動します。
Available Tools
6 toolsconfirm_delete_taskADestructive
Delete the confirmed task after validating its signed, single-use token.
| Name | Required | Description | Default |
|---|---|---|---|
| task_id | Yes | ||
| confirmation_token | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructiveHint=true. The description adds context: it validates a signed, single-use token before deleting, which goes beyond the annotation. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no extraneous information. Every word is necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists (assumed to indicate result), and the tool is part of a clear workflow, the description is fairly complete. It could mention what happens on invalid token, but overall adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the burden is on the description. The description does not elaborate on parameters like task_id or confirmation_token (e.g., format, where to get the token). Minimal added meaning beyond parameter names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: 'Delete the confirmed task after validating its signed, single-use token.' It specifies the resource (task) and the precondition (validation), distinguishing it from siblings like prepare_delete_task or delete_task.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is used after a prepare step, as it mentions validating a 'signed, single-use token.' While it doesn't explicitly state when not to use it or list alternatives, the context from sibling names clarifies its role in a two-step deletion workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_taskA
Create one validated task and its audit event atomically.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | ||
| status | No | todo | |
| due_date | No | ||
| description | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are all false, so the description carries the full burden. It discloses that tasks are validated, that an audit event is created, and that the operation is atomic, providing useful behavioral context beyond what annotations offer.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no unnecessary words. Every element adds value, making it highly concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the existence of an output schema, the description need not detail return values. It covers the core function and side effects (validation, audit, atomicity). However, it lacks usage context, which slightly reduces completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description does not mention any parameters. With 0% schema description coverage, the agent must rely solely on parameter titles and constraints, which is insufficient for understanding how to construct valid input.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Create one validated task and its audit event atomically' clearly states the verb (create), resource (task), and additional context (validated, audit event, atomicity). It effectively distinguishes from sibling tools like update_task or confirm_delete_task.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. Sibling tools include get_task, list_tasks, update_task, etc., but no criteria for selection are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_taskARead-onlyIdempotent
Get one task by its positive integer ID.
| Name | Required | Description | Default |
|---|---|---|---|
| task_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint, idempotentHint, destructiveHint. The description adds no new behavioral context beyond the identifier constraint. No mention of error handling, permissions, or response format.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, succinct sentence that immediately states the tool's purpose. No extraneous words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-ID tool with a single parameter, annotations, and output schema, the description is adequate. It covers the essential use case, though it could optionally mention behavior on missing IDs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description mentions 'positive integer ID', which aligns with the schema's exclusiveMinimum:0, but adds no additional detail like format or examples. With 0% schema description coverage, the description partially compensates but offers minimal enhancement.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly specifies the action (Get), the resource (one task), and the identifier (positive integer ID). This distinguishes it from sibling tools like list_tasks (listing) and create_task (creation).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when a specific task ID is known, but does not explicitly mention when-not to use it or suggest alternatives such as list_tasks for multiple tasks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tasksBRead-onlyIdempotent
List tasks with bounded pagination and allowlisted sorting.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No | ||
| status | No | ||
| sort_by | No | created_at | |
| sort_order | No | desc |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false. Description adds behavioral traits: 'bounded pagination' implies limit and offset are enforced, 'allowlisted sorting' indicates only specific sort fields. No contradictions with annotations. Additional context like rate limits or empty result behavior is missing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, front-loaded with verb and resource. Every phrase adds value ('bounded pagination', 'allowlisted sorting'). However, it could be slightly expanded to include the status filter without losing conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists (documenting return structure) and annotations cover safety, the description is mostly adequate. However, it fails to mention the status filter, a key parameter. Pagination and sorting are addressed. Overall, a minor gap reduces completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so description must compensate. It only mentions pagination and sorting in general terms, but does not specify the parameters (limit, offset, sort_by, sort_order) or the status filter. No parameter details or syntax are provided, leaving agents to infer from schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'List' and resource 'tasks', with constraints 'bounded pagination' and 'allowlisted sorting'. It distinguishes from sibling tools like get_task (single) and create_task/modify tasks. However, it omits mentioning the status filter parameter, which is a notable missing aspect.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives. The description does not mention when not to use it (e.g., for single record retrieval, use get_task). Siblings are listed but not referenced. Agent must infer usage context from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prepare_delete_taskARead-onlyIdempotent
Return the exact delete target and a short-lived confirmation token.
| Name | Required | Description | Default |
|---|---|---|---|
| task_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnly, idempotent, non-destructive. The description adds that the token is 'short-lived', providing a behavioral trait beyond annotations. No contradiction with annotations observed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no extraneous words, efficiently conveying the core action and outputs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one parameter, output schema exists), the description is largely adequate. It covers the primary purpose, but could hint at using the token with confirm_delete_task.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, and the description does not explain the task_id parameter or its meaning. Although the parameter is implied by context, the description fails to add semantic value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns the delete target and a confirmation token, differentiating it from sibling tools like get_task and confirm_delete_task. The verb 'return' and specific outputs convey precise purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use before confirm_delete_task but does not explicitly state when to use or not, nor mention alternatives. Usage context is derived from sibling tools rather than the description itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_taskADestructive
Update only allowlisted task fields, optionally checking the observed version.
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | ||
| status | No | ||
| task_id | Yes | ||
| due_date | No | ||
| description | No | ||
| expected_updated_at | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral detail beyond annotations: 'only allowlisted fields' and 'optionally checking the observed version' provide context for field restrictions and optimistic locking. Annotations already indicate write and destructive nature, but description enriches with field semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, no wasted words. Could be slightly more structured by listing allowlisted fields, but overall efficient and front-loaded with core action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given complex schema (6 params, 0% description coverage) and destructiveHint, description covers version checking but lacks detail on field restrictions, error handling, and side effects. Output schema exists, so return values are covered, but overall completeness is average.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so description must compensate. It mentions 'allowlisted fields' but doesn't enumerate which parameters are updatable. The 'expected_updated_at' parameter is hinted but not explained in terms of format or conflict behavior. Agent lacks sufficient detail to use parameters correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool updates task fields and mentions allowlisting and version checking, distinguishing it from create/get/list/delete siblings. The verb 'Update' and resource 'task' are specific.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use (to update tasks) but lacks explicit guidance on when not to use or alternatives. No mention of prerequisites or comparison with sibling tools like create_task or confirm_delete_task.
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. Dates show when Glama detected each change.
6 tool updates
v0.1.0- First observed
confirm_delete_task - First observed
create_task - First observed
get_task - First observed
list_tasks - First observed
prepare_delete_task - First observed
update_task
TDQS
Each tool targets a distinct operation: create, get, list, update, and a two-step delete with prepare and confirm. There is no functional overlap.
All tool names follow a consistent verb_noun pattern (e.g., create_task, update_task, prepare_delete_task). The naming is clear and predictable.
With 6 tools, the server is well-scoped for task CRUD operations. The count is neither excessive nor insufficient for the domain.
The tool set covers full CRUD functionality plus a secure two-step delete. No obvious missing operations for the stated purpose of secure task management.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Local-first task manager: create, edit, and complete tasks, projects, and checklists via MCP.
Task management for people and AI agents, with scoped OAuth access to issues, projects, and docs.
130Shared task queue for humans and AI agents: leases, handoffs, approvals and signed receipts.
Project management MCP for AI agents with safe task reads and writes.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables secure database interactions with MySQL, PostgreSQL, and SQLite through granular permissions, multi-database support, and cloud-ready SSL/TLS connections. Supports read-only modes, schema-specific permissions, and transaction management for safe database operations.242MIT
- AlicenseNot gradedqualityFmaintenanceEnables secure and controlled access to SQLite databases through the Model Context Protocol. Provides comprehensive database operations with granular permissions, SQL injection protection, and audit logging for safe database interactions.71MIT
- FlicenseNot gradedqualityDmaintenanceEnables task management through a local MySQL database, supporting full CRUD operations and automated tracking of status transitions. Users can create, search, and update tasks while maintaining a detailed progress history for all activities.-
- AlicenseCqualityAmaintenanceProvides comprehensive SQLite database operations for LLMs with security features, transaction support, and separation of read-only and destructive operations.2213319MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/yunosuke-github/secure-mcp-database-crud'
If you have feedback or need assistance with the MCP directory API, please join our Discord server