singlestore-mcp-server 0.1.2__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,15 @@
1
+ # Copy this file to .env and fill in your values
2
+
3
+ # SingleStore's management API key
4
+ SINGLESTORE_API_KEY=your_api_key_here
5
+
6
+ # Username for connecting with the SingleStore database.
7
+ # It is optional, it can also be provided as a part of input
8
+ SINGLESTORE_DB_USERNAME=your_db_username_here
9
+
10
+ # Password for authenticating with the SingleStore database.
11
+ # It is optional, it can also be provided as a part of input
12
+ SINGLESTORE_DB_PASSWORD=your_db_password_here
13
+
14
+ # Note: Never commit the actual .env file with credentials to version control
15
+ # Add .env to your .gitignore file
@@ -0,0 +1,37 @@
1
+ name: Publish Python Package
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - ci/update-package-version-on-github-action # TODO: Remove this branch after testing
8
+ workflow_dispatch: # Allows manual triggering
9
+
10
+ jobs:
11
+ publish:
12
+ runs-on: ubuntu-latest
13
+ environment: release
14
+ permissions:
15
+ id-token: write # OIDC authentication with PyPI
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v4
22
+ with:
23
+ python-version: '3.11'
24
+
25
+ - name: Install dependencies
26
+ run: |
27
+ python -m pip install --upgrade pip
28
+ pip install build twine
29
+ pip install -r requirements.txt
30
+
31
+ - name: Build package
32
+ run: python -m build
33
+
34
+ - name: Publish package to PyPI
35
+ uses: pypa/gh-action-pypi-publish@release/v1
36
+ with:
37
+ password: ${{ secrets.PYPI_API_KEY }}
@@ -0,0 +1,52 @@
1
+ # Configuration files
2
+ config/
3
+
4
+ # Byte-compiled / optimized / DLL files
5
+ __pycache__/
6
+ *.py[cod]
7
+ *$py.class
8
+
9
+ # C extensions
10
+ *.so
11
+
12
+ # Distribution / packaging
13
+ dist/
14
+ build/
15
+ *.egg-info/
16
+ *.egg
17
+
18
+ # Virtual environments
19
+ venv/
20
+ env/
21
+ .env/
22
+ .venv/
23
+
24
+ # IDE specific files
25
+ .idea/
26
+ .vscode/
27
+ *.swp
28
+ *.swo
29
+
30
+ # Python testing
31
+ .pytest_cache/
32
+ .coverage
33
+ htmlcov/
34
+
35
+ # Environment variables
36
+ .env
37
+ .env.local
38
+
39
+ # Logs
40
+ *.log
41
+
42
+ # Local development settings
43
+ config/settings.local.toml
44
+
45
+ # Cache files
46
+ .mypy_cache/
47
+ .dmypy.json
48
+ dmypy.json
49
+
50
+ # Tool specific
51
+ tool_result.txt
52
+ .DS_Store
@@ -0,0 +1,28 @@
1
+ # Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile
2
+ FROM python:3.11-alpine
3
+
4
+ # Set working directory
5
+ WORKDIR /app
6
+
7
+ # Install build dependencies
8
+ RUN apk add --no-cache gcc musl-dev linux-headers
9
+
10
+ # Copy requirements and project files
11
+ COPY pyproject.toml ./
12
+ COPY requirements.txt ./
13
+ COPY README.md ./
14
+ COPY src/ ./src/
15
+ COPY uv.lock ./
16
+
17
+ # Install pipenv system dependencies
18
+ # Install project dependencies using pip
19
+ RUN pip install --upgrade pip \
20
+ && pip install --ignore-installed -r requirements.txt || true
21
+
22
+ # Install project using Hatchling build
23
+ RUN pip install hatchling \
24
+ && pip install .
25
+
26
+ # Expose any port if needed (not strictly needed for stdio based server)
27
+
28
+ CMD ["python", "src/server/server.py"]
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 - 2025 SingleStore Inc.
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,141 @@
1
+ Metadata-Version: 2.4
2
+ Name: singlestore_mcp_server
3
+ Version: 0.1.2
4
+ Summary: SingleStore MCP server
5
+ License-File: LICENSE
6
+ Requires-Python: >=3.11
7
+ Requires-Dist: mcp>=1.3.0
8
+ Requires-Dist: singlestoredb>=1.12.0
9
+ Description-Content-Type: text/markdown
10
+
11
+ # SingleStore MCP Server
12
+
13
+ [![PyPI version](https://img.shields.io/pypi/v/singlestore-mcp-server)](https://pypi.org/project/singlestore_mcp_server/)
14
+ [![PyPI downloads](https://img.shields.io/pypi/dm/singlestore-mcp-server)](https://pypi.org/project/singlestore_mcp_server/)
15
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
16
+ [![smithery badge](https://smithery.ai/badge/@singlestore-labs/mcp-server-singlestore)](https://smithery.ai/server/@singlestore-labs/mcp-server-singlestore)
17
+
18
+ [Model Context Protocol]((https://modelcontextprotocol.io/introduction)) (MCP) is a standardized protocol designed to manage context between large language models (LLMs) and external systems. This repository provides an installer and an MCP Server for Singlestore, enabling seamless integration.
19
+
20
+ With MCP, you can use Claude Desktop or any compatible MCP client to interact with SingleStore using natural language, making it easier to perform complex operations effortlessly.
21
+
22
+ ## Claude Setup
23
+
24
+ ### Installing via Smithery
25
+
26
+ To install mcp-server-singlestore for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@singlestore-labs/mcp-server-singlestore):
27
+
28
+ ```bash
29
+ npx -y @smithery/cli install @singlestore-labs/mcp-server-singlestore --client claude
30
+ ```
31
+
32
+ ## Requirements
33
+
34
+ - Python >= v3.11.0
35
+ - [Pipx](https://pipx.pypa.io/stable/) installed on your python environment
36
+ - Claude Desktop
37
+
38
+ ## How to use locally
39
+
40
+ 1. Add the following config to your Claude Desktop [config file](https://modelcontextprotocol.io/quickstart/user)
41
+ 2. Restart Claude Desktop after making changes to the configuration
42
+
43
+ ```json
44
+ {
45
+ "mcpServers": {
46
+ "singlestore-mcp-server": {
47
+ "command": "pipx",
48
+ "args": [
49
+ "run",
50
+ "singlestore-mcp-server"
51
+ ],
52
+ "env": {
53
+ "SINGLESTORE_DB_USERNAME": "your-database-username",
54
+ "SINGLESTORE_DB_PASSWORD": "your-database-password",
55
+ "SINGLESTORE_API_KEY": "your-api-key"
56
+ }
57
+ }
58
+ }
59
+ }
60
+ ```
61
+
62
+ Note:
63
+
64
+ You can get your API key and DB credentials on SingleStore's [Helios Portal](https://portal.singlestore.com/intention/cloud)
65
+
66
+ ## Components
67
+
68
+ ### Tools
69
+
70
+ The server implements the following tools:
71
+
72
+ - **workspace_groups_info**: Retrieve details about the workspace groups accessible to the user
73
+ - No arguments required
74
+ - Returns details of the workspace groups
75
+ - **workspaces_info**: Retrieve details about the workspaces in a specific workspace group
76
+ - Arguments: `workspaceGroupID` (string)
77
+ - Returns details of the workspaces
78
+ - **organization_info**: Retrieve details about the user's current organization
79
+ - No arguments required
80
+ - Returns details of the organization
81
+ - **list_of_regions**: Retrieve a list of all regions that support workspaces for the user
82
+ - No arguments required
83
+ - Returns a list of regions
84
+ - **execute_sql**: Execute SQL operations on a connected workspace
85
+ - Arguments: `workspace_group_identifier`, `workspace_identifier`, `username`, `password`, `database`, `sql_query`
86
+ - Returns the results of the SQL query in a structured format
87
+ - **list_virtual_workspaces**: List all starter workspaces accessible to the user
88
+ - No arguments required
89
+ - Returns details of available starter workspaces
90
+ - **create_virtual_workspace**: Create a new starter workspace with a user
91
+ - Arguments:
92
+ - `name`: Name of the starter workspace
93
+ - `database_name`: Name of the database to create
94
+ - `username`: Username for accessing the workspace
95
+ - `password`: Password for the user
96
+ - `workspace_group`: Object containing `name` (optional) and `cellID` (mandatory)
97
+ - Returns details of the created workspace and user
98
+ - **execute_sql_on_virtual_workspace**: Execute SQL operations on a virtual workspace
99
+ - Arguments: `virtual_workspace_id`, `username`, `password`, `sql_query`
100
+ - Returns the results of the SQL query in a structured format including data, row count, columns, and status
101
+ - **list_notebook_samples**: List all notebook samples available in SingleStore Spaces
102
+ - No arguments required
103
+ - Returns details of available notebook samples
104
+ - **create_notebook**: Create a new notebook in the user's personal space
105
+ - Arguments: `notebook_name`, `content` (optional)
106
+ - Returns details of the created notebook
107
+ - **list_personal_files**: List all files in the user's personal space
108
+ - No arguments required
109
+ - Returns details of all files in the user's personal space
110
+ - **create_scheduled_job**: Create a new scheduled job to run a notebook
111
+ - Arguments:
112
+ - `name`: Name for the job
113
+ - `notebook_path`: Path to the notebook to execute
114
+ - `schedule_mode`: Once or Recurring
115
+ - `execution_interval_minutes`: Minutes between executions (optional)
116
+ - `start_at`: When to start the job (optional)
117
+ - `description`: Description of the job (optional)
118
+ - `create_snapshot`: Whether to create notebook snapshots (optional)
119
+ - `runtime_name`: Name of the runtime environment
120
+ - `parameters`: Parameters for the job (optional)
121
+ - `target_config`: Target configuration for the job (optional)
122
+ - Returns details of the created job
123
+ - **get_job_details**: Get details about a specific job
124
+ - Arguments: `job_id`
125
+ - Returns detailed information about the specified job
126
+ - **list_job_executions**: List execution history for a specific job
127
+ - Arguments: `job_id`, `start` (optional), `end` (optional)
128
+ - Returns execution history for the specified job
129
+
130
+ ## Configuration
131
+
132
+ The server requires the following environment variables:
133
+
134
+ ```bash
135
+ # SingleStore's management API key (required)
136
+ SINGLESTORE_API_KEY=your_api_key_here
137
+
138
+ # Database credentials (optional - can be provided as input parameters)
139
+ SINGLESTORE_DB_USERNAME=your_db_username_here
140
+ SINGLESTORE_DB_PASSWORD=your_db_password_here
141
+ ```
@@ -0,0 +1,131 @@
1
+ # SingleStore MCP Server
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/singlestore-mcp-server)](https://pypi.org/project/singlestore_mcp_server/)
4
+ [![PyPI downloads](https://img.shields.io/pypi/dm/singlestore-mcp-server)](https://pypi.org/project/singlestore_mcp_server/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![smithery badge](https://smithery.ai/badge/@singlestore-labs/mcp-server-singlestore)](https://smithery.ai/server/@singlestore-labs/mcp-server-singlestore)
7
+
8
+ [Model Context Protocol]((https://modelcontextprotocol.io/introduction)) (MCP) is a standardized protocol designed to manage context between large language models (LLMs) and external systems. This repository provides an installer and an MCP Server for Singlestore, enabling seamless integration.
9
+
10
+ With MCP, you can use Claude Desktop or any compatible MCP client to interact with SingleStore using natural language, making it easier to perform complex operations effortlessly.
11
+
12
+ ## Claude Setup
13
+
14
+ ### Installing via Smithery
15
+
16
+ To install mcp-server-singlestore for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@singlestore-labs/mcp-server-singlestore):
17
+
18
+ ```bash
19
+ npx -y @smithery/cli install @singlestore-labs/mcp-server-singlestore --client claude
20
+ ```
21
+
22
+ ## Requirements
23
+
24
+ - Python >= v3.11.0
25
+ - [Pipx](https://pipx.pypa.io/stable/) installed on your python environment
26
+ - Claude Desktop
27
+
28
+ ## How to use locally
29
+
30
+ 1. Add the following config to your Claude Desktop [config file](https://modelcontextprotocol.io/quickstart/user)
31
+ 2. Restart Claude Desktop after making changes to the configuration
32
+
33
+ ```json
34
+ {
35
+ "mcpServers": {
36
+ "singlestore-mcp-server": {
37
+ "command": "pipx",
38
+ "args": [
39
+ "run",
40
+ "singlestore-mcp-server"
41
+ ],
42
+ "env": {
43
+ "SINGLESTORE_DB_USERNAME": "your-database-username",
44
+ "SINGLESTORE_DB_PASSWORD": "your-database-password",
45
+ "SINGLESTORE_API_KEY": "your-api-key"
46
+ }
47
+ }
48
+ }
49
+ }
50
+ ```
51
+
52
+ Note:
53
+
54
+ You can get your API key and DB credentials on SingleStore's [Helios Portal](https://portal.singlestore.com/intention/cloud)
55
+
56
+ ## Components
57
+
58
+ ### Tools
59
+
60
+ The server implements the following tools:
61
+
62
+ - **workspace_groups_info**: Retrieve details about the workspace groups accessible to the user
63
+ - No arguments required
64
+ - Returns details of the workspace groups
65
+ - **workspaces_info**: Retrieve details about the workspaces in a specific workspace group
66
+ - Arguments: `workspaceGroupID` (string)
67
+ - Returns details of the workspaces
68
+ - **organization_info**: Retrieve details about the user's current organization
69
+ - No arguments required
70
+ - Returns details of the organization
71
+ - **list_of_regions**: Retrieve a list of all regions that support workspaces for the user
72
+ - No arguments required
73
+ - Returns a list of regions
74
+ - **execute_sql**: Execute SQL operations on a connected workspace
75
+ - Arguments: `workspace_group_identifier`, `workspace_identifier`, `username`, `password`, `database`, `sql_query`
76
+ - Returns the results of the SQL query in a structured format
77
+ - **list_virtual_workspaces**: List all starter workspaces accessible to the user
78
+ - No arguments required
79
+ - Returns details of available starter workspaces
80
+ - **create_virtual_workspace**: Create a new starter workspace with a user
81
+ - Arguments:
82
+ - `name`: Name of the starter workspace
83
+ - `database_name`: Name of the database to create
84
+ - `username`: Username for accessing the workspace
85
+ - `password`: Password for the user
86
+ - `workspace_group`: Object containing `name` (optional) and `cellID` (mandatory)
87
+ - Returns details of the created workspace and user
88
+ - **execute_sql_on_virtual_workspace**: Execute SQL operations on a virtual workspace
89
+ - Arguments: `virtual_workspace_id`, `username`, `password`, `sql_query`
90
+ - Returns the results of the SQL query in a structured format including data, row count, columns, and status
91
+ - **list_notebook_samples**: List all notebook samples available in SingleStore Spaces
92
+ - No arguments required
93
+ - Returns details of available notebook samples
94
+ - **create_notebook**: Create a new notebook in the user's personal space
95
+ - Arguments: `notebook_name`, `content` (optional)
96
+ - Returns details of the created notebook
97
+ - **list_personal_files**: List all files in the user's personal space
98
+ - No arguments required
99
+ - Returns details of all files in the user's personal space
100
+ - **create_scheduled_job**: Create a new scheduled job to run a notebook
101
+ - Arguments:
102
+ - `name`: Name for the job
103
+ - `notebook_path`: Path to the notebook to execute
104
+ - `schedule_mode`: Once or Recurring
105
+ - `execution_interval_minutes`: Minutes between executions (optional)
106
+ - `start_at`: When to start the job (optional)
107
+ - `description`: Description of the job (optional)
108
+ - `create_snapshot`: Whether to create notebook snapshots (optional)
109
+ - `runtime_name`: Name of the runtime environment
110
+ - `parameters`: Parameters for the job (optional)
111
+ - `target_config`: Target configuration for the job (optional)
112
+ - Returns details of the created job
113
+ - **get_job_details**: Get details about a specific job
114
+ - Arguments: `job_id`
115
+ - Returns detailed information about the specified job
116
+ - **list_job_executions**: List execution history for a specific job
117
+ - Arguments: `job_id`, `start` (optional), `end` (optional)
118
+ - Returns execution history for the specified job
119
+
120
+ ## Configuration
121
+
122
+ The server requires the following environment variables:
123
+
124
+ ```bash
125
+ # SingleStore's management API key (required)
126
+ SINGLESTORE_API_KEY=your_api_key_here
127
+
128
+ # Database credentials (optional - can be provided as input parameters)
129
+ SINGLESTORE_DB_USERNAME=your_db_username_here
130
+ SINGLESTORE_DB_PASSWORD=your_db_password_here
131
+ ```
@@ -0,0 +1,23 @@
1
+ [project]
2
+ name = "singlestore_mcp_server"
3
+ dynamic = ["version"]
4
+ description = "SingleStore MCP server"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ dependencies = [
8
+ "mcp>=1.3.0",
9
+ "singlestoredb>=1.12.0",
10
+ ]
11
+
12
+ [build-system]
13
+ requires = ["hatchling"]
14
+ build-backend = "hatchling.build"
15
+
16
+ [tool.hatch.version]
17
+ path = "src/server/version.py"
18
+
19
+ [tool.hatch.build.targets.wheel]
20
+ packages = ["src/server"]
21
+
22
+ [project.scripts]
23
+ singlestore-mcp-server = "server:main"
@@ -0,0 +1,2 @@
1
+ pydantic-settings
2
+ singlestoredb
@@ -0,0 +1,19 @@
1
+ # Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml
2
+
3
+ startCommand:
4
+ type: stdio
5
+ configSchema:
6
+ # JSON Schema defining the configuration options for the MCP.
7
+ type: object
8
+ required:
9
+ - singlestoreApiKey
10
+ properties:
11
+ singlestoreApiKey:
12
+ type: string
13
+ description: SingleStore's API key required for authentication
14
+ commandFunction:
15
+ # A JS function that produces the CLI command based on the given config to start the MCP on stdio.
16
+ |-
17
+ (config) => { return { command: 'python', args: ['src/server/server.py'], env: { SINGLESTORE_API_KEY: config.singlestoreApiKey } }; }
18
+ exampleConfig:
19
+ singlestoreApiKey: your_api_key_here
@@ -0,0 +1,9 @@
1
+ from . import server
2
+ import asyncio
3
+
4
+ def main():
5
+ """Main entry point for the package."""
6
+ asyncio.run(server.main())
7
+
8
+ # Optionally expose other important items at package level
9
+ __all__ = ['main', 'server']
@@ -0,0 +1,9 @@
1
+ import os
2
+ from dotenv import load_dotenv
3
+
4
+ load_dotenv() # Loads environment variables from a .env file
5
+
6
+ SINGLESTORE_API_KEY = os.getenv("SINGLESTORE_API_KEY")
7
+ SINGLESTORE_DB_USERNAME = os.getenv("SINGLESTORE_DB_USERNAME")
8
+ SINGLESTORE_DB_PASSWORD = os.getenv("SINGLESTORE_DB_PASSWORD")
9
+ SINGLESTORE_API_BASE_URL = "https://api.singlestore.com"
@@ -0,0 +1 @@
1
+ {"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# SingleStore Sample Notebook\n", "\n", "This notebook demonstrates how to connect to a SingleStore database and run queries.\n"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["# Close the connection\n", "conn.close()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 2}
@@ -0,0 +1,135 @@
1
+ import asyncio
2
+
3
+ from mcp.server.models import InitializationOptions
4
+ import mcp.types as types
5
+ from mcp.server import NotificationOptions, Server
6
+ from pydantic import AnyUrl
7
+ import mcp.server.stdio
8
+ from .config import SINGLESTORE_API_KEY
9
+ from .tools import tools, tool_functions
10
+
11
+ # Store notes as a simple key-value dict to demonstrate state management
12
+ notes: dict[str, str] = {}
13
+
14
+ # Store custom text resources
15
+ custom_text_resources: dict[str, str] = {}
16
+
17
+ # Store session state for caching user inputs
18
+ session_state: dict[str, dict] = {}
19
+
20
+ server = Server("SingleStore MCP Server")
21
+
22
+
23
+ @server.list_resources()
24
+ async def handle_list_resources() -> list[types.Resource]:
25
+ """
26
+ List available note resources.
27
+ Each note is exposed as a resource with a custom note:// URI scheme.
28
+ """
29
+ return [
30
+ types.Resource(
31
+ uri=AnyUrl(f"note://internal/{name}"),
32
+ name=f"Note: {name}",
33
+ description=f"A simple note named {name}",
34
+ mimeType="text/plain",
35
+ )
36
+ for name in notes
37
+ ]
38
+
39
+
40
+ @server.read_resource()
41
+ async def handle_read_resource(uri: AnyUrl) -> str:
42
+ """
43
+ Read a specific note's content by its URI.
44
+ The note name is extracted from the URI host component.
45
+ """
46
+ if uri.scheme != "note":
47
+ raise ValueError(f"Unsupported URI scheme: {uri.scheme}")
48
+
49
+ name = uri.path
50
+ if name is not None:
51
+ name = name.lstrip("/")
52
+ return notes[name]
53
+ raise ValueError(f"Note not found: {name}")
54
+
55
+
56
+ @server.list_resources()
57
+ async def handle_list_custom_text_resources() -> list[types.Resource]:
58
+ """
59
+ List available custom text resources.
60
+ Each resource is exposed with a custom text:// URI scheme.
61
+ """
62
+ return [
63
+ types.Resource(
64
+ uri=AnyUrl(f"text://internal/{name}"),
65
+ name=f"Text Resource: {name}",
66
+ description=f"A custom text resource named {name}",
67
+ mimeType="text/plain",
68
+ )
69
+ for name in custom_text_resources
70
+ ]
71
+
72
+
73
+ @server.read_resource()
74
+ async def handle_read_custom_text_resource(uri: AnyUrl) -> str:
75
+ """
76
+ Read a specific custom text resource's content by its URI.
77
+ The resource name is extracted from the URI host component.
78
+ """
79
+ if uri.scheme != "text":
80
+ raise ValueError(f"Unsupported URI scheme: {uri.scheme}")
81
+
82
+ name = uri.path
83
+ if name is not None:
84
+ name = name.lstrip("/")
85
+ return custom_text_resources[name]
86
+ raise ValueError(f"Resource not found: {name}")
87
+
88
+
89
+ @server.list_tools()
90
+ async def handle_list_tools() -> list[types.Tool]:
91
+ """
92
+ List available tools.
93
+ Each tool specifies its arguments using JSON Schema validation.
94
+ """
95
+ return tools
96
+
97
+
98
+ @server.call_tool()
99
+ async def handle_call_tool(
100
+ name: str, arguments: dict | None
101
+ ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
102
+ """
103
+ Handle tool execution requests.
104
+ Tools can modify server state and notify clients of changes.
105
+ """
106
+ if name not in tool_functions:
107
+ raise ValueError(f"Unknown tool: {name}")
108
+
109
+ result = tool_functions[name](**arguments)
110
+
111
+ return [types.TextContent(type="text", text=str(result))]
112
+
113
+
114
+ async def main():
115
+ # Run the server using stdin/stdout streams
116
+ async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
117
+ await server.run(
118
+ read_stream,
119
+ write_stream,
120
+ InitializationOptions(
121
+ server_name="SingleStore MCP Server",
122
+ server_version="0.1.2",
123
+ capabilities=server.get_capabilities(
124
+ notification_options=NotificationOptions(),
125
+ experimental_capabilities={},
126
+ ),
127
+ initialization_options={
128
+ "singlestore_api_key": SINGLESTORE_API_KEY,
129
+ },
130
+ ),
131
+ )
132
+
133
+ # Add this block to run the main function when the script is executed directly
134
+ if __name__ == "__main__":
135
+ asyncio.run(main())
@@ -0,0 +1,15 @@
1
+ import mcp.types as types
2
+ from .definitions import tools_definitions
3
+
4
+ # Export the tools
5
+ tools = [
6
+ types.Tool(
7
+ name=tool["name"],
8
+ description=tool["description"],
9
+ inputSchema=tool["inputSchema"]
10
+ )
11
+ for tool in tools_definitions
12
+ ]
13
+
14
+ # Map tool functions by name for execution
15
+ tool_functions = {tool["name"]: tool["func"] for tool in tools_definitions}