Skip to content

Commit f79bad0

Browse files
authored
Add Smithery platform integration (#131)
* Smithery configuration * --amend
1 parent f24581f commit f79bad0

8 files changed

Lines changed: 162 additions & 65 deletions

File tree

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ repos:
7878
- simpleeval>=1.0.3
7979
- fastmcp>=0.1.0
8080
- pandera>=0.22.0
81+
- smithery>=0.4.2
8182
- .
8283
args: ['--config-file', 'pyproject.toml']
8384
pass_filenames: true

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ dependencies = [
6767
"fastapi>=0.117.1",
6868
"uvicorn>=0.36.0",
6969
"fastmcp>=2.12.4",
70+
"smithery>=0.4.2",
7071
]
7172

7273

@@ -255,6 +256,7 @@ module = [
255256
"fastparquet",
256257
"pytest",
257258
"simpleeval",
259+
"smithery",
258260
]
259261
ignore_missing_imports = true
260262

@@ -357,6 +359,9 @@ site_author = "Santosh Ray"
357359
repo_url = "https://github.com/jonpspri/databeak"
358360
repo_name = "databeak"
359361

362+
[tool.smithery]
363+
server = "databeak.server:create_server"
364+
360365
[dependency-groups]
361366
dev = [
362367
"mdformat>=0.7.22",

smithery.yaml

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,2 @@
11
---
2-
# Smithery configuration file: https://smithery.ai/docs/build/project-config
3-
4-
startCommand:
5-
type: stdio
6-
commandFunction:
7-
# A JS function that produces the CLI command based on the given config
8-
# to start the MCP on stdio.
9-
|-
10-
(config) => ({command: 'databeak', args: ['--transport', 'stdio']})
11-
configSchema:
12-
# JSON Schema defining the configuration options for the MCP.
13-
type: object
14-
default: {}
15-
description:
16-
No configuration necessary to run the DataBeak MCP server. Supply
17-
an empty object.
18-
exampleConfig: {}
2+
runtime: python

src/databeak/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
__author__ = "Jonathan Springer"
44

55
from ._version import __version__
6-
from .server import main, mcp
6+
from .server import main
77

8-
__all__ = ["__version__", "main", "mcp"]
8+
__all__ = ["__version__", "main"]

src/databeak/server.py

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from pathlib import Path
99

1010
from fastmcp import FastMCP
11+
from smithery.decorators import smithery
1112

1213
from databeak._version import __version__
1314

@@ -51,30 +52,15 @@ def _load_instructions() -> str:
5152
# Initialize relaxed JSON schema validation before creating server
5253
initialize_relaxed_validation()
5354

54-
# Initialize FastMCP server
55-
mcp = FastMCP("DataBeak", instructions=_load_instructions(), version=__version__)
56-
5755
# All tools have been migrated to specialized servers
5856
# No direct tool registration needed - using server composition pattern
5957

60-
# Mount specialized servers
61-
mcp.mount(system_server)
62-
mcp.mount(io_server)
63-
mcp.mount(row_operations_server)
64-
mcp.mount(statistics_server)
65-
mcp.mount(discovery_server)
66-
mcp.mount(validation_server)
67-
mcp.mount(transformation_server)
68-
mcp.mount(column_server)
69-
mcp.mount(column_text_server)
70-
7158

7259
# ============================================================================
7360
# PROMPTS
7461
# ============================================================================
7562

7663

77-
@mcp.prompt
7864
def analyze_csv_prompt(session_id: str, analysis_type: str = "summary") -> str:
7965
"""Generate a prompt to analyze CSV data."""
8066
return f"""Please analyze the CSV data in session {session_id}.
@@ -89,7 +75,6 @@ def analyze_csv_prompt(session_id: str, analysis_type: str = "summary") -> str:
8975
"""
9076

9177

92-
@mcp.prompt
9378
def data_cleaning_prompt(session_id: str) -> str:
9479
"""Generate a prompt for data cleaning suggestions."""
9580
return f"""Review the data in session {session_id} and suggest cleaning operations.
@@ -108,6 +93,27 @@ def data_cleaning_prompt(session_id: str) -> str:
10893
# ============================================================================
10994

11095

96+
@smithery.server()
97+
def create_server() -> FastMCP:
98+
"""Create and return the FastMCP server instance."""
99+
# Initialize FastMCP server
100+
mcp = FastMCP("DataBeak", instructions=_load_instructions(), version=__version__)
101+
# Mount specialized servers
102+
mcp.mount(system_server)
103+
mcp.mount(io_server)
104+
mcp.mount(row_operations_server)
105+
mcp.mount(statistics_server)
106+
mcp.mount(discovery_server)
107+
mcp.mount(validation_server)
108+
mcp.mount(transformation_server)
109+
mcp.mount(column_server)
110+
mcp.mount(column_text_server)
111+
112+
mcp.prompt()(analyze_csv_prompt)
113+
mcp.prompt()(data_cleaning_prompt)
114+
return mcp
115+
116+
111117
def main() -> None:
112118
"""Start the DataBeak server."""
113119
parser = ArgumentParser(description="DataBeak")
@@ -152,7 +158,7 @@ def main() -> None:
152158
run_args["port"] = args.port
153159

154160
# Run the server
155-
mcp.run(**run_args) # type: ignore[arg-type]
161+
create_server().run(**run_args)
156162

157163

158164
if __name__ == "__main__":

tests/integration/conftest.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,12 @@ async def test_something(databeak_client : Client):
7171
result = await databeak_client.call_tool("get_session_info", {})
7272
assert result.is_error is False
7373
"""
74-
# Import the server instance
75-
from databeak.server import mcp
74+
# Create the server instance
75+
from databeak.server import create_server
76+
77+
smithery_server = create_server()
78+
# Extract the underlying FastMCP instance from the Smithery wrapper
79+
mcp = smithery_server._fastmcp
7680

7781
# Create FastMCP Client with direct server connection
7882
async with Client(mcp) as client:

0 commit comments

Comments
 (0)