What an IRS-facing MCP tool has to get right: a checklist

Last reviewed . IRS source read on . General information only, not tax, legal or accounting advice. This is an engineering article.

Disclosure. efile.technology is operated by Terragroupe, LLC and is not live. The IRS has accepted Terragroupe, LLC as an e-file provider (Electronic Return Originator, Transmitter and Software Developer). We are preparing for IRS testing and have not been approved to transmit returns, so we cannot file returns for anyone yet. Acceptance as a provider is not IRS approval or endorsement of our software. We are not affiliated with, endorsed by, or acting on behalf of the IRS. The server used for examples is a mock. It does not file with the IRS, does not connect to any IRS system, and uses fake data only.

Short answer

If a tool can send something to a tax authority, an agent will call it at the worst moment: after a timeout, with a half-finished payload, or because a user’s message was ambiguous. This is the checklist we use. Six items, each with an example from the mock server’s five tools (list_supported_forms, validate_return, build_return_xml, mock_submit_return, get_acknowledgement) and an honest note on where the mock falls short. This page is the version to print.

1. Idempotency

Rule. Every committing call takes a client-supplied idempotency key. Same key and same payload returns the original result. Same key and a different payload is an error. A retry must never create a second filing.

Mock example. mock_submit_return is the only committing tool, and it is deliberately not idempotent: each call mints a new submission ID, and the only protection is a duplicate check on form, identifier, year and period, which returns a rejection for a repeat. That is a teaching limitation. A real tool needs the key.

Also. After a timeout the right move is a lookup, not a resend. The IRS A2A flow has the same shape: Publication 4164 describes retrieving acknowledgements by the original message ID, and says these services are often used to retrieve results that were lost due to a timeout. [S1]

2. Explicit human confirmation

Rule. The model must not be able to confirm for the human. Put the gate on the server: a person completes a step on a page the service controls, which yields an authorization reference bound to the exact payload, and the committing tool refuses without it. A line in a prompt saying “ask the user first” is a courtesy, not a control.

Mock example. The mock’s agent playbook asks the assistant to confirm test values, the form, the period and any accepted warnings before calling mock_submit_return. That is policy, not enforcement, and we say so in the docs. Mark the real thing as a destructive action in whatever metadata your client supports, and do not rely on that alone.

Also. Hash the payload at confirmation time. If anything changes afterward, the reference is void. Keep PINs, taxpayer numbers and payment details on the human’s side of the handoff.

3. An audit trail

Rule. Append-only entries for validation requested, confirmation granted, submission attempted, acknowledgement received. Each carries IDs, timestamps, the idempotency key, a payload hash and the actor. No secrets, no personal data. Hash-chain entries if you want tamper evidence.

Mock example. There is none, by design. The mock keeps submissions in memory, so a restart forgets everything, and the playbook tells the agent to note IDs itself. We use that as the cautionary example: an audit store that lives in the process is not an audit store.

Also. The trail should let a human answer “who authorized this, and what exactly was sent” without asking the model.

4. Acknowledgement polling

Rule. Submission is asynchronous. The authority first reports that a submission is received or processing, then later returns a final accepted or rejected result. Your tool must not let an agent summarize “processing” as “done.”

Mock example. get_acknowledgement returns a kind field. While the status is Processing the kind is StatusRecord, which is not proof of acceptance; once the status is Accepted or Rejected the kind is Acknowledgement. As shipped, the mock answers finally on the first call; the status-record path is reachable only in its unit tests, so test your own polling loop accordingly. This mirrors IRS guidance: Publication 4164 says the status record is not proof a return was accepted or rejected, and that you must retrieve the acknowledgement file to prove the outcome. [S1]

Also.

5. Error code mapping

Rule. Give the agent a stable code, a path to the offending field, a plain message, the basis for the rule and an instruction: fix, retry, or ask a human. Map the authority’s codes to your own without hiding the original.

Mock example. validate_return returns errors[] and warnings[], each with code, path, message and basis. The basis marks almost every rule illustrative and tags the few taken from an IRS publication with their source, so nobody mistakes a mock rejection for an IRS one. The agent loops: fix the field at path, validate again. The error catalog lists each code and its fix.

Also. Three categories are enough to start:

CategoryAgent action
Shape or data errorFix the data; never retry unchanged
Rule rejection from the authorityShow the human; a correction is a new submission, not a retry
Transport or unknown outcomeLook up by key or ID; do not resend

Keep the authority’s raw code alongside your mapped one. A tool that hides it makes support impossible.

6. Never put credentials in the model’s context

Rule. The model requests actions; it never holds secrets. That covers the signing key and certificate password for the authority’s channel, the session assertion returned after login, API tokens, and the person’s own identifiers and PINs.

Mock example. The mock needs no credentials, which is exactly why it is safe to run next to a model. Its five tools take form data and return results. Nothing it returns would be useful to an attacker.

Also.

One-page version

ItemQuestion to ask
IdempotencyIf this call runs twice, what happens?
ConfirmationCan the model produce the confirmation itself?
AuditCan a human reconstruct who authorized what?
AcknowledgementsDoes “processing” ever read as “done”?
ErrorsDoes the agent know whether to fix, retry or ask?
CredentialsCould any secret reach the model’s context?

What the mock does not do

To be plain: the mock does not file with the IRS. It implements illustrative validation, builds illustrative XML that is not schema-valid, and keeps fake submissions in memory. It has no idempotency keys, no server-side confirmation gate, no persistent audit log and no credentials. We list those as gaps because they are the checklist. Try it from the quickstart; inputs and outputs are in the tools reference, and the calling sequence is in the agent playbook.

Sources

S1 is an IRS publication, read on 2026-11-05. S2 is this site’s own mock documentation, checked on the same date; it is not IRS material.

IDSourceRevisionRetrieved
S1IRS Publication 4164: MeF Guide for Software Developers and Transmitters (PDF)Rev. 12-2025, Processing Year 20262026-11-05
S2efile.technology mock docs: Tools reference, Error catalog, Agent playbookthis site (mock; not IRS material)2026-11-05

Design recommendations are the authors’ engineering opinion, not IRS guidance.

Related guides

Where efile.technology stands

efile.technology plans to offer employment-tax forms first, if and when the IRS approves production transmission. Access will be by application. What is efile.technology? · Apply for early access