sqlseed 0.1.16__tar.gz → 0.1.18__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. {sqlseed-0.1.16 → sqlseed-0.1.18}/CHANGELOG.md +21 -0
  2. {sqlseed-0.1.16 → sqlseed-0.1.18}/CHANGELOG.zh-CN.md +21 -0
  3. {sqlseed-0.1.16 → sqlseed-0.1.18}/PKG-INFO +1 -1
  4. sqlseed-0.1.18/plugins/mcp-server-sqlseed/README.md +77 -0
  5. sqlseed-0.1.18/plugins/mcp-server-sqlseed/README.zh-CN.md +77 -0
  6. sqlseed-0.1.18/plugins/mcp-server-sqlseed/pyproject.toml +47 -0
  7. sqlseed-0.1.18/plugins/mcp-server-sqlseed/src/mcp_server_sqlseed/__init__.py +7 -0
  8. sqlseed-0.1.18/plugins/mcp-server-sqlseed/src/mcp_server_sqlseed/__main__.py +6 -0
  9. sqlseed-0.1.18/plugins/mcp-server-sqlseed/src/mcp_server_sqlseed/config.py +9 -0
  10. sqlseed-0.1.18/plugins/mcp-server-sqlseed/src/mcp_server_sqlseed/server.py +190 -0
  11. sqlseed-0.1.18/plugins/mcp-server-sqlseed/uv.lock +1165 -0
  12. sqlseed-0.1.18/plugins/sqlseed-ai/README.md +109 -0
  13. sqlseed-0.1.18/plugins/sqlseed-ai/README.zh-CN.md +109 -0
  14. sqlseed-0.1.18/plugins/sqlseed-ai/pyproject.toml +44 -0
  15. sqlseed-0.1.18/plugins/sqlseed-ai/src/sqlseed_ai/__init__.py +77 -0
  16. sqlseed-0.1.18/plugins/sqlseed-ai/src/sqlseed_ai/_client.py +24 -0
  17. sqlseed-0.1.18/plugins/sqlseed-ai/src/sqlseed_ai/_json_utils.py +38 -0
  18. sqlseed-0.1.18/plugins/sqlseed-ai/src/sqlseed_ai/_model_selector.py +111 -0
  19. sqlseed-0.1.18/plugins/sqlseed-ai/src/sqlseed_ai/analyzer.py +353 -0
  20. sqlseed-0.1.18/plugins/sqlseed-ai/src/sqlseed_ai/config.py +55 -0
  21. sqlseed-0.1.18/plugins/sqlseed-ai/src/sqlseed_ai/errors.py +151 -0
  22. sqlseed-0.1.18/plugins/sqlseed-ai/src/sqlseed_ai/examples.py +183 -0
  23. sqlseed-0.1.18/plugins/sqlseed-ai/src/sqlseed_ai/provider.py +63 -0
  24. sqlseed-0.1.18/plugins/sqlseed-ai/src/sqlseed_ai/refiner.py +292 -0
  25. sqlseed-0.1.18/plugins/sqlseed-ai/uv.lock +677 -0
  26. {sqlseed-0.1.16 → sqlseed-0.1.18}/pyproject.toml +0 -1
  27. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/_utils/progress.py +57 -10
  28. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/core/mapper.py +1 -1
  29. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/core/orchestrator.py +62 -2
  30. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/database/_base_adapter.py +12 -0
  31. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/database/_protocol.py +2 -0
  32. sqlseed-0.1.18/src/sqlseed/plugins/__init__.py +12 -0
  33. sqlseed-0.1.18/src/sqlseed/plugins/hookspecs.py +119 -0
  34. sqlseed-0.1.18/src/sqlseed/plugins/manager.py +37 -0
  35. sqlseed-0.1.16/sqlseed-/344/273/243/347/240/201/350/264/250/351/207/217/351/227/256/351/242/230/346/261/207/346/200/273.md +0 -204
  36. {sqlseed-0.1.16 → sqlseed-0.1.18}/.gitignore +0 -0
  37. {sqlseed-0.1.16 → sqlseed-0.1.18}/LICENSE +0 -0
  38. {sqlseed-0.1.16 → sqlseed-0.1.18}/README.md +0 -0
  39. {sqlseed-0.1.16 → sqlseed-0.1.18}/README.zh-CN.md +0 -0
  40. {sqlseed-0.1.16 → sqlseed-0.1.18}/examples/build_demo_db.py +0 -0
  41. {sqlseed-0.1.16 → sqlseed-0.1.18}/examples/notebooks/01-quickstart.ipynb +0 -0
  42. {sqlseed-0.1.16 → sqlseed-0.1.18}/examples/notebooks/02-column-mapping.ipynb +0 -0
  43. {sqlseed-0.1.16 → sqlseed-0.1.18}/examples/notebooks/03-generators.ipynb +0 -0
  44. {sqlseed-0.1.16 → sqlseed-0.1.18}/examples/notebooks/04-database-advanced.ipynb +0 -0
  45. {sqlseed-0.1.16 → sqlseed-0.1.18}/examples/notebooks/05-dag-and-constraints.ipynb +0 -0
  46. {sqlseed-0.1.16 → sqlseed-0.1.18}/examples/notebooks/06-config-deep-dive.ipynb +0 -0
  47. {sqlseed-0.1.16 → sqlseed-0.1.18}/examples/notebooks/07-ai-plugin.ipynb +0 -0
  48. {sqlseed-0.1.16 → sqlseed-0.1.18}/examples/notebooks/08-mcp-server.ipynb +0 -0
  49. {sqlseed-0.1.16 → sqlseed-0.1.18}/examples/notebooks/09-plugin-hooks.ipynb +0 -0
  50. {sqlseed-0.1.16 → sqlseed-0.1.18}/examples/notebooks/10-cli-reference.ipynb +0 -0
  51. {sqlseed-0.1.16 → sqlseed-0.1.18}/examples/notebooks/11-utilities.ipynb +0 -0
  52. {sqlseed-0.1.16 → sqlseed-0.1.18}/examples/notebooks/12-testing-patterns.ipynb +0 -0
  53. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/__init__.py +0 -0
  54. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/_utils/__init__.py +0 -0
  55. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/_utils/logger.py +0 -0
  56. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/_utils/metrics.py +0 -0
  57. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/_utils/paths.py +0 -0
  58. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/_utils/schema_helpers.py +0 -0
  59. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/_utils/sql_safe.py +0 -0
  60. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/_version.py +0 -0
  61. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/cli/__init__.py +0 -0
  62. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/cli/main.py +0 -0
  63. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/config/__init__.py +0 -0
  64. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/config/loader.py +0 -0
  65. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/config/models.py +0 -0
  66. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/config/snapshot.py +0 -0
  67. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/core/__init__.py +0 -0
  68. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/core/column_dag.py +0 -0
  69. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/core/constraints.py +0 -0
  70. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/core/enrichment.py +0 -0
  71. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/core/expression.py +0 -0
  72. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/core/plugin_mediator.py +0 -0
  73. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/core/relation.py +0 -0
  74. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/core/result.py +0 -0
  75. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/core/schema.py +0 -0
  76. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/core/transform.py +0 -0
  77. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/core/unique_adjuster.py +0 -0
  78. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/database/__init__.py +0 -0
  79. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/database/_compat.py +0 -0
  80. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/database/_helpers.py +0 -0
  81. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/database/optimizer.py +0 -0
  82. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/database/raw_sqlite_adapter.py +0 -0
  83. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/database/sqlite_utils_adapter.py +0 -0
  84. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/generators/__init__.py +0 -0
  85. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/generators/_dispatch.py +0 -0
  86. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/generators/_json_helpers.py +0 -0
  87. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/generators/_protocol.py +0 -0
  88. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/generators/_string_helpers.py +0 -0
  89. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/generators/base_provider.py +0 -0
  90. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/generators/faker_provider.py +0 -0
  91. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/generators/mimesis_provider.py +0 -0
  92. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/generators/registry.py +0 -0
  93. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/generators/stream.py +0 -0
  94. {sqlseed-0.1.16 → sqlseed-0.1.18}/src/sqlseed/py.typed +0 -0
  95. {sqlseed-0.1.16 → sqlseed-0.1.18}/uv.lock +0 -0
@@ -7,6 +7,27 @@ All notable changes to this project will be documented in this file.
7
7
  Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
8
8
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
9
9
 
10
+ ## [v0.1.17]
11
+
12
+ ### Added
13
+
14
+ - `RichProgressBackend` now accepts `ascii_only` parameter: when `True`, uses `"line"` spinner (`|/-\`) and omits `BarColumn`, avoiding `UnicodeEncodeError` on GBK/Big5/CP936 console encodings
15
+ - `_can_render_unicode()` cached helper probes whether stdout can encode Rich's Braille/block-element characters (U+280B, U+2588, U+2591)
16
+ - `create_progress()` auto-falls back to `ascii_only=True` when `_can_render_unicode()` returns `False`, with a debug log message
17
+ - `DataOrchestrator` adds SQL operation methods: `execute(sql, params)`, `query(sql, params)`, `fetch_one(sql, params)`, `fetch_all(sql, params)` for direct database interaction
18
+ - `BaseSQLiteAdapter._execute(sql, params)` method for parameterized SQL execution
19
+ - `DatabaseAdapter` protocol updated with `_execute` method signature
20
+
21
+ ### Changed
22
+
23
+ - `RichProgressBackend` refresh rate set to 1 Hz (was default 10 Hz) to reduce terminal flicker
24
+ - Test suite: `TestRichProgressBackend` and `TestRichProgressBackendAsciiOnly` merged via `pytest.mark.parametrize` to eliminate code duplication
25
+
26
+ ### Fixed
27
+
28
+ - Windows compatibility: GBK/GB2312/Big5/CP936 encoded terminals no longer crash with `UnicodeEncodeError` when displaying Rich progress bars
29
+ - `.gitignore`: removed `*汇总.md` pattern (no longer needed)
30
+
10
31
  ## [v0.1.16]
11
32
 
12
33
  ### Added
@@ -7,6 +7,27 @@
7
7
  格式基于 [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
8
8
  本项目遵循[语义化版本](https://semver.org/spec/v2.0.0.html)。
9
9
 
10
+ ## [v0.1.17]
11
+
12
+ ### 新增
13
+
14
+ - `RichProgressBackend` 新增 `ascii_only` 参数:启用时使用 `"line"` 旋转符(`|/-\`)并省略 `BarColumn`,避免 GBK/Big5/CP936 编码终端的 `UnicodeEncodeError`
15
+ - `_can_render_unicode()` 缓存辅助函数,检测 stdout 是否能编码 Rich 的盲文/方块字符(U+280B, U+2588, U+2591)
16
+ - `create_progress()` 在 `_can_render_unicode()` 返回 `False` 时自动回退到 `ascii_only=True`,并输出 debug 日志
17
+ - `DataOrchestrator` 新增 SQL 操作方法:`execute(sql, params)`、`query(sql, params)`、`fetch_one(sql, params)`、`fetch_all(sql, params)` 用于直接数据库交互
18
+ - `BaseSQLiteAdapter._execute(sql, params)` 参数化 SQL 执行方法
19
+ - `DatabaseAdapter` 协议新增 `_execute` 方法签名
20
+
21
+ ### 变更
22
+
23
+ - `RichProgressBackend` 刷新频率设为 1 Hz(原默认 10 Hz),减少终端闪烁
24
+ - 测试套件:`TestRichProgressBackend` 和 `TestRichProgressBackendAsciiOnly` 通过 `pytest.mark.parametrize` 合并,消除代码重复
25
+
26
+ ### 修复
27
+
28
+ - Windows 兼容性:GBK/GB2312/Big5/CP936 编码终端不再因 Rich 进度条的 Unicode 字符而崩溃
29
+ - `.gitignore`:移除 `*汇总.md` 规则(不再需要)
30
+
10
31
  ## [v0.1.16]
11
32
 
12
33
  ### 新增
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlseed
3
- Version: 0.1.16
3
+ Version: 0.1.18
4
4
  Summary: Declarative SQLite test data generation toolkit
5
5
  Project-URL: Homepage, https://github.com/sunbos/sqlseed
6
6
  Project-URL: Documentation, https://github.com/sunbos/sqlseed#readme
@@ -0,0 +1,77 @@
1
+ # mcp-server-sqlseed
2
+
3
+ **[English](README.md)** | [中文](README.zh-CN.md)
4
+
5
+ [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server for [sqlseed](https://github.com/sunbos/sqlseed) — enabling AI assistants to inspect schemas, generate configs, and fill SQLite databases.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ # Basic
11
+ pip install mcp-server-sqlseed
12
+
13
+ # With AI support (includes sqlseed-ai)
14
+ pip install mcp-server-sqlseed[ai]
15
+ ```
16
+
17
+ ## Configuration
18
+
19
+ ### Claude Desktop
20
+
21
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or equivalent:
22
+
23
+ ```json
24
+ {
25
+ "mcpServers": {
26
+ "sqlseed": {
27
+ "command": "mcp-server-sqlseed"
28
+ }
29
+ }
30
+ }
31
+ ```
32
+
33
+ ### Cursor / Other MCP Clients
34
+
35
+ Use command: `mcp-server-sqlseed`
36
+
37
+ ## MCP Tools
38
+
39
+ | Tool | Description |
40
+ |:-----|:------------|
41
+ | `sqlseed_inspect_schema` | Inspect database schema: columns, foreign keys, indexes, sample data, schema_hash. Accepts optional `table_name` (all tables if omitted). |
42
+ | `sqlseed_generate_yaml` | AI-driven YAML config generation with self-correction. Requires `sqlseed-ai` plugin and API key. Supports `api_key`/`base_url`/`model` parameter overrides. |
43
+ | `sqlseed_execute_fill` | Execute data generation. Accepts optional `yaml_config` string, `count`, and `enrich` flag. Max YAML config size: 256KB. |
44
+
45
+ ### MCP Resource
46
+
47
+ | Resource | Description |
48
+ |:---------|:------------|
49
+ | `sqlseed://schema/{db_path}/{table_name}` | Read-only JSON schema for a specific table |
50
+
51
+ ## Example Usage
52
+
53
+ After configuring your MCP client, you can prompt:
54
+
55
+ > "Inspect the schema of `app.db`, generate a YAML config for the `users` table, then fill 1000 rows."
56
+
57
+ The AI assistant will call:
58
+ 1. `sqlseed_inspect_schema` → get table structure
59
+ 2. `sqlseed_generate_yaml` → generate YAML config (if sqlseed-ai is installed)
60
+ 3. `sqlseed_execute_fill` → fill data
61
+
62
+ ## AI Integration
63
+
64
+ When `sqlseed-ai` is installed and an API key is configured (`SQLSEED_AI_API_KEY` or `OPENAI_API_KEY`), the `sqlseed_generate_yaml` tool uses LLM-driven analysis with self-correction. Without the AI plugin, the tool returns a fallback message.
65
+
66
+ ## Requirements
67
+
68
+ - Python >= 3.10
69
+ - `sqlseed >= 0.1.0`
70
+ - `mcp >= 1.0`
71
+
72
+ Optional:
73
+ - `sqlseed-ai` (for `sqlseed_generate_yaml` tool)
74
+
75
+ ## License
76
+
77
+ AGPL-3.0-or-later
@@ -0,0 +1,77 @@
1
+ # mcp-server-sqlseed
2
+
3
+ [English](README.md) | **[中文](README.zh-CN.md)**
4
+
5
+ [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) 服务器,用于 [sqlseed](https://github.com/sunbos/sqlseed) — 让 AI 助手直接检查 Schema、生成配置和填充 SQLite 数据库。
6
+
7
+ ## 安装
8
+
9
+ ```bash
10
+ # 基础安装
11
+ pip install mcp-server-sqlseed
12
+
13
+ # 含 AI 支持(包含 sqlseed-ai)
14
+ pip install mcp-server-sqlseed[ai]
15
+ ```
16
+
17
+ ## 配置
18
+
19
+ ### Claude Desktop
20
+
21
+ 添加到 `~/Library/Application Support/Claude/claude_desktop_config.json`(macOS):
22
+
23
+ ```json
24
+ {
25
+ "mcpServers": {
26
+ "sqlseed": {
27
+ "command": "mcp-server-sqlseed"
28
+ }
29
+ }
30
+ }
31
+ ```
32
+
33
+ ### Cursor / 其他 MCP 客户端
34
+
35
+ 使用命令:`mcp-server-sqlseed`
36
+
37
+ ## MCP Tools
38
+
39
+ | Tool | 说明 |
40
+ |:-----|:-----|
41
+ | `sqlseed_inspect_schema` | 检查数据库 Schema:列、外键、索引、样本数据、schema_hash。可选 `table_name`(省略则返回所有表)。 |
42
+ | `sqlseed_generate_yaml` | AI 驱动的 YAML 配置生成,含自纠正。需要 `sqlseed-ai` 插件和 API Key。支持 `api_key`/`base_url`/`model` 参数覆盖。 |
43
+ | `sqlseed_execute_fill` | 执行数据生成。可选 `yaml_config` 字符串、`count` 和 `enrich` 标志。YAML 配置最大 256KB。 |
44
+
45
+ ### MCP Resource
46
+
47
+ | Resource | 说明 |
48
+ |:---------|:-----|
49
+ | `sqlseed://schema/{db_path}/{table_name}` | 指定表的只读 JSON Schema |
50
+
51
+ ## 使用示例
52
+
53
+ 配置 MCP 客户端后,可以这样提示:
54
+
55
+ > "检查 `app.db` 的 Schema,为 `users` 表生成 YAML 配置,然后填充 1000 行数据。"
56
+
57
+ AI 助手会依次调用:
58
+ 1. `sqlseed_inspect_schema` → 获取表结构
59
+ 2. `sqlseed_generate_yaml` → 生成 YAML 配置(需安装 sqlseed-ai)
60
+ 3. `sqlseed_execute_fill` → 填充数据
61
+
62
+ ## AI 集成
63
+
64
+ 当安装了 `sqlseed-ai` 并配置了 API Key(`SQLSEED_AI_API_KEY` 或 `OPENAI_API_KEY`)时,`sqlseed_generate_yaml` 工具使用 LLM 驱动的分析和自纠正。未安装 AI 插件时,该工具返回回退消息。
65
+
66
+ ## 依赖
67
+
68
+ - Python >= 3.10
69
+ - `sqlseed >= 0.1.0`
70
+ - `mcp >= 1.0`
71
+
72
+ 可选:
73
+ - `sqlseed-ai`(用于 `sqlseed_generate_yaml` 工具)
74
+
75
+ ## 许可证
76
+
77
+ AGPL-3.0-or-later
@@ -0,0 +1,47 @@
1
+ [build-system]
2
+ requires = ["hatchling", "hatch-vcs"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "mcp-server-sqlseed"
7
+ dynamic = ["version"]
8
+ requires-python = ">=3.10"
9
+ description = "MCP server for sqlseed - AI-powered SQLite test data generation"
10
+ readme = "README.md"
11
+ license = "AGPL-3.0-or-later"
12
+ authors = [
13
+ {name = "SunBo", email = "1443584939@qq.com"},
14
+ ]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ ]
24
+ dependencies = [
25
+ "sqlseed>=0.1.0,<2",
26
+ "mcp>=1.0,<2",
27
+ ]
28
+
29
+ [project.urls]
30
+ Homepage = "https://github.com/sunbos/sqlseed"
31
+ Repository = "https://github.com/sunbos/sqlseed/tree/main/plugins/mcp-server-sqlseed"
32
+
33
+ [project.optional-dependencies]
34
+ ai = ["sqlseed-ai"]
35
+
36
+ [project.scripts]
37
+ mcp-server-sqlseed = "mcp_server_sqlseed:main"
38
+
39
+ [tool.hatch.version]
40
+ source = "vcs"
41
+ fallback-version = "0.0.0"
42
+
43
+ [tool.hatch.version.raw-options]
44
+ root = "../.."
45
+
46
+ [tool.hatch.build.targets.wheel]
47
+ packages = ["src/mcp_server_sqlseed"]
@@ -0,0 +1,7 @@
1
+ from __future__ import annotations
2
+
3
+ from mcp_server_sqlseed.server import mcp
4
+
5
+
6
+ def main() -> None:
7
+ mcp.run()
@@ -0,0 +1,6 @@
1
+ from __future__ import annotations
2
+
3
+ from mcp_server_sqlseed import main
4
+
5
+ if __name__ == "__main__":
6
+ main()
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+
3
+ from pydantic import BaseModel
4
+
5
+
6
+ class MCPServerConfig(BaseModel):
7
+ db_path: str | None = None
8
+ host: str = "localhost"
9
+ port: int = 8000
@@ -0,0 +1,190 @@
1
+ from __future__ import annotations
2
+
3
+ import hashlib
4
+ import json
5
+ from pathlib import Path
6
+ from typing import Any
7
+
8
+ import yaml
9
+ from mcp.server.fastmcp import FastMCP
10
+
11
+ from sqlseed.config.models import GeneratorConfig
12
+ from sqlseed.core.orchestrator import DataOrchestrator
13
+
14
+ try:
15
+ from sqlseed_ai.analyzer import SchemaAnalyzer
16
+ from sqlseed_ai.config import AIConfig
17
+ from sqlseed_ai.refiner import AiConfigRefiner, AISuggestionFailedError
18
+
19
+ _AI_AVAILABLE = True
20
+ except ImportError:
21
+ _AI_AVAILABLE = False
22
+
23
+ mcp = FastMCP("sqlseed")
24
+
25
+ _MAX_YAML_CONFIG_SIZE = 256 * 1024
26
+
27
+
28
+ def _validate_db_path(db_path: str) -> str:
29
+ resolved = Path(db_path).resolve()
30
+ valid_exts = (".db", ".sqlite", ".sqlite3")
31
+ if not str(resolved).endswith(valid_exts):
32
+ raise ValueError(f"Invalid database path: {db_path}. Must be a .db, .sqlite, or .sqlite3 file.")
33
+ if not resolved.exists():
34
+ raise ValueError(f"Database file not found: {db_path}")
35
+ return str(resolved)
36
+
37
+
38
+ def _validate_table_name(table_name: str, allowed_tables: list[str]) -> str:
39
+ if table_name not in allowed_tables:
40
+ raise ValueError(f"Table '{table_name}' does not exist in the database. Available: {allowed_tables}")
41
+ return table_name
42
+
43
+
44
+ def _serialize_schema_context(ctx: dict[str, Any]) -> dict[str, Any]:
45
+ return {
46
+ "table_name": ctx["table_name"],
47
+ "columns": [
48
+ {
49
+ "name": c.name,
50
+ "type": c.type,
51
+ "nullable": c.nullable,
52
+ "default": c.default,
53
+ "is_primary_key": c.is_primary_key,
54
+ "is_autoincrement": c.is_autoincrement,
55
+ }
56
+ for c in ctx["columns"]
57
+ ],
58
+ "foreign_keys": [
59
+ {"column": fk.column, "ref_table": fk.ref_table, "ref_column": fk.ref_column} for fk in ctx["foreign_keys"]
60
+ ],
61
+ "indexes": ctx["indexes"],
62
+ "sample_data": ctx["sample_data"],
63
+ "all_table_names": ctx["all_table_names"],
64
+ }
65
+
66
+
67
+ def _compute_schema_hash(schema_ctx: dict[str, Any]) -> str:
68
+ hash_input = json.dumps(
69
+ {
70
+ "columns": [{"name": c.name, "type": c.type, "nullable": c.nullable} for c in schema_ctx["columns"]],
71
+ "foreign_keys": [{"column": fk.column, "ref_table": fk.ref_table} for fk in schema_ctx["foreign_keys"]],
72
+ },
73
+ sort_keys=True,
74
+ )
75
+ return hashlib.sha256(hash_input.encode()).hexdigest()[:16]
76
+
77
+
78
+ @mcp.resource("sqlseed://schema/{db_path}/{table_name}")
79
+ def get_schema_resource(db_path: str, table_name: str) -> str:
80
+ db_path = _validate_db_path(db_path)
81
+ with DataOrchestrator(db_path) as orch:
82
+ _validate_table_name(table_name, orch.get_table_names())
83
+ ctx = orch.get_schema_context(table_name)
84
+ serializable_ctx = _serialize_schema_context(ctx)
85
+ return json.dumps(serializable_ctx, ensure_ascii=False, indent=2)
86
+
87
+
88
+ @mcp.tool()
89
+ def sqlseed_inspect_schema(db_path: str, table_name: str | None = None) -> dict[str, Any]:
90
+ """Inspect database schema. Returns column info, foreign keys, indexes,
91
+ sample data, and schema_hash for specified table or all tables."""
92
+ db_path = _validate_db_path(db_path)
93
+ with DataOrchestrator(db_path) as orch:
94
+ if table_name:
95
+ _validate_table_name(table_name, orch.get_table_names())
96
+ tables = [table_name] if table_name else orch.get_table_names()
97
+ result: dict[str, Any] = {}
98
+ for tbl in tables:
99
+ ctx = orch.get_schema_context(tbl)
100
+ result[tbl] = _serialize_schema_context(ctx)
101
+ result[tbl]["schema_hash"] = _compute_schema_hash(ctx)
102
+ return result
103
+
104
+
105
+ @mcp.tool()
106
+ def sqlseed_generate_yaml(
107
+ db_path: str,
108
+ table_name: str,
109
+ max_retries: int = 3,
110
+ api_key: str | None = None,
111
+ base_url: str | None = None,
112
+ model: str | None = None,
113
+ ) -> str:
114
+ """Generate YAML config for a table using AI analysis with self-correction.
115
+ Returns YAML string for human review. Requires sqlseed-ai plugin and API key."""
116
+ if not _AI_AVAILABLE:
117
+ return "# No AI suggestions available. Ensure sqlseed-ai plugin is installed and API key is configured."
118
+
119
+ db_path = _validate_db_path(db_path)
120
+ with DataOrchestrator(db_path) as orch:
121
+ _validate_table_name(table_name, orch.get_table_names())
122
+
123
+ ai_config = AIConfig.from_env().apply_overrides(api_key=api_key, base_url=base_url, model=model)
124
+
125
+ ai_config.resolve_model()
126
+
127
+ analyzer = SchemaAnalyzer(config=ai_config)
128
+ refiner = AiConfigRefiner(analyzer, db_path)
129
+
130
+ try:
131
+ result = refiner.generate_and_refine(
132
+ table_name=table_name,
133
+ max_retries=max_retries,
134
+ )
135
+ except AISuggestionFailedError as e:
136
+ return f"# AI suggestion failed: {e}"
137
+ except (ValueError, RuntimeError, OSError) as e:
138
+ return f"# Error: {e}"
139
+
140
+ if result:
141
+ output = {"db_path": db_path, "provider": "mimesis", "locale": "en_US", "tables": [result]}
142
+ return str(yaml.dump(output, allow_unicode=True, sort_keys=False, default_flow_style=False))
143
+ return "# No AI suggestions available. Ensure sqlseed-ai plugin is installed and API key is configured."
144
+
145
+
146
+ @mcp.tool()
147
+ def sqlseed_execute_fill(
148
+ db_path: str,
149
+ table_name: str,
150
+ count: int = 1000,
151
+ yaml_config: str | None = None,
152
+ enrich: bool = False,
153
+ ) -> dict[str, Any]:
154
+ """Execute data generation for a table. Optionally provide YAML config string for column rules."""
155
+ db_path = _validate_db_path(db_path)
156
+
157
+ if yaml_config is not None and len(yaml_config) > _MAX_YAML_CONFIG_SIZE:
158
+ raise ValueError(f"yaml_config exceeds maximum allowed size of {_MAX_YAML_CONFIG_SIZE} bytes")
159
+
160
+ with DataOrchestrator(db_path) as orch:
161
+ _validate_table_name(table_name, orch.get_table_names())
162
+ column_configs = None
163
+ clear_before = False
164
+ seed = None
165
+
166
+ if yaml_config:
167
+ data = yaml.safe_load(yaml_config)
168
+ config = GeneratorConfig(**data)
169
+ for t in config.tables:
170
+ if t.name == table_name:
171
+ column_configs = t.columns
172
+ clear_before = t.clear_before
173
+ seed = t.seed
174
+ break
175
+
176
+ result = orch.fill_table(
177
+ table_name=table_name,
178
+ count=count,
179
+ column_configs=column_configs,
180
+ clear_before=clear_before,
181
+ seed=seed,
182
+ enrich=enrich,
183
+ )
184
+
185
+ return {
186
+ "table_name": result.table_name,
187
+ "count": result.count,
188
+ "elapsed": result.elapsed,
189
+ "errors": result.errors,
190
+ }