Skip to content

Commit b13724a

Browse files
committed
MCP: Add example about MCP Alchemy
1 parent 00f4197 commit b13724a

File tree

4 files changed

+97
-0
lines changed

4 files changed

+97
-0
lines changed

framework/mcp/README.md

+7
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ program.
3636
Server for JDBC] from the [quarkus-mcp-servers] package, providing a range
3737
of tools. It is written in Java, to be invoked with [JBang].
3838

39+
- `example_mcp_alchemy.py`: Exercise communication using the [MCP Alchemy] MCP
40+
server package, providing a range of tools. It is written in Python, and uses
41+
[SQLAlchemy] and the [CrateDB SQLAlchemy dialect].
42+
3943
## Resources
4044

4145
- Read a [brief introduction to MCP] by ByteByteGo.
@@ -124,10 +128,12 @@ unlocking more details and features.
124128
[Claude Desktop configuration]: https://github.com/modelcontextprotocol/servers?tab=readme-ov-file#using-an-mcp-client
125129
[connecting to an already running MCP server]: https://github.com/modelcontextprotocol/python-sdk/issues/145
126130
[CrateDB]: https://cratedb.com/database
131+
[CrateDB SQLAlchemy dialect]: https://cratedb.com/docs/sqlalchemy-cratedb/
127132
[DBHub]: https://github.com/bytebase/dbhub
128133
[Introduction to MCP]: https://modelcontextprotocol.io/introduction
129134
[JBang]: https://www.jbang.dev/
130135
[MCP]: https://modelcontextprotocol.io/
136+
[MCP Alchemy]: https://github.com/runekaagaard/mcp-alchemy
131137
[MCP Python SDK]: https://github.com/modelcontextprotocol/python-sdk
132138
[MCP SSE]: https://github.com/sidharthrajaram/mcp-sse
133139
[Model Context Protocol (MCP) @ CrateDB]: https://github.com/crate/crate-clients-tools/discussions/234
@@ -137,5 +143,6 @@ unlocking more details and features.
137143
[npx]: https://docs.npmjs.com/cli/v11/commands/npx
138144
[oterm configuration]: https://ggozad.github.io/oterm/tools/mcp/
139145
[quarkus-mcp-servers]: https://github.com/quarkiverse/quarkus-mcp-servers
146+
[SQLAlchemy]: https://sqlalchemy.org/
140147
[uv]: https://docs.astral.sh/uv/
141148
[Writing MCP Clients]: https://github.com/modelcontextprotocol/python-sdk?tab=readme-ov-file#writing-mcp-clients

framework/mcp/example_mcp_alchemy.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# MCP Alchemy Model Context Protocol Server for CrateDB
2+
# https://github.com/runekaagaard/mcp-alchemy
3+
#
4+
# Derived from:
5+
# https://github.com/modelcontextprotocol/python-sdk?tab=readme-ov-file#writing-mcp-clients
6+
from cratedb_toolkit.util import DatabaseAdapter
7+
from mcp import ClientSession, StdioServerParameters
8+
from mcp.client.stdio import stdio_client
9+
import where
10+
11+
from mcp_utils import McpDatabaseConversation
12+
13+
# Create server parameters for stdio connection.
14+
server_params = StdioServerParameters(
15+
command=where.first("mcp-alchemy"),
16+
args=[],
17+
env={"DB_URL": "crate://crate@localhost:4200/?schema=testdrive"},
18+
)
19+
20+
async def run():
21+
async with stdio_client(server_params) as (read, write):
22+
async with ClientSession(
23+
read, write
24+
) as session:
25+
# Initialize the connection.
26+
await session.initialize()
27+
28+
client = McpDatabaseConversation(session)
29+
await client.inquire()
30+
31+
print("## MCP server conversations")
32+
print()
33+
34+
# Provision database content.
35+
db = DatabaseAdapter("crate://crate@localhost:4200/")
36+
db.run_sql("CREATE TABLE IF NOT EXISTS mcp_alchemy (id INT, data TEXT)")
37+
db.run_sql("INSERT INTO mcp_alchemy (id, data) VALUES (42, 'Hotzenplotz')")
38+
db.refresh_table("mcp_alchemy")
39+
40+
# Call a few tools.
41+
await client.call_tool("execute_query", arguments={"query": "SELECT * FROM sys.summits ORDER BY height DESC LIMIT 3"})
42+
await client.call_tool("all_table_names", arguments={})
43+
await client.call_tool("filter_table_names", arguments={"q": "mcp"})
44+
await client.call_tool("schema_definitions", arguments={"table_names": ["mcp_alchemy"]})
45+
46+
47+
if __name__ == "__main__":
48+
import asyncio
49+
50+
asyncio.run(run())

framework/mcp/requirements.txt

+3
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
cratedb-toolkit
22
mcp<1.5
3+
mcp-alchemy @ git+https://github.com/runekaagaard/mcp-alchemy.git@f42aaf0
4+
sqlalchemy-cratedb>=0.42.0.dev1
5+
where

framework/mcp/test.py

+37
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,40 @@ def test_dbhub():
116116
assert b"Getting prompt: explain_db" in p.stdout
117117
assert b"Table: mcp_dbhub in schema 'testdrive'" in p.stdout
118118
assert b"Structure:\\n- id (integer)\\n- data (text)" in p.stdout
119+
120+
121+
def test_mcp_alchemy():
122+
"""
123+
Validate the MCP Alchemy server works well.
124+
125+
MCP Alchemy connects Claude Desktop directly to your databases.
126+
MCP Alchemy is a MCP (model context protocol) server that gives the LLM access
127+
to and knowledge about relational databases like SQLite, Postgresql, MySQL &
128+
MariaDB, Oracle, MS-SQL, and CrateDB.
129+
130+
It is written in Python and uses SQLAlchemy.
131+
https://github.com/runekaagaard/mcp-alchemy
132+
"""
133+
p = run(f"{sys.executable} example_mcp_alchemy.py")
134+
assert p.returncode == 0
135+
136+
# Validate output specific to the MCP server.
137+
assert b"Processing request of type" in p.stderr
138+
assert b"ListPromptsRequest" in p.stderr
139+
assert b"ListResourcesRequest" in p.stderr
140+
assert b"ListToolsRequest" in p.stderr
141+
assert b"CallToolRequest" in p.stderr
142+
143+
# Validate output specific to CrateDB.
144+
assert b"Calling tool: execute_query" in p.stdout
145+
assert b"mountain: Mont Blanc" in p.stdout
146+
147+
assert b"Calling tool: all_table_names" in p.stdout
148+
assert b"mcp_alchemy" in p.stdout
149+
150+
assert b"Calling tool: filter_table_names" in p.stdout
151+
assert b"mcp_alchemy" in p.stdout
152+
153+
assert b"Calling tool: schema_definitions" in p.stdout
154+
assert b"id: INTEGER, nullable" in p.stdout
155+
assert b"data: VARCHAR, nullable" in p.stdout

0 commit comments

Comments
 (0)