# gateway/server.py
from mcp import MCPServer, ToolCallRequest, ToolCallResponse
from aarm import PolicyEngine, ReceiptGenerator
class AARMGateway(MCPServer):
def __init__(self, backend_url: str, policy_path: str):
self.backend = MCPClient(backend_url)
self.policy = PolicyEngine(policy_path)
self.receipts = ReceiptGenerator()
async def handle_tool_call(self, request: ToolCallRequest) -> ToolCallResponse:
# Build action from MCP request
action = self.build_action(request)
# Evaluate policy
decision = self.policy.evaluate(action)
# Enforce
if decision.result == "DENY":
self.receipts.emit(action, decision, None)
return ToolCallResponse(
error=f"Policy denied: {decision.reason}"
)
if decision.result == "STEP_UP":
approval = await self.request_approval(action)
if not approval.granted:
self.receipts.emit(action, decision, None)
return ToolCallResponse(error="Approval denied")
# Forward to backend
result = await self.backend.call(request)
# Record receipt
self.receipts.emit(action, decision, result)
return result
def build_action(self, request: ToolCallRequest) -> dict:
return {
"tool": request.tool_name,
"operation": request.method,
"parameters": request.params,
"identity": self.extract_identity(request),
"timestamp": datetime.utcnow().isoformat()
}