Skip to main content
Glama
test_contacts.py6.52 kB
from __future__ import annotations import pytest from fastmcp import Client from fastmcp.exceptions import ToolError from mcp_agent_mail.app import build_mcp_server @pytest.mark.asyncio async def test_contact_policy_block_all_blocks_direct_message(isolated_env): server = build_mcp_server() async with Client(server) as client: await client.call_tool("ensure_project", {"human_key": "/backend"}) await client.call_tool( "register_agent", {"project_key": "Backend", "program": "codex", "model": "gpt-5", "name": "GreenCastle"}, ) await client.call_tool( "register_agent", {"project_key": "Backend", "program": "codex", "model": "gpt-5", "name": "BlueLake"}, ) await client.call_tool( "set_contact_policy", {"project_key": "Backend", "agent_name": "BlueLake", "policy": "block_all"}, ) with pytest.raises(ToolError) as excinfo: await client.call_tool( "send_message", { "project_key": "Backend", "sender_name": "GreenCastle", "to": ["BlueLake"], "subject": "Hello", "body_md": "test", }, ) assert "Recipient is not accepting messages" in str(excinfo.value) @pytest.mark.asyncio async def test_contacts_only_requires_approval_then_allows(isolated_env): server = build_mcp_server() async with Client(server) as client: await client.call_tool("ensure_project", {"human_key": "/backend"}) await client.call_tool( "register_agent", {"project_key": "Backend", "program": "codex", "model": "gpt-5", "name": "GreenCastle"}, ) await client.call_tool( "register_agent", {"project_key": "Backend", "program": "codex", "model": "gpt-5", "name": "BlueLake"}, ) await client.call_tool( "set_contact_policy", {"project_key": "Backend", "agent_name": "BlueLake", "policy": "contacts_only"}, ) first = await client.call_tool( "send_message", { "project_key": "Backend", "sender_name": "GreenCastle", "to": ["BlueLake"], "subject": "Ping", "body_md": "x", }, ) deliveries_first = first.data.get("deliveries") or [] assert deliveries_first and deliveries_first[0]["payload"]["subject"] == "Ping" ok = await client.call_tool( "send_message", { "project_key": "Backend", "sender_name": "GreenCastle", "to": ["BlueLake"], "subject": "AfterApproval", "body_md": "y", }, ) deliveries = ok.data.get("deliveries") or [] assert deliveries and deliveries[0]["payload"]["subject"] == "AfterApproval" @pytest.mark.asyncio async def test_contact_auto_allows_recent_overlapping_file_reservations(isolated_env): server = build_mcp_server() async with Client(server) as client: await client.call_tool("ensure_project", {"human_key": "/backend"}) await client.call_tool( "register_agent", {"project_key": "Backend", "program": "codex", "model": "gpt-5", "name": "GreenCastle"}, ) await client.call_tool( "register_agent", {"project_key": "Backend", "program": "codex", "model": "gpt-5", "name": "BlueLake"}, ) # Overlapping file reservations -> auto allow contact await client.call_tool( "file_reservation_paths", { "project_key": "Backend", "agent_name": "GreenCastle", "paths": ["src/app.py"], "ttl_seconds": 300, "exclusive": True, }, ) await client.call_tool( "file_reservation_paths", { "project_key": "Backend", "agent_name": "BlueLake", "paths": ["src/*.py"], "ttl_seconds": 300, "exclusive": True, }, ) ok = await client.call_tool( "send_message", { "project_key": "Backend", "sender_name": "GreenCastle", "to": ["BlueLake"], "subject": "OverlapOK", "body_md": "z", }, ) deliveries = ok.data.get("deliveries") or [] assert deliveries and deliveries[0]["payload"]["subject"] == "OverlapOK" @pytest.mark.asyncio async def test_cross_project_contact_handshake_routes_message(isolated_env): server = build_mcp_server() async with Client(server) as client: # Two projects await client.call_tool("ensure_project", {"human_key": "/backend"}) await client.call_tool("ensure_project", {"human_key": "/frontend"}) await client.call_tool( "register_agent", {"project_key": "Backend", "program": "codex", "model": "gpt-5", "name": "GreenCastle"}, ) await client.call_tool( "register_agent", {"project_key": "Frontend", "program": "claude", "model": "opus", "name": "BlueLake"}, ) # Request/approve cross-project contact req = await client.call_tool( "request_contact", {"project_key": "Backend", "from_agent": "GreenCastle", "to_agent": "BlueLake", "to_project": "Frontend"}, ) assert req.data.get("status") == "pending" resp = await client.call_tool( "respond_contact", {"project_key": "Frontend", "to_agent": "BlueLake", "from_agent": "GreenCastle", "from_project": "Backend", "accept": True}, ) assert resp.data.get("approved") is True # Now route a message from Backend->Frontend ok = await client.call_tool( "send_message", { "project_key": "Backend", "sender_name": "GreenCastle", "to": ["project:Frontend#BlueLake"], "subject": "CrossProject", "body_md": "hello", }, ) deliveries = ok.data.get("deliveries") or [] assert any(d.get("project") in {"Frontend", "/frontend"} for d in deliveries)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Dicklesworthstone/mcp_agent_mail'

If you have feedback or need assistance with the MCP directory API, please join our Discord server