shop-sql-mcp
shop-sql-mcp
shop.db SQLiteデータベースへの読み取り専用の分析アクセスを、stdio経由でAIエージェントに提供する小さなMCPサーバーです。
サーバーが行うのは3つのことだけです。テーブルの一覧表示、スキーマの説明、サーバーが強制するページネーション付きで呼び出しごとに1つの読み取り専用SQL文を実行することです。どの結合を行うか、どのように集計するか、いつスキーマを参照するかといったすべての推論はエージェントに委ねられます。
AI Agent
|
| MCP over stdio
v
shop-sql-mcp
|
+-- list_tables
+-- describe_table
+-- query_database
|
v
read-only SQLite connection
|
v
shop.db要件
Node.js 22.5以上(24+を推奨)。サーバーは組み込みの
node:sqliteモジュールを使用するため、コンパイルが必要なネイティブSQLite依存関係はありません。その他のランタイム前提条件はありません。
Related MCP server: mcpserve-py
インストール
npm install設定
設定は任意です。デフォルトでは、サーバーはプロジェクトルートにあるshop.dbを開きます。
変数 | デフォルト | 意味 |
|
| SQLiteファイルへのパス。相対パスはプロジェクトルートに対して解決されるため、サーバーは起動された作業ディレクトリに依存しません。 |
ローカルの上書きを保持したい場合は、.env.exampleを.envにコピーしてください。サーバー自体はプレーンな環境変数を読み取ります。.env.example内のANTHROPIC_API_KEY、EVAL_MODEL、EVAL_MAX_STEPSはnpm run evalでのみ使用されます。
ビルド
npm run buildsrc/をdist/にコンパイルします。
実行
npm start # runs the built server (dist/index.js)
npm run dev # runs src/index.ts directly, no build stepサーバーはstdin/stdoutでMCPを話し、stderrには診断情報しか出力しません。そのため、ターミナルで実行するとハングしたように見えますが、それが正しい動作です。MCPホストから起動されることを想定しています。
MCPエージェントに接続する
これをMCPホストの設定(Claude Desktopのclaude_desktop_config.json、Claude Codeの.mcp.json、またはホストに応じた同等のファイル)に追加します。プロジェクトへの絶対パスを使用します:
{
"mcpServers": {
"shop-sql": {
"command": "node",
"args": ["/absolute/path/to/shop-sql-mcp/dist/index.js"]
}
}
}ビルドせずにソースから実行するには、代わりにTypeScriptエントリポイントを指定します — Node.jsが直接実行します:
{
"mcpServers": {
"shop-sql": {
"command": "node",
"args": ["/absolute/path/to/shop-sql-mcp/src/index.ts"]
}
}
}別の場所のデータベースを読み取る場合:
{
"mcpServers": {
"shop-sql": {
"command": "node",
"args": ["/absolute/path/to/shop-sql-mcp/dist/index.js"],
"env": { "DATABASE_PATH": "/absolute/path/to/other.db" }
}
}
}Claude Codeでは、コマンドラインから登録することもできます:
claude mcp add shop-sql -- node /absolute/path/to/shop-sql-mcp/dist/index.jsツール
list_tables
引数なし。ユーザーテーブルを返します。内部のsqlite_*テーブルは非表示です。
{
"tables": [
{ "name": "customers" },
{ "name": "order_items" },
{ "name": "orders" },
{ "name": "products" }
]
}describe_table
{ table: string }スキーマをSQLiteからライブで読み取ります — ハードコードされたものはありません — そして、列、型、NULL許容性、主キー、外部キーを報告します:
{
"table": "order_items",
"columns": [
{ "name": "id", "type": "INTEGER", "nullable": false, "primaryKey": true },
{ "name": "order_id", "type": "INTEGER", "nullable": false, "primaryKey": false }
],
"foreignKeys": [
{ "column": "order_id", "referencesTable": "orders", "referencesColumn": "id" },
{ "column": "product_id", "referencesTable": "products", "referencesColumn": "id" }
]
}不明な名前はクラッシュではなく、回復可能なエラーです:
{ "error": { "code": "TABLE_NOT_FOUND", "message": "TABLE_NOT_FOUND: Table \"foo\" does not exist." } }注:INTEGER PRIMARY KEYの列はnullable: falseとして報告されます。SQLiteのtable_infoは別のことを示しますが、そのような列はrowidの別名であり、NULLを保持することはできません。
query_database
{ sql: string; limit?: number; offset?: number }読み取り専用の文を1つ実行します — SELECT ...またはWITH ... SELECT ... — JOIN、WHERE、GROUP BY、HAVING、ORDER BY、サブクエリ、集計、日付フィルタリングのすべてがサポートされています。
{
"columns": ["category", "revenue"],
"rows": [["Electronics", 1234567.89]],
"returnedRows": 1,
"limit": 100,
"offset": 0,
"hasMore": false
}行はcolumnsの順序の値の配列です。これにより、結果ペイロードをコンパクトに保ち、クエリが同名列を2つ生成した場合でも曖昧さがありません。
失敗は、isErrorが設定された通常のツール結果と、短く実行可能なペイロードとして返されます。エージェントはそれを受けてSQLを修正し、再試行できます:
{ "error": { "code": "SQL_ERROR", "message": "no such column: total" } }エラーコード:SQL_ERROR、READ_ONLY_VIOLATION、MULTIPLE_STATEMENTS、TABLE_NOT_FOUND、INVALID_ARGUMENT、DATABASE_UNAVAILABLE。スタックトレースが返されることはありません。
ページネーション
ページネーションはモデルのSQLではなく、サーバーによって強制されます。
limitのデフォルトは100、最大は500です。offsetのデフォルトは0です。エージェントのクエリは
SELECT * FROM (<your sql>) LIMIT ? OFFSET ?としてラップされるため、クエリにLIMIT 100000が含まれていても、limitより多くの行を返すことはできません。サーバーは内部的に
limit + 1行を取得して、2回目のカウントクエリなしにhasMoreを判定し、最大limit行を返します。したがって、1回の呼び出しが500行を超えることはありません。これにより、広範な
SELECT *がモデルのコンテキストに殺到しません。
結果をページ送りするには、SQLを同一のまま(決定論的なORDER BY付きで)維持し、hasMoreがtrueの間offsetをlimitずつ進めます。
読み取り専用の安全性
2つの独立したレイヤーがあるため、どちらか一方だけに依存することはありません。
1. SQL検証(src/sqlSafety.ts)。小さなレクサーがコメント、文字列リテラル、引用符付き識別子をスキップし、次を要求します:
文が
SELECTまたはWITHで始まること。単純なstartsWith("SELECT")では、有効な読み取り専用CTEを拒否してしまいます。文がちょうど1つであること(最初の
;より後の部分は拒否され、リテラルまたはコメント内の;は区切り記号ではありません)。禁止キーワードがどこにも現れないこと(CTE内にネストしたものも含む):
INSERT、UPDATE、DELETE、CREATE、DROP、ALTER、REPLACE、ATTACH、DETACH、VACUUM、REINDEX、PRAGMA、ANALYZE、BEGIN、COMMIT、ROLLBACK、SAVEPOINT、load_extension、writable_schema。
禁止されたSQLは、常に明示的なエラーで拒否されます — 黙って無視されることも、部分的に実行されることもありません。REPLACE(a, b, c)はスカラー関数として引き続き許可されます。書き込みを伴うのはREPLACE INTO文だけだからです。
2. SQLite接続自体。 shop.dbはnew DatabaseSync(path, { readOnly: true })で開かれます。検証をすり抜けた書き込みが発生しても、SQLiteは*"attempt to write a readonly database"*と拒否します。テストスイートは、バリデータをバイパスして接続上に直接書き込みを発行し、これを検証しています。
不正または禁止されたクエリはツールエラーとして返され、プロセスを終了させることはありません。そのため、セッションは何度失敗しても生き続けます。
テストの実行
npm test決定的スイートのみを実行します — ネットワーク、APIキー、LLMは使用しません。Node.jsビルトインのテストランナーがTypeScriptソースを直接実行します。カバレッジには次が含まれます:list_tables、describe_table(列、型、NULL許容性、主キー、外部キー、不明なテーブル)、単純なSELECT、フィルタリング、集約、結合、GROUP BY、読み取り専用CTE、日付フィルタリング、ページネーション(デフォルトのlimit、最大limit、offset、hasMoreの境界)、無効なSQL、不明な列とテーブル、INSERT/UPDATE/DELETE/CREATE/DROP/ALTER/REPLACE/ATTACH/DETACH/VACUUM/REINDEX/PRAGMAと複数文の拒否、拒否されたすべての書き込みの後にデータベースがバイト単位で同一であることの証明、そしてstdioを介したエンドツーエンドのMCP呼び出しがエラー後もサーバーが使用可能なことを確認します。
evalを手動で実行
export ANTHROPIC_API_KEY=sk-...
npm run evalこれは手動で起動してください。 実際のLLMに対してstdioで実際のMCPサーバーを起動し、有料のAPI呼び出しを行うため、意図的にnpm testから除外されています。
サーバーを起動し、モデルに3つのMCPツールと、タスクごとに固定されたJSONスキーマを持つsubmit_answerツールを渡し、構造化された回答を自然言語テキストではなく、SQLiteから直接計算された参照値と比較します。タスクには、テーブル発見、マルチステップのスキーマ発見、フィルタリング、集約、結合、顧客の支出額、顧客の注文数、商品の売上、カテゴリの売上高、2025年の売上、そして拒否されなければならない破壊的なリクエストが含まれます(このチェックでは、その後にデータベースが変更されていないことも検証します)。
任意:EVAL_MODEL(デフォルトclaude-sonnet-5)とEVAL_MAX_STEPS(デフォルト12)。いずれかのタスクが失敗すると、終了コードは非ゼロになります。
レイアウト
src/
index.ts MCP server: tool registration, stdio wiring, error shaping
db.ts read-only connection, path resolution, row/value normalisation
tools.ts the three tools: list_tables, describe_table, query_database
sqlSafety.ts single-statement read-only SQL validation
tests/
sqlSafety.test.ts validator, allowed and forbidden SQL
tools.test.ts tools against the real shop.db
mcp.test.ts end-to-end over stdio with a real MCP client
eval/
tasks.ts eval tasks and their SQLite reference values
run.ts LLM + MCP eval runner (manual)
shop.db依存関係
パッケージ | 理由 |
| 公式のMCPTypeScript SDK(v2)。によって提供されるもの |
| SDKのツール入出力スキーマに必要です。エージェントに機械可読な引数型を公開するものです。 |
必要なのは、 | 開発のみ:ビルドと型テストのため。 |
| 開発のみ:stdioのエンドツーエンドテストとevalランナーで使用する公式MCPクライアントです。 |
SQLiteはNode.jsビルトインのnode:sqlite、テストはNode.jsビルトインのテストランナー、evalのHTTP呼び出しはビルトインのfetchを使用します。ドライバ、ORM、クエリビルダー、Webフレームワーク、ロガー、テストフレームワーク、SQLパーサー、LLM SDKはインストールされていません。
This server cannot be installed
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 Servers
- AlicenseAqualityCmaintenanceEnables safe, read-only SQL access to SQLite databases for AI agents, allowing schema exploration and SELECT queries with defense-in-depth protections.3MIT
- AlicenseNot gradedqualityDmaintenanceExposes SQLite database query tools and markdown document resources over JSON-RPC 2.0 stdio transport, enabling AI assistants to read and search documents and execute read-only SQL queries.1MIT
- AlicenseAqualityBmaintenanceLets AI agents query local SQLite database files read-only using Node's built-in sqlite module, providing tools for listing tables, describing schemas, and running SQL queries.315MIT
- FlicenseNot gradedqualityCmaintenanceExposes any SQLite database as read-only MCP tools for AI assistants, enabling listing tables, describing schemas, and running SELECT queries with filtering, ordering, and pagination.
Related MCP Connectors
Explore, query, and inspect SQLite databases with ease. List tables, preview results, and view det…
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
Query PostgreSQL databases in plain English — LLM-generated, safety-validated SQL.
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/lampmaster/shop-sql-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server