mcp-server-sqlseed 0.1.0__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.
- mcp_server_sqlseed-0.1.0/.gitignore +69 -0
- mcp_server_sqlseed-0.1.0/PKG-INFO +20 -0
- mcp_server_sqlseed-0.1.0/pyproject.toml +39 -0
- mcp_server_sqlseed-0.1.0/src/mcp_server_sqlseed/__init__.py +7 -0
- mcp_server_sqlseed-0.1.0/src/mcp_server_sqlseed/__main__.py +6 -0
- mcp_server_sqlseed-0.1.0/src/mcp_server_sqlseed/config.py +9 -0
- mcp_server_sqlseed-0.1.0/src/mcp_server_sqlseed/server.py +148 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Virtual Environment
|
|
24
|
+
.venv/
|
|
25
|
+
env/
|
|
26
|
+
ENV/
|
|
27
|
+
|
|
28
|
+
# IDE
|
|
29
|
+
.vscode/
|
|
30
|
+
.idea/
|
|
31
|
+
*.swp
|
|
32
|
+
*.swo
|
|
33
|
+
*~
|
|
34
|
+
|
|
35
|
+
# Testing
|
|
36
|
+
.pytest_cache/
|
|
37
|
+
.coverage
|
|
38
|
+
htmlcov/
|
|
39
|
+
|
|
40
|
+
# Type checking
|
|
41
|
+
.mypy_cache/
|
|
42
|
+
.dmypy.json
|
|
43
|
+
dmypy.json
|
|
44
|
+
|
|
45
|
+
# Linting
|
|
46
|
+
.ruff_cache/
|
|
47
|
+
|
|
48
|
+
# Project specific
|
|
49
|
+
*.db
|
|
50
|
+
*.sqlite
|
|
51
|
+
*.sqlite3
|
|
52
|
+
snapshots/
|
|
53
|
+
|
|
54
|
+
# AI cache
|
|
55
|
+
.sqlseed_cache/
|
|
56
|
+
|
|
57
|
+
# Archived temp files
|
|
58
|
+
_archived_temp/
|
|
59
|
+
|
|
60
|
+
# macOS
|
|
61
|
+
.DS_Store
|
|
62
|
+
|
|
63
|
+
# Trae IDE
|
|
64
|
+
.trae/
|
|
65
|
+
|
|
66
|
+
# Build artifacts
|
|
67
|
+
dist/
|
|
68
|
+
*.whl
|
|
69
|
+
*.tar.gz
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcp-server-sqlseed
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server for sqlseed - AI-powered SQLite test data generation
|
|
5
|
+
Project-URL: Homepage, https://github.com/sunbos/sqlseed
|
|
6
|
+
Project-URL: Repository, https://github.com/sunbos/sqlseed/tree/main/plugins/mcp-server-sqlseed
|
|
7
|
+
Author-email: SunBo <1443584939@qq.com>
|
|
8
|
+
License-Expression: AGPL-3.0-or-later
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: mcp>=1.0
|
|
18
|
+
Requires-Dist: sqlseed
|
|
19
|
+
Provides-Extra: ai
|
|
20
|
+
Requires-Dist: sqlseed-ai; extra == 'ai'
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "mcp-server-sqlseed"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
requires-python = ">=3.10"
|
|
9
|
+
description = "MCP server for sqlseed - AI-powered SQLite test data generation"
|
|
10
|
+
license = "AGPL-3.0-or-later"
|
|
11
|
+
authors = [
|
|
12
|
+
{name = "SunBo", email = "1443584939@qq.com"},
|
|
13
|
+
]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
]
|
|
23
|
+
dependencies = [
|
|
24
|
+
"sqlseed",
|
|
25
|
+
"mcp>=1.0",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
Homepage = "https://github.com/sunbos/sqlseed"
|
|
30
|
+
Repository = "https://github.com/sunbos/sqlseed/tree/main/plugins/mcp-server-sqlseed"
|
|
31
|
+
|
|
32
|
+
[project.optional-dependencies]
|
|
33
|
+
ai = ["sqlseed-ai"]
|
|
34
|
+
|
|
35
|
+
[project.scripts]
|
|
36
|
+
mcp-server-sqlseed = "mcp_server_sqlseed:main"
|
|
37
|
+
|
|
38
|
+
[tool.hatch.build.targets.wheel]
|
|
39
|
+
packages = ["src/mcp_server_sqlseed"]
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
import json
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from mcp.server.fastmcp import FastMCP
|
|
8
|
+
|
|
9
|
+
mcp = FastMCP("sqlseed")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _serialize_schema_context(ctx: dict[str, Any]) -> dict[str, Any]:
|
|
13
|
+
return {
|
|
14
|
+
"table_name": ctx["table_name"],
|
|
15
|
+
"columns": [
|
|
16
|
+
{
|
|
17
|
+
"name": c.name,
|
|
18
|
+
"type": c.type,
|
|
19
|
+
"nullable": c.nullable,
|
|
20
|
+
"default": c.default,
|
|
21
|
+
"is_primary_key": c.is_primary_key,
|
|
22
|
+
"is_autoincrement": c.is_autoincrement,
|
|
23
|
+
}
|
|
24
|
+
for c in ctx["columns"]
|
|
25
|
+
],
|
|
26
|
+
"foreign_keys": [
|
|
27
|
+
{"column": fk.column, "ref_table": fk.ref_table, "ref_column": fk.ref_column}
|
|
28
|
+
for fk in ctx["foreign_keys"]
|
|
29
|
+
],
|
|
30
|
+
"indexes": ctx["indexes"],
|
|
31
|
+
"sample_data": ctx["sample_data"],
|
|
32
|
+
"all_table_names": ctx["all_table_names"],
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _compute_schema_hash(schema_ctx: dict[str, Any]) -> str:
|
|
37
|
+
hash_input = json.dumps(
|
|
38
|
+
{
|
|
39
|
+
"columns": [
|
|
40
|
+
{"name": c.name, "type": c.type, "nullable": c.nullable}
|
|
41
|
+
for c in schema_ctx["columns"]
|
|
42
|
+
],
|
|
43
|
+
"foreign_keys": [
|
|
44
|
+
{"column": fk.column, "ref_table": fk.ref_table}
|
|
45
|
+
for fk in schema_ctx["foreign_keys"]
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
sort_keys=True,
|
|
49
|
+
)
|
|
50
|
+
return hashlib.sha256(hash_input.encode()).hexdigest()[:16]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@mcp.resource("sqlseed://schema/{db_path}/{table_name}")
|
|
54
|
+
def get_schema_resource(db_path: str, table_name: str) -> str:
|
|
55
|
+
from sqlseed.core.orchestrator import DataOrchestrator
|
|
56
|
+
|
|
57
|
+
with DataOrchestrator(db_path) as orch:
|
|
58
|
+
ctx = orch.get_schema_context(table_name)
|
|
59
|
+
serializable_ctx = _serialize_schema_context(ctx)
|
|
60
|
+
return json.dumps(serializable_ctx, ensure_ascii=False, indent=2)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@mcp.tool()
|
|
64
|
+
def sqlseed_inspect_schema(db_path: str, table_name: str | None = None) -> dict[str, Any]:
|
|
65
|
+
"""Inspect database schema. Returns column info, foreign keys, indexes,
|
|
66
|
+
sample data, and schema_hash for specified table or all tables."""
|
|
67
|
+
from sqlseed.core.orchestrator import DataOrchestrator
|
|
68
|
+
|
|
69
|
+
with DataOrchestrator(db_path) as orch:
|
|
70
|
+
tables = [table_name] if table_name else orch._db.get_table_names()
|
|
71
|
+
result: dict[str, Any] = {}
|
|
72
|
+
for tbl in tables:
|
|
73
|
+
ctx = orch.get_schema_context(tbl)
|
|
74
|
+
result[tbl] = _serialize_schema_context(ctx)
|
|
75
|
+
result[tbl]["schema_hash"] = _compute_schema_hash(ctx)
|
|
76
|
+
return result
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@mcp.tool()
|
|
80
|
+
def sqlseed_generate_yaml(db_path: str, table_name: str, max_retries: int = 3) -> str:
|
|
81
|
+
"""Generate YAML config for a table using AI analysis with self-correction.
|
|
82
|
+
Returns YAML string for human review. Requires sqlseed-ai plugin and API key."""
|
|
83
|
+
import yaml
|
|
84
|
+
from sqlseed_ai.analyzer import SchemaAnalyzer
|
|
85
|
+
from sqlseed_ai.refiner import AiConfigRefiner, AISuggestionFailedError
|
|
86
|
+
|
|
87
|
+
analyzer = SchemaAnalyzer()
|
|
88
|
+
refiner = AiConfigRefiner(analyzer, db_path)
|
|
89
|
+
|
|
90
|
+
try:
|
|
91
|
+
result = refiner.generate_and_refine(
|
|
92
|
+
table_name=table_name,
|
|
93
|
+
max_retries=max_retries,
|
|
94
|
+
)
|
|
95
|
+
except AISuggestionFailedError as e:
|
|
96
|
+
return f"# AI suggestion failed: {e}"
|
|
97
|
+
except Exception as e:
|
|
98
|
+
return f"# Error: {e}"
|
|
99
|
+
|
|
100
|
+
if result:
|
|
101
|
+
output = {"db_path": db_path, "provider": "mimesis", "locale": "zh_CN", "tables": [result]}
|
|
102
|
+
return yaml.dump(output, allow_unicode=True, sort_keys=False, default_flow_style=False)
|
|
103
|
+
return "# No AI suggestions available. Ensure sqlseed-ai plugin is installed and API key is configured."
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@mcp.tool()
|
|
107
|
+
def sqlseed_execute_fill(
|
|
108
|
+
db_path: str,
|
|
109
|
+
table_name: str,
|
|
110
|
+
count: int = 1000,
|
|
111
|
+
yaml_config: str | None = None,
|
|
112
|
+
) -> dict[str, Any]:
|
|
113
|
+
"""Execute data generation for a table. Optionally provide YAML config string for column rules."""
|
|
114
|
+
from sqlseed.core.orchestrator import DataOrchestrator
|
|
115
|
+
|
|
116
|
+
with DataOrchestrator(db_path) as orch:
|
|
117
|
+
column_configs = None
|
|
118
|
+
clear_before = False
|
|
119
|
+
seed = None
|
|
120
|
+
|
|
121
|
+
if yaml_config:
|
|
122
|
+
import yaml as _yaml
|
|
123
|
+
|
|
124
|
+
from sqlseed.config.models import GeneratorConfig
|
|
125
|
+
|
|
126
|
+
data = _yaml.safe_load(yaml_config)
|
|
127
|
+
config = GeneratorConfig(**data)
|
|
128
|
+
for t in config.tables:
|
|
129
|
+
if t.name == table_name:
|
|
130
|
+
column_configs = t.columns
|
|
131
|
+
clear_before = t.clear_before
|
|
132
|
+
seed = t.seed
|
|
133
|
+
break
|
|
134
|
+
|
|
135
|
+
result = orch.fill_table(
|
|
136
|
+
table_name=table_name,
|
|
137
|
+
count=count,
|
|
138
|
+
column_configs=column_configs,
|
|
139
|
+
clear_before=clear_before,
|
|
140
|
+
seed=seed,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
"table_name": result.table_name,
|
|
145
|
+
"count": result.count,
|
|
146
|
+
"elapsed": result.elapsed,
|
|
147
|
+
"errors": result.errors,
|
|
148
|
+
}
|