s2_mcp_server 0.1.0__py3-none-any.whl

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.

Potentially problematic release.


This version of s2_mcp_server might be problematic. Click here for more details.

@@ -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,131 @@
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 s2_mcp_server.config import SINGLESTORE_API_KEY
9
+ from s2_mcp_server.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.0",
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
+ )
@@ -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}