Skip to content

Commit 5e4f596

Browse files
committed
ran formatter
1 parent bfc482c commit 5e4f596

File tree

10 files changed

+187
-122
lines changed

10 files changed

+187
-122
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ RUN --mount=type=cache,target=/root/.cache/uv \
2525
FROM python:3.12-slim-bookworm
2626

2727
WORKDIR /app
28-
28+
2929
COPY --from=uv --chown=app:app /app/.venv /app/.venv
3030

3131
# Place executables in the environment at the front of the path

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ https://smithery.ai/server/@kenliao94/mcp-server-rabbitmq
3838
"command": "uv",
3939
"args": [
4040
"--directory",
41-
"/path/to/repo/mcp-server-rabbitmq",
42-
"run",
41+
"/path/to/repo/mcp-server-rabbitmq",
42+
"run",
4343
"mcp-server-rabbitmq",
4444
"--rabbitmq-host",
4545
"<hostname ex. test.rabbit.com, localhost>",
46-
"--port",
46+
"--port",
4747
"<port number ex. 5672>",
4848
"--username",
4949
"<rabbitmq username>",

glama.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
"maintainers": [
44
"kenliao94"
55
]
6-
}
6+
}

mcp_server_rabbitmq/admin.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@
33

44
import requests
55

6+
from mcp_server_rabbitmq.connection import validate_rabbitmq_name
7+
68

79
class RabbitMQAdmin:
810
def __init__(self, host: str, port: int, username: str, password: str, use_tls: bool):
911
self.protocol = "https" if use_tls else "http"
1012
self.base_url = f"{self.protocol}://{host}:{port}/api"
1113
self.auth = base64.b64encode(f"{username}:{password}".encode()).decode()
12-
self.headers = {
13-
"Authorization": f"Basic {self.auth}",
14-
"Content-Type": "application/json"
15-
}
14+
self.headers = {"Authorization": f"Basic {self.auth}", "Content-Type": "application/json"}
1615

17-
def _make_request(self, method: str, endpoint: str, data: Optional[Dict] = None) -> requests.Response:
16+
def _make_request(
17+
self, method: str, endpoint: str, data: Optional[Dict] = None
18+
) -> requests.Response:
1819
url = f"{self.base_url}/{endpoint}"
1920
response = requests.request(method, url, headers=self.headers, json=data, verify=True)
2021
response.raise_for_status()
@@ -60,15 +61,19 @@ def delete_exchange(self, exchange: str, vhost: str = "/") -> None:
6061
vhost_encoded = requests.utils.quote(vhost, safe="")
6162
self._make_request("DELETE", f"exchanges/{vhost_encoded}/{exchange}")
6263

63-
def get_bindings(self, queue: Optional[str] = None, exchange: Optional[str] = None, vhost: str = "/") -> List[Dict]:
64+
def get_bindings(
65+
self, queue: Optional[str] = None, exchange: Optional[str] = None, vhost: str = "/"
66+
) -> List[Dict]:
6467
"""Get bindings, optionally filtered by queue or exchange"""
6568
vhost_encoded = requests.utils.quote(vhost, safe="")
6669
if queue:
6770
validate_rabbitmq_name(queue, "Queue name")
6871
response = self._make_request("GET", f"queues/{vhost_encoded}/{queue}/bindings")
6972
elif exchange:
7073
validate_rabbitmq_name(exchange, "Exchange name")
71-
response = self._make_request("GET", f"exchanges/{vhost_encoded}/{exchange}/bindings/source")
74+
response = self._make_request(
75+
"GET", f"exchanges/{vhost_encoded}/{exchange}/bindings/source"
76+
)
7277
else:
7378
response = self._make_request("GET", f"bindings/{vhost_encoded}")
7479
return response.json()

mcp_server_rabbitmq/connection.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def __init__(self, host: str, port: int, username: str, password: str, use_tls:
88
self.protocol = "amqps" if use_tls else "amqp"
99
self.url = f"{self.protocol}://{username}:{password}@{host}:{port}"
1010
self.parameters = pika.URLParameters(self.url)
11-
11+
1212
if use_tls:
1313
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
1414
ssl_context.set_ciphers("ECDHE+AESGCM:!ECDSA")
@@ -19,11 +19,14 @@ def get_channel(self) -> tuple[pika.BlockingConnection, pika.channel.Channel]:
1919
channel = connection.channel()
2020
return connection, channel
2121

22+
2223
def validate_rabbitmq_name(name: str, field_name: str) -> None:
2324
"""Validate RabbitMQ queue/exchange names"""
2425
if not name or not name.strip():
2526
raise ValueError(f"{field_name} cannot be empty")
2627
if not all(c.isalnum() or c in "-_.:" for c in name):
27-
raise ValueError(f"{field_name} can only contain letters, digits, hyphen, underscore, period, or colon")
28+
raise ValueError(
29+
f"{field_name} can only contain letters, digits, hyphen, underscore, period, or colon"
30+
)
2831
if len(name) > 255:
2932
raise ValueError(f"{field_name} must be less than 255 characters")

mcp_server_rabbitmq/handlers.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,41 @@ def handle_enqueue(rabbitmq: RabbitMQConnection, queue: str, message: str):
1010
channel.basic_publish(exchange="", routing_key=queue, body=message)
1111
connection.close()
1212

13+
1314
def handle_fanout(rabbitmq: RabbitMQConnection, exchange: str, message: str):
1415
connection, channel = rabbitmq.get_channel()
1516
channel.exchange_declare(exchange=exchange, exchange_type="fanout")
1617
channel.basic_publish(exchange=exchange, routing_key="", body=message)
1718
connection.close()
1819

20+
1921
def handle_list_queues(rabbitmq_admin: RabbitMQAdmin) -> List[str]:
2022
result = rabbitmq_admin.list_queues()
2123
return [queue["name"] for queue in result]
2224

25+
2326
def handle_list_exchanges(rabbitmq_admin: RabbitMQAdmin) -> List[str]:
2427
result = rabbitmq_admin.list_exchanges()
2528
return [exchange["name"] for exchange in result]
2629

30+
2731
def handle_get_queue_info(rabbitmq_admin: RabbitMQAdmin, queue: str, vhost: str = "/") -> dict:
2832
return rabbitmq_admin.get_queue_info(queue, vhost)
2933

34+
3035
def handle_delete_queue(rabbitmq_admin: RabbitMQAdmin, queue: str, vhost: str = "/") -> None:
3136
rabbitmq_admin.delete_queue(queue, vhost)
3237

38+
3339
def handle_purge_queue(rabbitmq_admin: RabbitMQAdmin, queue: str, vhost: str = "/") -> None:
3440
rabbitmq_admin.purge_queue(queue, vhost)
3541

42+
3643
def handle_delete_exchange(rabbitmq_admin: RabbitMQAdmin, exchange: str, vhost: str = "/") -> None:
3744
rabbitmq_admin.delete_exchange(exchange, vhost)
3845

39-
def handle_get_exchange_info(rabbitmq_admin: RabbitMQAdmin, exchange: str, vhost: str = "/") -> dict:
46+
47+
def handle_get_exchange_info(
48+
rabbitmq_admin: RabbitMQAdmin, exchange: str, vhost: str = "/"
49+
) -> dict:
4050
return rabbitmq_admin.get_exchange_info(exchange, vhost)

mcp_server_rabbitmq/server.py

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@ def __init__(self):
2626
self.logger.setLevel(logging.INFO)
2727
logging.basicConfig(
2828
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
29-
handlers=[
30-
logging.FileHandler("server.log"),
31-
logging.StreamHandler()
32-
]
29+
handlers=[logging.FileHandler("server.log"), logging.StreamHandler()],
3330
)
3431

3532
# Initialize FastMCP
@@ -57,8 +54,11 @@ def enqueue(queue: str, message: str) -> str:
5754
validate_rabbitmq_name(queue, "Queue name")
5855
try:
5956
rabbitmq = RabbitMQConnection(
60-
self.rabbitmq_host, self.rabbitmq_port, self.rabbitmq_username,
61-
self.rabbitmq_password, self.rabbitmq_use_tls
57+
self.rabbitmq_host,
58+
self.rabbitmq_port,
59+
self.rabbitmq_username,
60+
self.rabbitmq_password,
61+
self.rabbitmq_use_tls,
6262
)
6363
handle_enqueue(rabbitmq, queue, message)
6464
return "Message successfully enqueued"
@@ -72,8 +72,11 @@ def fanout(exchange: str, message: str) -> str:
7272
validate_rabbitmq_name(exchange, "Exchange name")
7373
try:
7474
rabbitmq = RabbitMQConnection(
75-
self.rabbitmq_host, self.rabbitmq_port, self.rabbitmq_username,
76-
self.rabbitmq_password, self.rabbitmq_use_tls
75+
self.rabbitmq_host,
76+
self.rabbitmq_port,
77+
self.rabbitmq_username,
78+
self.rabbitmq_password,
79+
self.rabbitmq_use_tls,
7780
)
7881
handle_fanout(rabbitmq, exchange, message)
7982
return "Message successfully published to exchange"
@@ -86,8 +89,11 @@ def list_queues() -> str:
8689
"""List all the queues in the broker."""
8790
try:
8891
admin = RabbitMQAdmin(
89-
self.rabbitmq_host, self.rabbitmq_api_port, self.rabbitmq_username,
90-
self.rabbitmq_password, self.rabbitmq_use_tls
92+
self.rabbitmq_host,
93+
self.rabbitmq_api_port,
94+
self.rabbitmq_username,
95+
self.rabbitmq_password,
96+
self.rabbitmq_use_tls,
9197
)
9298
result = handle_list_queues(admin)
9399
return str(result)
@@ -100,8 +106,11 @@ def list_exchanges() -> str:
100106
"""List all the exchanges in the broker."""
101107
try:
102108
admin = RabbitMQAdmin(
103-
self.rabbitmq_host, self.rabbitmq_api_port, self.rabbitmq_username,
104-
self.rabbitmq_password, self.rabbitmq_use_tls
109+
self.rabbitmq_host,
110+
self.rabbitmq_api_port,
111+
self.rabbitmq_username,
112+
self.rabbitmq_password,
113+
self.rabbitmq_use_tls,
105114
)
106115
result = handle_list_exchanges(admin)
107116
return str(result)
@@ -114,8 +123,11 @@ def get_queue_info(queue: str, vhost: str = "/") -> str:
114123
"""Get detailed information about a specific queue."""
115124
try:
116125
admin = RabbitMQAdmin(
117-
self.rabbitmq_host, self.rabbitmq_api_port, self.rabbitmq_username,
118-
self.rabbitmq_password, self.rabbitmq_use_tls
126+
self.rabbitmq_host,
127+
self.rabbitmq_api_port,
128+
self.rabbitmq_username,
129+
self.rabbitmq_password,
130+
self.rabbitmq_use_tls,
119131
)
120132
validate_rabbitmq_name(queue, "Queue name")
121133
result = handle_get_queue_info(admin, queue, vhost)
@@ -129,8 +141,11 @@ def delete_queue(queue: str, vhost: str = "/") -> str:
129141
"""Delete a specific queue."""
130142
try:
131143
admin = RabbitMQAdmin(
132-
self.rabbitmq_host, self.rabbitmq_api_port, self.rabbitmq_username,
133-
self.rabbitmq_password, self.rabbitmq_use_tls
144+
self.rabbitmq_host,
145+
self.rabbitmq_api_port,
146+
self.rabbitmq_username,
147+
self.rabbitmq_password,
148+
self.rabbitmq_use_tls,
134149
)
135150
validate_rabbitmq_name(queue, "Queue name")
136151
handle_delete_queue(admin, queue, vhost)
@@ -144,8 +159,11 @@ def purge_queue(queue: str, vhost: str = "/") -> str:
144159
"""Remove all messages from a specific queue."""
145160
try:
146161
admin = RabbitMQAdmin(
147-
self.rabbitmq_host, self.rabbitmq_api_port, self.rabbitmq_username,
148-
self.rabbitmq_password, self.rabbitmq_use_tls
162+
self.rabbitmq_host,
163+
self.rabbitmq_api_port,
164+
self.rabbitmq_username,
165+
self.rabbitmq_password,
166+
self.rabbitmq_use_tls,
149167
)
150168
validate_rabbitmq_name(queue, "Queue name")
151169
handle_purge_queue(admin, queue, vhost)
@@ -159,8 +177,11 @@ def delete_exchange(exchange: str, vhost: str = "/") -> str:
159177
"""Delete a specific exchange."""
160178
try:
161179
admin = RabbitMQAdmin(
162-
self.rabbitmq_host, self.rabbitmq_api_port, self.rabbitmq_username,
163-
self.rabbitmq_password, self.rabbitmq_use_tls
180+
self.rabbitmq_host,
181+
self.rabbitmq_api_port,
182+
self.rabbitmq_username,
183+
self.rabbitmq_password,
184+
self.rabbitmq_use_tls,
164185
)
165186
validate_rabbitmq_name(exchange, "Exchange name")
166187
handle_delete_exchange(admin, exchange, vhost)
@@ -174,8 +195,11 @@ def get_exchange_info(exchange: str, vhost: str = "/") -> str:
174195
"""Get detailed information about a specific exchange."""
175196
try:
176197
admin = RabbitMQAdmin(
177-
self.rabbitmq_host, self.rabbitmq_api_port, self.rabbitmq_username,
178-
self.rabbitmq_password, self.rabbitmq_use_tls
198+
self.rabbitmq_host,
199+
self.rabbitmq_api_port,
200+
self.rabbitmq_username,
201+
self.rabbitmq_password,
202+
self.rabbitmq_use_tls,
179203
)
180204
validate_rabbitmq_name(exchange, "Exchange name")
181205
result = handle_get_exchange_info(admin, exchange, vhost)
@@ -212,16 +236,22 @@ def main():
212236
parser.add_argument("--port", type=int, required=True, help="Port of the RabbitMQ host")
213237
parser.add_argument("--username", type=str, required=True, help="Username for the connection")
214238
parser.add_argument("--password", type=str, required=True, help="Password for the connection")
215-
parser.add_argument("--use-tls", type=bool, default=False, help="Is the connection using TLS/SSL")
216-
parser.add_argument("--api-port", type=int, default=15672, help="Port for the RabbitMQ management API")
239+
parser.add_argument(
240+
"--use-tls", type=bool, default=False, help="Is the connection using TLS/SSL"
241+
)
242+
parser.add_argument(
243+
"--api-port", type=int, default=15672, help="Port for the RabbitMQ management API"
244+
)
217245
parser.add_argument("--sse", action="store_true", help="Use SSE transport")
218-
parser.add_argument("--server-port", type=int, default=8888, help="Port to run the MCP server on")
246+
parser.add_argument(
247+
"--server-port", type=int, default=8888, help="Port to run the MCP server on"
248+
)
219249

220250
args = parser.parse_args()
221-
251+
222252
server = RabbitMQMCPServer()
223253
server.run(args)
224254

225255

226256
if __name__ == "__main__":
227-
main()
257+
main()

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ ignore = ["E203", "E501"]
6767
known-first-party = ["mcp_server_rabbitmq"]
6868

6969
[tool.ruff.format]
70-
quote-style = "single"
70+
quote-style = "double"
7171
indent-style = "space"
7272
line-ending = "auto"
7373

tests/test_connection.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@ class TestRabbitMQConnection:
1414
def test_connection_initialization(self, mock_connection):
1515
"""Test that the connection is initialized correctly."""
1616
mock_connection.return_value = MagicMock()
17-
1817
connection = RabbitMQConnection("localhost", 5672, "guest", "guest", False)
19-
2018
assert connection is not None
19+
_, _ = connection.get_channel()
2120
mock_connection.assert_called_once()
2221

2322

@@ -36,12 +35,12 @@ def test_validate_rabbitmq_name_invalid(self):
3635
"""Test that invalid names fail validation."""
3736
with pytest.raises(ValueError):
3837
validate_rabbitmq_name("", "Test")
39-
38+
4039
with pytest.raises(ValueError):
4140
validate_rabbitmq_name("invalid/name", "Test")
42-
41+
4342
with pytest.raises(ValueError):
4443
validate_rabbitmq_name("invalid\\name", "Test")
45-
44+
4645
with pytest.raises(ValueError):
4746
validate_rabbitmq_name("invalid*name", "Test")

0 commit comments

Comments
 (0)