Skip to content

Commit 9f5f5be

Browse files
authored
Merge pull request #43 from mminichino/mm--fix-tool-import
fix(server): fix issue with tool discovery
2 parents c74e16f + 31ae70f commit 9f5f5be

File tree

2 files changed

+45
-10
lines changed

2 files changed

+45
-10
lines changed

src/common/server.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1+
import importlib
2+
import pkgutil
13
from mcp.server.fastmcp import FastMCP
24

5+
def load_tools():
6+
import src.tools as tools_pkg
7+
for _, module_name, _ in pkgutil.iter_modules(tools_pkg.__path__):
8+
importlib.import_module(f"src.tools.{module_name}")
9+
310
# Initialize FastMCP server
411
mcp = FastMCP("Redis MCP Server", dependencies=["redis", "dotenv", "numpy"])
12+
13+
# Load tools
14+
load_tools()

src/tools/string.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,42 @@
1+
import json
2+
from typing import Union
3+
14
from redis.exceptions import RedisError
2-
from redis.typing import EncodableT
5+
from redis import Redis
36

47
from src.common.connection import RedisConnectionManager
58
from src.common.server import mcp
69

710

811
@mcp.tool()
9-
async def set(key: str, value: EncodableT, expiration: int = None) -> str:
12+
async def set(key: str, value: Union[str, bytes, int, float, dict], expiration: int = None) -> str:
1013
"""Set a Redis string value with an optional expiration time.
1114
1215
Args:
1316
key (str): The key to set.
14-
value (str): The value to store.
17+
value (str, bytes, int, float, dict): The value to store.
1518
expiration (int, optional): Expiration time in seconds.
1619
1720
Returns:
1821
str: Confirmation message or an error message.
1922
"""
23+
if isinstance(value, bytes):
24+
encoded_value = value
25+
elif isinstance(value, dict):
26+
encoded_value = json.dumps(value)
27+
else:
28+
encoded_value = str(value)
29+
30+
if isinstance(encoded_value, str):
31+
encoded_value = encoded_value.encode("utf-8")
32+
2033
try:
21-
r = RedisConnectionManager.get_connection()
34+
r: Redis = RedisConnectionManager.get_connection()
2235
if expiration:
23-
r.setex(key, expiration, value)
36+
r.setex(key, expiration, encoded_value)
2437
else:
25-
r.set(key, value)
38+
r.set(key, encoded_value)
39+
2640
return f"Successfully set {key}" + (
2741
f" with expiration {expiration} seconds" if expiration else ""
2842
)
@@ -31,18 +45,29 @@ async def set(key: str, value: EncodableT, expiration: int = None) -> str:
3145

3246

3347
@mcp.tool()
34-
async def get(key: str) -> str:
48+
async def get(key: str) -> Union[str, bytes]:
3549
"""Get a Redis string value.
3650
3751
Args:
3852
key (str): The key to retrieve.
3953
4054
Returns:
41-
str: The stored value or an error message.
55+
str, bytes: The stored value or an error message.
4256
"""
4357
try:
44-
r = RedisConnectionManager.get_connection()
58+
r: Redis = RedisConnectionManager.get_connection()
4559
value = r.get(key)
46-
return value if value else f"Key {key} does not exist"
60+
61+
if value is None:
62+
return f"Key {key} does not exist"
63+
64+
if isinstance(value, bytes):
65+
try:
66+
text = value.decode("utf-8")
67+
return text
68+
except UnicodeDecodeError:
69+
return value
70+
71+
return value
4772
except RedisError as e:
4873
return f"Error retrieving key {key}: {str(e)}"

0 commit comments

Comments
 (0)