← Back to Blog

Building Trust With AI Agents: The pyRPC Approach

·8 min read

The hardest part of letting an AI agent near your codebase is not getting it to write code. It is trusting that the code it writes will not delete your database, charge the wrong amount, or send an email to the wrong person. pyRPC was designed with this problem in mind, and the trust model is not an afterthought. It is baked into the architecture.

The trust triangle

Three participants interact in every MCP session: you the developer, the MCP server, and the agent. Each edge of that triangle has a clear boundary:

  Developer
    |
    | writes code, registers procedures
    v
  MCP Server                      Agent
    |                               |
    | imports YOUR code             | calls MCP tools
    | returns schemas              | generates code
    | validates calls              | checks with check_call
    | NEVER executes               | executes only when YOU approve
    |                               |
    +-------------------------------+

  Boundaries:
  - MCP server: read-only access to registry, write access to nothing
  - Agent: can ask questions, cannot invoke procedures without human approval
  - Developer: controls both the code and the approval step

The never-execute guarantee

The local MCP server that ships with pyRPC validates calls but never executes them. This is not a configuration option. It is the only mode. The introspection tool reads your registry and returns schemas. The check_call tool validates arguments against those schemas. Neither tool can invoke your procedures. An agent can ask "would this call work?" and receive a definitive answer, but it cannot ask "make this call happen" through the MCP.

This means the agent can validate code endlessly without risk. It can try every combination of parameters, catch every validation error, and refine its output until check_call returns valid, all without touching your database, your API, or your file system.

The dry-run-first pattern

When the agent uses code generation, pyRPC defaults to dry_run=true. The agent sees exactly what files would change, what code would be written, and what imports would be added. Nothing touches disk until the developer approves. The generated code appears in the agent's context, the developer reviews it, and only then does it get written. This is the same pattern that makes CI/CD safe, applied to AI-generated code.

Structured errors, not vague failures

When check_call validates a call and finds problems, it returns per-parameter errors. Each error names the parameter, states the constraint that was violated, and provides the pydantic message. The agent does not receive "invalid input" or "something went wrong." It receives:

{
  "valid": false,
  "errors": [
    {
      "parameter": "amount",
      "message": "Input should be greater than 0"
    },
    {
      "parameter": "currency",
      "message": "Input should be 'USD', 'EUR', or 'GBP'"
    }
  ]
}

The agent reads these, corrects the two parameters, and re-validates. The entire loop takes seconds. No human debugging, no log diving, no guessing.

Transparent discovery

The MCP server does not filter, summarize, or hide procedures. When an agent calls introspect_project, it receives the full list of every registered procedure with every detail. There is no black box. The developer can inspect what the agent sees by running the same tool themselves. This transparency builds trust because you can verify exactly what information the agent is working with.

The real scenario

An agent needs to add a procedure call to a frontend component. The sequence looks like this: the agent calls introspect_project to see what procedures exist. It finds create_user. It reads the schema and sees the required email parameter and optional role parameter. It generates a client call with the right types. It calls check_call with the generated arguments. check_call returns valid. The agent writes the code. If check_call had returned invalid, the agent would have read the per-parameter errors, corrected the code, and re-validated. At no point did the agent execute the procedure. At no point could it.

The audit trail

Every MCP call is a tool invocation that the agent framework logs. The developer can review which tools the agent called, what arguments it passed, and what results it received. Every validation is explicit and recorded. If something goes wrong later, you can trace exactly what the agent knew and what it did with that knowledge. This is not surveillance. It is the same audit capability you would want from any automated system that touches production code.

Why this matters for production

The question is not whether AI agents can write useful code. They can. The question is whether you can trust that code in production. pyRPC's answer is to give the agent maximum information and zero execution power. The agent sees your full API surface, validates every call against your real schemas, and generates code that passes type checking. But it cannot call your procedures, it cannot write files without approval, and every action is logged. Trust is not about hoping the agent behaves. It is about making misbehavior structurally impossible.