text2sql-mcp 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.
@@ -0,0 +1,21 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .venv/
8
+ venv/
9
+
10
+ # Tooling
11
+ .python-version
12
+ .pytest_cache/
13
+ .ruff_cache/
14
+
15
+ # OS / editors
16
+ .DS_Store
17
+ .idea/
18
+ .vscode/
19
+
20
+ # Local-only files
21
+ HANDOFF.md
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Cooper Penniman
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,94 @@
1
+ Metadata-Version: 2.4
2
+ Name: text2sql-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server for text2sql-framework. Lets any MCP-compatible assistant (Claude Desktop, Cursor, Goose, etc.) ask a SQL database questions in natural language.
5
+ Project-URL: Homepage, https://github.com/cpenniman12/text2sql-mcp
6
+ Project-URL: Repository, https://github.com/cpenniman12/text2sql-mcp
7
+ Project-URL: Bug Tracker, https://github.com/cpenniman12/text2sql-mcp/issues
8
+ Project-URL: text2sql-framework, https://github.com/cpenniman12/text2sql-framework
9
+ Author: Cooper Penniman
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: ai,claude,database,goose,llm,mcp,natural-language,sql,text-to-sql
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Database
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: langchain-anthropic>=0.3
25
+ Requires-Dist: mcp>=1.0
26
+ Requires-Dist: text2sql-framework>=0.3
27
+ Provides-Extra: openai
28
+ Requires-Dist: langchain-openai>=0.3; extra == 'openai'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # text2sql-mcp
32
+
33
+ MCP server for [text2sql-framework](https://github.com/cpenniman12/text2sql-framework). Plugs into Claude Desktop, Cursor, Goose, or any other MCP-compatible assistant and lets it ask a SQL database questions in natural language.
34
+
35
+ The agent explores the schema, writes SQL, executes it against the real DB, and self-corrects on errors — no RAG layer, no schema descriptions, no pre-computed embeddings.
36
+
37
+ ## Install
38
+
39
+ ```bash
40
+ pip install text2sql-mcp
41
+ # or
42
+ uvx text2sql-mcp
43
+ ```
44
+
45
+ ## Configure
46
+
47
+ Set environment variables in your MCP client config:
48
+
49
+ | Variable | Required | Description |
50
+ | --- | --- | --- |
51
+ | `TEXT2SQL_DATABASE_URL` | yes | SQLAlchemy URL, e.g. `sqlite:///mydb.db`, `postgresql://user:pass@host/db` |
52
+ | `ANTHROPIC_API_KEY` *or* `OPENAI_API_KEY` | yes | LLM provider key |
53
+ | `TEXT2SQL_MODEL` | no | LangChain model id (default: `anthropic:claude-sonnet-4-6`) |
54
+ | `TEXT2SQL_INSTRUCTIONS` | no | Business rules / hints, e.g. "Revenue = net of refunds." |
55
+ | `TEXT2SQL_EXAMPLES` | no | Path to a scenarios.md file for the agent's `lookup_example` tool |
56
+
57
+ ### Claude Desktop / Cursor / generic MCP
58
+
59
+ ```json
60
+ {
61
+ "mcpServers": {
62
+ "text2sql": {
63
+ "command": "uvx",
64
+ "args": ["text2sql-mcp"],
65
+ "env": {
66
+ "TEXT2SQL_DATABASE_URL": "sqlite:///mydb.db",
67
+ "ANTHROPIC_API_KEY": "sk-ant-..."
68
+ }
69
+ }
70
+ }
71
+ }
72
+ ```
73
+
74
+ ### Goose CLI
75
+
76
+ ```bash
77
+ goose configure
78
+ # Add Extension → Command-line Extension
79
+ # Name: text2sql
80
+ # Command: uvx text2sql-mcp
81
+ # Env: TEXT2SQL_DATABASE_URL, ANTHROPIC_API_KEY
82
+ ```
83
+
84
+ ## Tools
85
+
86
+ - **`query(question, max_rows=100)`** — ask the database a natural-language question. Returns `{sql, data, error, row_count, tool_calls_made}`.
87
+
88
+ ## How it works
89
+
90
+ Under the hood this is a thin wrapper around [text2sql-framework](https://github.com/cpenniman12/text2sql-framework), which uses LangChain Deep Agents to do iterative tool-calling against a single `execute_sql` tool. See the framework README for benchmarks (19/20 on Spider zero-shot across 80 tables) and architecture details.
91
+
92
+ ## License
93
+
94
+ MIT
@@ -0,0 +1,64 @@
1
+ # text2sql-mcp
2
+
3
+ MCP server for [text2sql-framework](https://github.com/cpenniman12/text2sql-framework). Plugs into Claude Desktop, Cursor, Goose, or any other MCP-compatible assistant and lets it ask a SQL database questions in natural language.
4
+
5
+ The agent explores the schema, writes SQL, executes it against the real DB, and self-corrects on errors — no RAG layer, no schema descriptions, no pre-computed embeddings.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install text2sql-mcp
11
+ # or
12
+ uvx text2sql-mcp
13
+ ```
14
+
15
+ ## Configure
16
+
17
+ Set environment variables in your MCP client config:
18
+
19
+ | Variable | Required | Description |
20
+ | --- | --- | --- |
21
+ | `TEXT2SQL_DATABASE_URL` | yes | SQLAlchemy URL, e.g. `sqlite:///mydb.db`, `postgresql://user:pass@host/db` |
22
+ | `ANTHROPIC_API_KEY` *or* `OPENAI_API_KEY` | yes | LLM provider key |
23
+ | `TEXT2SQL_MODEL` | no | LangChain model id (default: `anthropic:claude-sonnet-4-6`) |
24
+ | `TEXT2SQL_INSTRUCTIONS` | no | Business rules / hints, e.g. "Revenue = net of refunds." |
25
+ | `TEXT2SQL_EXAMPLES` | no | Path to a scenarios.md file for the agent's `lookup_example` tool |
26
+
27
+ ### Claude Desktop / Cursor / generic MCP
28
+
29
+ ```json
30
+ {
31
+ "mcpServers": {
32
+ "text2sql": {
33
+ "command": "uvx",
34
+ "args": ["text2sql-mcp"],
35
+ "env": {
36
+ "TEXT2SQL_DATABASE_URL": "sqlite:///mydb.db",
37
+ "ANTHROPIC_API_KEY": "sk-ant-..."
38
+ }
39
+ }
40
+ }
41
+ }
42
+ ```
43
+
44
+ ### Goose CLI
45
+
46
+ ```bash
47
+ goose configure
48
+ # Add Extension → Command-line Extension
49
+ # Name: text2sql
50
+ # Command: uvx text2sql-mcp
51
+ # Env: TEXT2SQL_DATABASE_URL, ANTHROPIC_API_KEY
52
+ ```
53
+
54
+ ## Tools
55
+
56
+ - **`query(question, max_rows=100)`** — ask the database a natural-language question. Returns `{sql, data, error, row_count, tool_calls_made}`.
57
+
58
+ ## How it works
59
+
60
+ Under the hood this is a thin wrapper around [text2sql-framework](https://github.com/cpenniman12/text2sql-framework), which uses LangChain Deep Agents to do iterative tool-calling against a single `execute_sql` tool. See the framework README for benchmarks (19/20 on Spider zero-shot across 80 tables) and architecture details.
61
+
62
+ ## License
63
+
64
+ MIT
@@ -0,0 +1,47 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "text2sql-mcp"
7
+ version = "0.1.0"
8
+ description = "MCP server for text2sql-framework. Lets any MCP-compatible assistant (Claude Desktop, Cursor, Goose, etc.) ask a SQL database questions in natural language."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ authors = [
13
+ { name = "Cooper Penniman" },
14
+ ]
15
+ keywords = ["mcp", "sql", "llm", "text-to-sql", "ai", "database", "natural-language", "goose", "claude"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Topic :: Database",
26
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
27
+ ]
28
+ dependencies = [
29
+ "mcp>=1.0",
30
+ "text2sql-framework>=0.3",
31
+ "langchain-anthropic>=0.3",
32
+ ]
33
+
34
+ [project.optional-dependencies]
35
+ openai = ["langchain-openai>=0.3"]
36
+
37
+ [project.scripts]
38
+ text2sql-mcp = "text2sql_mcp.server:main"
39
+
40
+ [project.urls]
41
+ Homepage = "https://github.com/cpenniman12/text2sql-mcp"
42
+ Repository = "https://github.com/cpenniman12/text2sql-mcp"
43
+ "Bug Tracker" = "https://github.com/cpenniman12/text2sql-mcp/issues"
44
+ "text2sql-framework" = "https://github.com/cpenniman12/text2sql-framework"
45
+
46
+ [tool.hatch.build.targets.wheel]
47
+ packages = ["text2sql_mcp"]
@@ -0,0 +1,3 @@
1
+ """MCP server for text2sql-framework."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,94 @@
1
+ """MCP server exposing text2sql-framework as a single `query` tool.
2
+
3
+ Configuration is read from environment variables:
4
+ TEXT2SQL_DATABASE_URL (required) SQLAlchemy URL, e.g. sqlite:///mydb.db
5
+ TEXT2SQL_MODEL (optional) LangChain model id (default: anthropic:claude-sonnet-4-6)
6
+ TEXT2SQL_INSTRUCTIONS (optional) Free-text business rules / hints
7
+ TEXT2SQL_EXAMPLES (optional) Path to a scenarios.md file
8
+
9
+ Plus the usual provider key — ANTHROPIC_API_KEY or OPENAI_API_KEY —
10
+ which text2sql-framework reads via LangChain.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import os
16
+ import sys
17
+ from typing import Any
18
+
19
+ from mcp.server.fastmcp import FastMCP
20
+
21
+ _engine = None
22
+
23
+
24
+ def _get_engine():
25
+ """Lazily build the TextSQL engine on first use."""
26
+ global _engine
27
+ if _engine is not None:
28
+ return _engine
29
+
30
+ db_url = os.environ.get("TEXT2SQL_DATABASE_URL")
31
+ if not db_url:
32
+ raise RuntimeError(
33
+ "TEXT2SQL_DATABASE_URL is not set. "
34
+ "Provide a SQLAlchemy connection string, e.g. sqlite:///mydb.db"
35
+ )
36
+
37
+ from text2sql import TextSQL
38
+
39
+ kwargs: dict[str, Any] = {}
40
+ if model := os.environ.get("TEXT2SQL_MODEL"):
41
+ kwargs["model"] = model
42
+ if instructions := os.environ.get("TEXT2SQL_INSTRUCTIONS"):
43
+ kwargs["instructions"] = instructions
44
+ if examples := os.environ.get("TEXT2SQL_EXAMPLES"):
45
+ kwargs["examples"] = examples
46
+
47
+ _engine = TextSQL(db_url, **kwargs)
48
+ return _engine
49
+
50
+
51
+ mcp = FastMCP("text2sql")
52
+
53
+
54
+ @mcp.tool()
55
+ def query(question: str, max_rows: int = 100) -> dict:
56
+ """Ask the database a natural-language question.
57
+
58
+ The agent explores the schema, writes SQL, executes it, and self-corrects
59
+ on errors before returning. Read-only — only SELECT-style statements.
60
+
61
+ Args:
62
+ question: The natural-language question, e.g. "top 5 customers by revenue".
63
+ max_rows: Cap on rows returned in `data`. Defaults to 100.
64
+
65
+ Returns:
66
+ dict with:
67
+ sql: the final verified SQL
68
+ data: list of row dicts (capped at max_rows)
69
+ error: error message if execution failed, else None
70
+ row_count: number of rows in `data`
71
+ tool_calls_made: how many SQL calls the agent made while exploring
72
+ """
73
+ engine = _get_engine()
74
+ result = engine.ask(question, max_rows=max_rows)
75
+ return {
76
+ "sql": result.sql,
77
+ "data": result.data,
78
+ "error": result.error,
79
+ "row_count": len(result.data),
80
+ "tool_calls_made": result.tool_calls_made,
81
+ }
82
+
83
+
84
+ def main() -> None:
85
+ """Entry point for the `text2sql-mcp` console script."""
86
+ try:
87
+ mcp.run()
88
+ except Exception as exc:
89
+ print(f"text2sql-mcp failed: {exc}", file=sys.stderr)
90
+ raise
91
+
92
+
93
+ if __name__ == "__main__":
94
+ main()