Sofia Nieves

Author

Sofia Nieves

Sofia works on agent evaluation and reliability. She writes about measuring LLM systems before and after they reach production.

Agent security

SSRF: your AI agent's URL tool can reach your internal network (Node)

If your agent has a tool that takes a URL, the model chooses where your server connects. Measured end to end on Node 24 with no dependencies and no API key: the guard most people write fails four ways, including the IPv4-mapped IPv6 bypass behind CVE-2026-56266, which also defeated the first version of my own hardened guard.

14 min read189
Tutorials

tool_search finds nothing unless the path is the exact tool name

Measured on @openai/agents 0.18.0: the built-in client-side tool_search loader matches paths against tool names by exact string equality, and a miss returns zero tools with no error and no warning. The failure arrives one turn later as an error that blames the model.

9 min read189
Tutorials

Your Zod .refine() never reaches the model

Measured on ai 7.0.118 and zod 4.6.5: a .refine() on a tool input schema is stripped before the schema reaches the model, with no warning. z.string().startsWith('acct_') arrives as a pattern; the same rule written as a refinement arrives as nothing.

11 min read161
Tutorials

Your MCP stdio server keeps running after the client dies (Node)

An MCP stdio server that holds a timer or a pool open does not exit when its client dies. Measured on SDK 1.30.0 and Node 24.8.0: it is reparented to init and keeps running. StdioServerTransport registers no stdin end-of-file listener. Here is the reproduction and the four-line fix.

9 min read139
Tutorials

How to sandbox an AI agent's file tools in Node.js

If your agent has a read_file tool, you probably guard it with path.resolve plus startsWith. It blocks the obvious traversal and is defeated by a symlink and by a sibling directory sharing the prefix. Both reproduced on Node 24.8.0, with the guard that passes all nine cases.

8 min read231
Tutorials

Mastra rewrites tool object keys, and toolChoice does not follow

Mastra documents that the object key, not the tool id, becomes the name the model sees. It does not document that the key is rewritten first: invalid characters become underscores and the result is cut to 63. The tools array goes through that rewrite. toolChoice does not.

11 min read129