forked from rsp2k/mcp-mailu
Fix HTTP client connection lifecycle management
- Replace shared client instance with fresh client per request - Add get_mailu_client() function for proper client creation - Fix "Cannot reopen a client instance" error - Ensure proper async context management for all HTTP requests - Version bump to 0.3.2 for connection lifecycle fixes 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
68d429f80c
commit
f04b9b9393
@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "mcp-mailu"
|
||||
version = "0.3.0"
|
||||
version = "0.3.2"
|
||||
description = "FastMCP server for Mailu email server API integration"
|
||||
authors = [
|
||||
{name = "Ryan Malloy", email = "ryan@supported.systems"}
|
||||
|
@ -689,6 +689,17 @@ def create_mailu_client(base_url: str, api_token: str) -> httpx.AsyncClient:
|
||||
)
|
||||
|
||||
|
||||
def get_mailu_client() -> httpx.AsyncClient:
|
||||
"""Get a new HTTP client for Mailu API."""
|
||||
mailu_base_url = os.getenv("MAILU_BASE_URL", "https://mail.example.com")
|
||||
mailu_api_token = os.getenv("MAILU_API_TOKEN")
|
||||
|
||||
if not mailu_api_token:
|
||||
raise ValueError("MAILU_API_TOKEN environment variable not set")
|
||||
|
||||
return create_mailu_client(mailu_base_url + "/api/v1", mailu_api_token)
|
||||
|
||||
|
||||
def create_mcp_server() -> FastMCP:
|
||||
"""Create the MCP server with Mailu API integration."""
|
||||
|
||||
@ -699,8 +710,7 @@ def create_mcp_server() -> FastMCP:
|
||||
if not mailu_api_token:
|
||||
logger.warning("MAILU_API_TOKEN environment variable not set. Server will not work without authentication.")
|
||||
|
||||
# Create authenticated HTTP client
|
||||
client = create_mailu_client(mailu_base_url + "/api/v1", mailu_api_token)
|
||||
# Configuration validated, client will be created fresh for each request
|
||||
|
||||
# Fetch the actual OpenAPI specification from Mailu
|
||||
spec_url = "https://mail.supported.systems/api/v1/swagger.json"
|
||||
@ -732,7 +742,7 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def list_users() -> str:
|
||||
"""List all users in the Mailu instance."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get("/user")
|
||||
return f"Users: {response.json()}"
|
||||
|
||||
@ -744,7 +754,7 @@ def create_mcp_server() -> FastMCP:
|
||||
reply_subject: str = "", reply_body: str = "", displayed_name: str = "",
|
||||
spam_enabled: bool = True, spam_mark_as_read: bool = False, spam_threshold: int = 80) -> str:
|
||||
"""Create a new user in the Mailu instance."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
user_data = {
|
||||
"email": email,
|
||||
"raw_password": raw_password,
|
||||
@ -772,7 +782,7 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def get_user(email: str) -> str:
|
||||
"""Get details of a specific user."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/user/{email}")
|
||||
return f"User details: {response.json()}"
|
||||
|
||||
@ -784,7 +794,7 @@ def create_mcp_server() -> FastMCP:
|
||||
reply_subject: str = "", reply_body: str = "", displayed_name: str = "",
|
||||
spam_enabled: bool = None, spam_mark_as_read: bool = None, spam_threshold: int = None) -> str:
|
||||
"""Update an existing user."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
user_data = {}
|
||||
if raw_password: user_data["raw_password"] = raw_password
|
||||
if comment: user_data["comment"] = comment
|
||||
@ -811,7 +821,7 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def delete_user(email: str) -> str:
|
||||
"""Delete a user from the Mailu instance."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.delete(f"/user/{email}")
|
||||
return f"Delete user result: {response.json()}"
|
||||
|
||||
@ -819,7 +829,7 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def list_domains() -> str:
|
||||
"""List all domains in the Mailu instance."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get("/domain")
|
||||
return f"Domains: {response.json()}"
|
||||
|
||||
@ -827,7 +837,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def create_domain(name: str, comment: str = "", max_users: int = -1, max_aliases: int = -1,
|
||||
max_quota_bytes: int = 0, signup_enabled: bool = False, alternatives: str = "") -> str:
|
||||
"""Create a new domain in the Mailu instance."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
domain_data = {
|
||||
"name": name,
|
||||
"comment": comment,
|
||||
@ -845,7 +855,7 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def get_domain(domain: str) -> str:
|
||||
"""Get details of a specific domain."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/domain/{domain}")
|
||||
return f"Domain details: {response.json()}"
|
||||
|
||||
@ -853,7 +863,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def update_domain(domain: str, comment: str = "", max_users: int = None, max_aliases: int = None,
|
||||
max_quota_bytes: int = None, signup_enabled: bool = None, alternatives: str = "") -> str:
|
||||
"""Update an existing domain."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
domain_data = {}
|
||||
if comment: domain_data["comment"] = comment
|
||||
if max_users is not None: domain_data["max_users"] = max_users
|
||||
@ -868,21 +878,21 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def delete_domain(domain: str) -> str:
|
||||
"""Delete a domain from the Mailu instance."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.delete(f"/domain/{domain}")
|
||||
return f"Delete domain result: {response.json()}"
|
||||
|
||||
@mcp.tool()
|
||||
async def generate_dkim_keys(domain: str) -> str:
|
||||
"""Generate DKIM keys for a domain."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.post(f"/domain/{domain}/dkim")
|
||||
return f"Generate DKIM keys result: {response.json()}"
|
||||
|
||||
@mcp.tool()
|
||||
async def list_domain_users(domain: str) -> str:
|
||||
"""List all users in a specific domain."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/domain/{domain}/users")
|
||||
return f"Domain users: {response.json()}"
|
||||
|
||||
@ -890,14 +900,14 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def list_domain_managers(domain: str) -> str:
|
||||
"""List all managers for a specific domain."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/domain/{domain}/manager")
|
||||
return f"Domain managers: {response.json()}"
|
||||
|
||||
@mcp.tool()
|
||||
async def create_domain_manager(domain: str, user_email: str) -> str:
|
||||
"""Create a new domain manager."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
manager_data = {"user_email": user_email}
|
||||
response = await mailu_client.post(f"/domain/{domain}/manager", json=manager_data)
|
||||
return f"Create domain manager result: {response.json()}"
|
||||
@ -905,14 +915,14 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def get_domain_manager(domain: str, email: str) -> str:
|
||||
"""Get details of a specific domain manager."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/domain/{domain}/manager/{email}")
|
||||
return f"Domain manager details: {response.json()}"
|
||||
|
||||
@mcp.tool()
|
||||
async def delete_domain_manager(domain: str, email: str) -> str:
|
||||
"""Delete a domain manager."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.delete(f"/domain/{domain}/manager/{email}")
|
||||
return f"Delete domain manager result: {response.json()}"
|
||||
|
||||
@ -920,14 +930,14 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def list_aliases() -> str:
|
||||
"""List all aliases in the Mailu instance."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get("/alias")
|
||||
return f"Aliases: {response.json()}"
|
||||
|
||||
@mcp.tool()
|
||||
async def create_alias(email: str, destination: str = "", comment: str = "", wildcard: bool = False) -> str:
|
||||
"""Create a new alias."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
alias_data = {
|
||||
"email": email,
|
||||
"destination": destination,
|
||||
@ -940,14 +950,14 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def get_alias(alias: str) -> str:
|
||||
"""Get details of a specific alias."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/alias/{alias}")
|
||||
return f"Alias details: {response.json()}"
|
||||
|
||||
@mcp.tool()
|
||||
async def update_alias(alias: str, destination: str = "", comment: str = "", wildcard: bool = None) -> str:
|
||||
"""Update an existing alias."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
alias_data = {}
|
||||
if destination: alias_data["destination"] = destination
|
||||
if comment: alias_data["comment"] = comment
|
||||
@ -959,14 +969,14 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def delete_alias(alias: str) -> str:
|
||||
"""Delete an alias."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.delete(f"/alias/{alias}")
|
||||
return f"Delete alias result: {response.json()}"
|
||||
|
||||
@mcp.tool()
|
||||
async def find_aliases_by_domain(domain: str) -> str:
|
||||
"""Find aliases by destination domain."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/alias/destination/{domain}")
|
||||
return f"Aliases for domain: {response.json()}"
|
||||
|
||||
@ -974,14 +984,14 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def list_alternative_domains() -> str:
|
||||
"""List all alternative domains."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get("/alternative")
|
||||
return f"Alternative domains: {response.json()}"
|
||||
|
||||
@mcp.tool()
|
||||
async def create_alternative_domain(name: str, domain: str) -> str:
|
||||
"""Create a new alternative domain."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
alt_data = {"name": name, "domain": domain}
|
||||
response = await mailu_client.post("/alternative", json=alt_data)
|
||||
return f"Create alternative domain result: {response.json()}"
|
||||
@ -989,14 +999,14 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def get_alternative_domain(alt: str) -> str:
|
||||
"""Get details of a specific alternative domain."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/alternative/{alt}")
|
||||
return f"Alternative domain details: {response.json()}"
|
||||
|
||||
@mcp.tool()
|
||||
async def delete_alternative_domain(alt: str) -> str:
|
||||
"""Delete an alternative domain."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.delete(f"/alternative/{alt}")
|
||||
return f"Delete alternative domain result: {response.json()}"
|
||||
|
||||
@ -1004,14 +1014,14 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def list_relays() -> str:
|
||||
"""List all relays."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get("/relay")
|
||||
return f"Relays: {response.json()}"
|
||||
|
||||
@mcp.tool()
|
||||
async def create_relay(name: str, smtp: str = "", comment: str = "") -> str:
|
||||
"""Create a new relay."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
relay_data = {"name": name, "smtp": smtp, "comment": comment}
|
||||
response = await mailu_client.post("/relay", json=relay_data)
|
||||
return f"Create relay result: {response.json()}"
|
||||
@ -1019,14 +1029,14 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def get_relay(name: str) -> str:
|
||||
"""Get details of a specific relay."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/relay/{name}")
|
||||
return f"Relay details: {response.json()}"
|
||||
|
||||
@mcp.tool()
|
||||
async def update_relay(name: str, smtp: str = "", comment: str = "") -> str:
|
||||
"""Update an existing relay."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
relay_data = {}
|
||||
if smtp: relay_data["smtp"] = smtp
|
||||
if comment: relay_data["comment"] = comment
|
||||
@ -1037,7 +1047,7 @@ def create_mcp_server() -> FastMCP:
|
||||
@mcp.tool()
|
||||
async def delete_relay(name: str) -> str:
|
||||
"""Delete a relay."""
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.delete(f"/relay/{name}")
|
||||
return f"Delete relay result: {response.json()}"
|
||||
|
||||
@ -1046,8 +1056,9 @@ def create_mcp_server() -> FastMCP:
|
||||
|
||||
# Create MCP server from OpenAPI spec
|
||||
try:
|
||||
openapi_client = get_mailu_client()
|
||||
mcp = FastMCP.from_openapi(
|
||||
client=client,
|
||||
client=openapi_client,
|
||||
openapi_spec=spec,
|
||||
name="Mailu MCP Server",
|
||||
version="1.0.0"
|
||||
@ -1069,7 +1080,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def users_resource(ctx: Context) -> str:
|
||||
"""List all users in the Mailu instance."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get("/user")
|
||||
response.raise_for_status()
|
||||
return json.dumps(response.json(), indent=2)
|
||||
@ -1080,7 +1091,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def domains_resource(ctx: Context) -> str:
|
||||
"""List all domains in the Mailu instance."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get("/domain")
|
||||
response.raise_for_status()
|
||||
return json.dumps(response.json(), indent=2)
|
||||
@ -1091,7 +1102,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def aliases_resource(ctx: Context) -> str:
|
||||
"""List all aliases in the Mailu instance."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get("/alias")
|
||||
response.raise_for_status()
|
||||
return json.dumps(response.json(), indent=2)
|
||||
@ -1102,7 +1113,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def alternative_domains_resource(ctx: Context) -> str:
|
||||
"""List all alternative domains in the Mailu instance."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get("/alternative")
|
||||
response.raise_for_status()
|
||||
return json.dumps(response.json(), indent=2)
|
||||
@ -1113,7 +1124,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def relays_resource(ctx: Context) -> str:
|
||||
"""List all relays in the Mailu instance."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get("/relay")
|
||||
response.raise_for_status()
|
||||
return json.dumps(response.json(), indent=2)
|
||||
@ -1125,7 +1136,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def user_resource(email: str, ctx: Context) -> str:
|
||||
"""Get details of a specific user."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/user/{email}")
|
||||
response.raise_for_status()
|
||||
return json.dumps(response.json(), indent=2)
|
||||
@ -1136,7 +1147,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def domain_resource(domain: str, ctx: Context) -> str:
|
||||
"""Get details of a specific domain."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/domain/{domain}")
|
||||
response.raise_for_status()
|
||||
return json.dumps(response.json(), indent=2)
|
||||
@ -1147,7 +1158,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def alias_resource(alias: str, ctx: Context) -> str:
|
||||
"""Get details of a specific alias."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/alias/{alias}")
|
||||
response.raise_for_status()
|
||||
return json.dumps(response.json(), indent=2)
|
||||
@ -1158,7 +1169,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def alternative_domain_resource(alt: str, ctx: Context) -> str:
|
||||
"""Get details of a specific alternative domain."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/alternative/{alt}")
|
||||
response.raise_for_status()
|
||||
return json.dumps(response.json(), indent=2)
|
||||
@ -1169,7 +1180,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def relay_resource(name: str, ctx: Context) -> str:
|
||||
"""Get details of a specific relay."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/relay/{name}")
|
||||
response.raise_for_status()
|
||||
return json.dumps(response.json(), indent=2)
|
||||
@ -1181,7 +1192,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def domain_users_resource(domain: str, ctx: Context) -> str:
|
||||
"""List all users in a specific domain."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/domain/{domain}/users")
|
||||
response.raise_for_status()
|
||||
return json.dumps(response.json(), indent=2)
|
||||
@ -1192,7 +1203,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def domain_managers_resource(domain: str, ctx: Context) -> str:
|
||||
"""List all managers for a specific domain."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/domain/{domain}/manager")
|
||||
response.raise_for_status()
|
||||
return json.dumps(response.json(), indent=2)
|
||||
@ -1203,7 +1214,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def domain_manager_resource(domain: str, email: str, ctx: Context) -> str:
|
||||
"""Get details of a specific domain manager."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/domain/{domain}/manager/{email}")
|
||||
response.raise_for_status()
|
||||
return json.dumps(response.json(), indent=2)
|
||||
@ -1214,7 +1225,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def aliases_by_domain_resource(domain: str, ctx: Context) -> str:
|
||||
"""Find aliases by destination domain."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.get(f"/alias/destination/{domain}")
|
||||
response.raise_for_status()
|
||||
return json.dumps(response.json(), indent=2)
|
||||
@ -1234,7 +1245,7 @@ def create_mcp_server() -> FastMCP:
|
||||
spam_enabled: bool = True, spam_mark_as_read: bool = False, spam_threshold: int = 80) -> str:
|
||||
"""Create a new user in the Mailu instance."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
user_data = {
|
||||
"email": email,
|
||||
"raw_password": raw_password,
|
||||
@ -1272,7 +1283,7 @@ def create_mcp_server() -> FastMCP:
|
||||
spam_enabled: bool = None, spam_mark_as_read: bool = None, spam_threshold: int = None) -> str:
|
||||
"""Update an existing user."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
user_data = {}
|
||||
if raw_password: user_data["raw_password"] = raw_password
|
||||
if comment: user_data["comment"] = comment
|
||||
@ -1303,7 +1314,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def delete_user(email: str) -> str:
|
||||
"""Delete a user from the Mailu instance."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.delete(f"/user/{email}")
|
||||
response.raise_for_status()
|
||||
return f"Delete user result: {response.json()}"
|
||||
@ -1317,7 +1328,7 @@ def create_mcp_server() -> FastMCP:
|
||||
max_quota_bytes: int = 0, signup_enabled: bool = False, alternatives: str = "") -> str:
|
||||
"""Create a new domain in the Mailu instance."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
domain_data = {
|
||||
"name": name,
|
||||
"comment": comment,
|
||||
@ -1341,7 +1352,7 @@ def create_mcp_server() -> FastMCP:
|
||||
max_quota_bytes: int = None, signup_enabled: bool = None, alternatives: str = "") -> str:
|
||||
"""Update an existing domain."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
domain_data = {}
|
||||
if comment: domain_data["comment"] = comment
|
||||
if max_users is not None: domain_data["max_users"] = max_users
|
||||
@ -1360,7 +1371,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def delete_domain(domain: str) -> str:
|
||||
"""Delete a domain from the Mailu instance."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.delete(f"/domain/{domain}")
|
||||
response.raise_for_status()
|
||||
return f"Delete domain result: {response.json()}"
|
||||
@ -1371,7 +1382,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def generate_dkim_keys(domain: str) -> str:
|
||||
"""Generate DKIM keys for a domain."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.post(f"/domain/{domain}/dkim")
|
||||
response.raise_for_status()
|
||||
return f"Generate DKIM keys result: {response.json()}"
|
||||
@ -1382,7 +1393,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def auto_configure_domain_security(domain: str) -> str:
|
||||
"""Auto-configure complete domain security: DKIM, SPF, DMARC with DNS records."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
# Step 1: Generate DKIM keys
|
||||
dkim_response = await mailu_client.post(f"/domain/{domain}/dkim")
|
||||
dkim_response.raise_for_status()
|
||||
@ -1528,7 +1539,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def analyze_domain_security(domain: str) -> str:
|
||||
"""Analyze current domain security configuration without making changes."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
# Get domain info with DNS records
|
||||
domain_response = await mailu_client.get(f"/domain/{domain}")
|
||||
domain_response.raise_for_status()
|
||||
@ -1634,7 +1645,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def create_domain_manager(domain: str, user_email: str) -> str:
|
||||
"""Create a new domain manager."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
manager_data = {"user_email": user_email}
|
||||
response = await mailu_client.post(f"/domain/{domain}/manager", json=manager_data)
|
||||
response.raise_for_status()
|
||||
@ -1647,7 +1658,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def delete_domain_manager(domain: str, email: str) -> str:
|
||||
"""Delete a domain manager."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.delete(f"/domain/{domain}/manager/{email}")
|
||||
response.raise_for_status()
|
||||
return f"Delete domain manager result: {response.json()}"
|
||||
@ -1660,7 +1671,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def create_alias(email: str, destination: str = "", comment: str = "", wildcard: bool = False) -> str:
|
||||
"""Create a new alias."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
alias_data = {
|
||||
"email": email,
|
||||
"destination": destination,
|
||||
@ -1678,7 +1689,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def update_alias(alias: str, destination: str = "", comment: str = "", wildcard: bool = None) -> str:
|
||||
"""Update an existing alias."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
alias_data = {}
|
||||
if destination: alias_data["destination"] = destination
|
||||
if comment: alias_data["comment"] = comment
|
||||
@ -1694,7 +1705,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def delete_alias(alias: str) -> str:
|
||||
"""Delete an alias."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.delete(f"/alias/{alias}")
|
||||
response.raise_for_status()
|
||||
return f"Delete alias result: {response.json()}"
|
||||
@ -1708,7 +1719,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def create_alternative_domain(name: str, domain: str) -> str:
|
||||
"""Create a new alternative domain."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
alt_data = {"name": name, "domain": domain}
|
||||
response = await mailu_client.post("/alternative", json=alt_data)
|
||||
response.raise_for_status()
|
||||
@ -1721,7 +1732,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def delete_alternative_domain(alt: str) -> str:
|
||||
"""Delete an alternative domain."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.delete(f"/alternative/{alt}")
|
||||
response.raise_for_status()
|
||||
return f"Delete alternative domain result: {response.json()}"
|
||||
@ -1734,7 +1745,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def create_relay(name: str, smtp: str = "", comment: str = "") -> str:
|
||||
"""Create a new relay."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
relay_data = {"name": name, "smtp": smtp, "comment": comment}
|
||||
response = await mailu_client.post("/relay", json=relay_data)
|
||||
response.raise_for_status()
|
||||
@ -1747,7 +1758,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def update_relay(name: str, smtp: str = "", comment: str = "") -> str:
|
||||
"""Update an existing relay."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
relay_data = {}
|
||||
if smtp: relay_data["smtp"] = smtp
|
||||
if comment: relay_data["comment"] = comment
|
||||
@ -1762,7 +1773,7 @@ def create_mcp_server() -> FastMCP:
|
||||
async def delete_relay(name: str) -> str:
|
||||
"""Delete a relay."""
|
||||
try:
|
||||
async with client as mailu_client:
|
||||
async with get_mailu_client() as mailu_client:
|
||||
response = await mailu_client.delete(f"/relay/{name}")
|
||||
response.raise_for_status()
|
||||
return f"Delete relay result: {response.json()}"
|
||||
|
Loading…
x
Reference in New Issue
Block a user