Skip to content

Commit 952420c

Browse files
committed
Add admin API interfaces
1 parent 305c43c commit 952420c

File tree

3 files changed

+99
-8
lines changed

3 files changed

+99
-8
lines changed

src/mcp_server_rabbitmq/admin.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import requests
2+
from typing import Optional, List, Dict
3+
import base64
4+
5+
class RabbitMQAdmin:
6+
def __init__(self, host: str, port: int, username: str, password: str, use_tls: bool):
7+
self.protocol = "https" if use_tls else "http"
8+
self.base_url = f"{self.protocol}://{host}:{port}/api"
9+
self.auth = base64.b64encode(f"{username}:{password}".encode()).decode()
10+
self.headers = {
11+
"Authorization": f"Basic {self.auth}",
12+
"Content-Type": "application/json"
13+
}
14+
15+
def _make_request(self, method: str, endpoint: str, data: Optional[Dict] = None) -> requests.Response:
16+
url = f"{self.base_url}/{endpoint}"
17+
response = requests.request(method, url, headers=self.headers, json=data, verify=True)
18+
response.raise_for_status()
19+
return response
20+
21+
def list_queues(self) -> List[Dict]:
22+
"""List all queues in the RabbitMQ server"""
23+
response = self._make_request("GET", "queues")
24+
return response.json()
25+
26+
def list_exchanges(self) -> List[Dict]:
27+
"""List all exchanges in the RabbitMQ server"""
28+
response = self._make_request("GET", "exchanges")
29+
return response.json()
30+
31+
def get_queue_info(self, queue: str, vhost: str = "/") -> Dict:
32+
"""Get detailed information about a specific queue"""
33+
vhost_encoded = requests.utils.quote(vhost, safe='')
34+
response = self._make_request("GET", f"queues/{vhost_encoded}/{queue}")
35+
return response.json()
36+
37+
def delete_queue(self, queue: str, vhost: str = "/") -> None:
38+
"""Delete a queue"""
39+
validate_rabbitmq_name(queue, "Queue name")
40+
vhost_encoded = requests.utils.quote(vhost, safe='')
41+
self._make_request("DELETE", f"queues/{vhost_encoded}/{queue}")
42+
43+
def purge_queue(self, queue: str, vhost: str = "/") -> None:
44+
"""Remove all messages from a queue"""
45+
validate_rabbitmq_name(queue, "Queue name")
46+
vhost_encoded = requests.utils.quote(vhost, safe='')
47+
self._make_request("DELETE", f"queues/{vhost_encoded}/{queue}/contents")
48+
49+
def get_exchange_info(self, exchange: str, vhost: str = "/") -> Dict:
50+
"""Get detailed information about a specific exchange"""
51+
vhost_encoded = requests.utils.quote(vhost, safe='')
52+
response = self._make_request("GET", f"exchanges/{vhost_encoded}/{exchange}")
53+
return response.json()
54+
55+
def delete_exchange(self, exchange: str, vhost: str = "/") -> None:
56+
"""Delete an exchange"""
57+
validate_rabbitmq_name(exchange, "Exchange name")
58+
vhost_encoded = requests.utils.quote(vhost, safe='')
59+
self._make_request("DELETE", f"exchanges/{vhost_encoded}/{exchange}")
60+
61+
def get_bindings(self, queue: Optional[str] = None, exchange: Optional[str] = None, vhost: str = "/") -> List[Dict]:
62+
"""Get bindings, optionally filtered by queue or exchange"""
63+
vhost_encoded = requests.utils.quote(vhost, safe='')
64+
if queue:
65+
validate_rabbitmq_name(queue, "Queue name")
66+
response = self._make_request("GET", f"queues/{vhost_encoded}/{queue}/bindings")
67+
elif exchange:
68+
validate_rabbitmq_name(exchange, "Exchange name")
69+
response = self._make_request("GET", f"exchanges/{vhost_encoded}/{exchange}/bindings/source")
70+
else:
71+
response = self._make_request("GET", f"bindings/{vhost_encoded}")
72+
return response.json()
73+
74+
def get_overview(self) -> Dict:
75+
"""Get overview of RabbitMQ server including version, stats, and listeners"""
76+
response = self._make_request("GET", "overview")
77+
return response.json()
78+
79+
if __name__ == "__main__":
80+
# test
81+
admin = RabbitMQAdmin("localhost", 15672, "guest", "guest", False)
82+
print(admin.list_queues())
83+
print("Done")
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from .connection import RabbitMQConnection
2+
3+
def handle_enqueue(rabbitmq: RabbitMQConnection, queue: str, message: str):
4+
connection, channel = rabbitmq.get_channel()
5+
channel.queue_declare(queue)
6+
channel.basic_publish(exchange="", routing_key=queue, body=message)
7+
connection.close()
8+
9+
def handle_fanout(rabbitmq: RabbitMQConnection, exchange: str, message: str):
10+
connection, channel = rabbitmq.get_channel()
11+
channel.exchange_declare(exchange=exchange, exchange_type="fanout")
12+
channel.basic_publish(exchange=exchange, routing_key="", body=message)
13+
connection.close()

src/mcp_server_rabbitmq/server.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from .models import Enqueue, Fanout
1010
from .logger import Logger, LOG_LEVEL
1111
from .connection import RabbitMQConnection, validate_rabbitmq_name
12+
from .handlers import handle_enqueue, handle_fanout
1213

1314

1415
async def serve(rabbitmq_host: str, port: int, username: str, password: str, use_tls: bool, log_level: str = LOG_LEVEL.DEBUG.name) -> None:
@@ -55,10 +56,7 @@ async def call_tool(
5556
validate_rabbitmq_name(queue, "Queue name")
5657

5758
try:
58-
connection, channel = rabbitmq.get_channel()
59-
channel.queue_declare(queue)
60-
channel.basic_publish(exchange="", routing_key=queue, body=message)
61-
connection.close()
59+
handle_enqueue(rabbitmq, queue, message)
6260
return [TextContent(type="text", text=str("suceeded"))]
6361
except Exception as e:
6462
logger.error(f"{e}")
@@ -71,10 +69,7 @@ async def call_tool(
7169
validate_rabbitmq_name(exchange, "Exchange name")
7270

7371
try:
74-
connection, channel = rabbitmq.get_channel()
75-
channel.exchange_declare(exchange=exchange, exchange_type="fanout")
76-
channel.basic_publish(exchange=exchange, routing_key="", body=message)
77-
connection.close()
72+
handle_fanout(rabbitmq, exchange, message)
7873
return [TextContent(type="text", text=str("suceeded"))]
7974
except Exception as e:
8075
logger.error(f"{e}")

0 commit comments

Comments
 (0)