Reply Rules
The rules that a reply to a user must follow, and the check that finds where a draft reply breaks them.
An AI agent that drafts a help desk reply has read the platform’s logs, its health and a user’s account,
which are for staff. The reply goes to one user, so it must carry only what is that user’s business.
The instructions of the MCPServer’s staff-only endpoint say so, and the check_reply tool
(CheckReplyTool) checks a draft before a staff member
sends it. check_reply() finds:
personal data and secrets, with the platform’s own Guardrail detectors (
detect()): email addresses, except the requester’s own, IP addresses, phone numbers, credit card numbers, api keys, AWS keys, private keys, JWTs and passwords. The same detectors protect LLMClients’ prompts and replies.the platform’s internals, with the rules of
REPLY_RULES: pod and node names, internal host names and urls, log lines, stack traces, exception names, the placeholders that the log store puts in place of redacted values, version numbers and cloud account ids.account enumeration: wording that tells whether an email address has an account, e.g. “there is no account with that address”. Such a reply lets anyone find out who uses the platform, so it is never sent, whatever the address.
The check is a safety net, not a guarantee: a finding is a reason for the staff member to read the draft again, and a clean result does not mean that the draft is right. A person sends the reply.
Note
Experimental. The MCPServer was designed and coded by Claude Code (Anthropic’s Claude Opus 5.5), with Lawrence McDaniel as co-author. It is experimental, and will be documented.
- smarter.apps.mcpserver.services.helpdesk.replies.DETECTOR_REASONS: dict[str, str] = {'api_key': 'Keys are secrets.', 'aws_access_key': 'Keys are secrets.', 'credit_card': 'Card numbers are payment data.', 'email': "Email addresses other than the requester's are another person's data.", 'iban': 'Bank account numbers are payment data.', 'ip_address': "IP addresses are personal data, or describe the platform's network.", 'jwt': 'Tokens are secrets.', 'password_assignment': 'Passwords are secrets.', 'phone_number': 'Phone numbers are personal data.', 'private_key': 'Keys are secrets.', 'us_ssn': 'Social security numbers are personal data.'}
Why a reply must not contain what each Guardrail detector finds, by the detector’s name.
{ 'api_key': 'Keys are secrets.', 'aws_access_key': 'Keys are secrets.', 'credit_card': 'Card numbers are payment data.', 'email': "Email addresses other than the requester's are another person's data.", 'iban': 'Bank account numbers are payment data.', 'ip_address': "IP addresses are personal data, or describe the platform's network.", 'jwt': 'Tokens are secrets.', 'password_assignment': 'Passwords are secrets.', 'phone_number': 'Phone numbers are personal data.', 'private_key': 'Keys are secrets.', 'us_ssn': 'Social security numbers are personal data.', }
- smarter.apps.mcpserver.services.helpdesk.replies.REPLY_RULES: tuple[ReplyRule, ...]
The rules of what a reply must not contain, beyond the Guardrail detectors, in the order they are checked.
- class smarter.apps.mcpserver.services.helpdesk.replies.ReplyFinding(rule, text, why)[source]
Bases:
objectSomething in a draft reply that breaks a rule, as
check_replyreports it.- __init__(rule, text, why)
- class smarter.apps.mcpserver.services.helpdesk.replies.ReplyRule(name, pattern, why)[source]
Bases:
objectOne rule of what a reply to a user must not contain, beyond the Guardrail detectors.
check_reply()reports every match of its pattern in a draft as aReplyFinding.- __init__(name, pattern, why)
- smarter.apps.mcpserver.services.helpdesk.replies.check_reply(reply, requester_email=None)[source]
Find everything in a draft reply that breaks the reply rules.
- Parameters:
- Return type:
- Returns:
The findings, those of the Guardrail detectors first, at most
MAX_FINDINGS, or an empty list if none of the rules finds anything.