TinyAgents: A Minimal Experiment with Code Agents and MCP Tools

Community Article Published May 16, 2025

Recently, I found myself fascinated by a blog post from Julien Chaumond "Tiny Agents: an MCP-powered agent in 50 lines of code", where he introduced the idea of Tiny Agents: minimalist LLM agents powered by MCP tools. The core idea was refreshing: small, focused agents calling tools asynchronously via the Model Context Protocol, without all the heavyweight frameworks that tend to come with "agent" infrastructure these days.

I couldn’t resist asking Julien a follow-up question: “What if, instead of tool-calling agents, we tried a code agent?”

Tool-calling agents are intuitive: you give the model a question, and it calls a relevant tool (e.g. get_weather_alerts("NY")). But this approach can break down when you ask for compositional reasoning, or a more complex workflow. That’s where code agents shine.

Why Code Agents?

Code agents, as the name suggests, write and execute small pieces of code instead of just calling tools directly. This allows them to:

  • Handle more complex logic (e.g., conditionals, loops)
  • Compose multiple tool calls into a single code block
  • Reduce the number of LLM calls, which can improve both performance and reliability

In short: more power, less chatter.

Building It: TinyAgents

So, I built a minimal implementation: TinyAgents = LLM + async MCP tools.

The setup is extremely lightweight: just a single-step agent implementation that wires an LLM to interact asynchronously with MCP tools.

The Experiment

I put both the tool-calling agent and the code agent to the test with a simple but slightly compositional question:

“What are the weather alerts in New York, California, and Alaska?”

Tool-Calling Agent

The tool-calling agent interpreted the task literally, but only performed a single tool call, returning alerts for New York, and stopping there. That’s often the limitation with tool call reasoning: it lacks support for more complex workflows. In this case, no multiple tool calls were made, likely because handling the full task would require multiple steps, which haven’t been implemented yet. In any case, it remains less effieient than the code agent, which handled the entire task in a single step.

The output:

### Weather Alerts in New York, California, and Alaska

#### New York:
- **Special Weather Statement (Northern and Southern portions)**:
  - **Areas**: Various parts of New York including Manhattan, Brooklyn, Staten Island, parts of Queens, Nassau, and Suffolk counties.
  - **Severity**: Moderate
  - **Description**: Dense fog reducing visibility to a quarter mile or less in spots, advising motorists to slow down and use caution.
  
- **Flood Warning (Northern Tompkins County)**:
  - **Area**: Tompkins, NY
  - **Severity**: Severe
  - **Description**: Minor flooding is occurring and forecasted on Cayuga Lake in Ithaca, affecting Tompkins County.
  - **Details**: Flood stage at 383.5 feet. Lake level is expected to remain steady above flood stage until the weekend and then drop slightly.

#### California:
- As of the provided information, there are no specific weather alerts mentioned for California.

#### Alaska:
- As of the provided information, there are no specific weather alerts mentioned for Alaska.

### Summary:
- **New York**: Moderate fog warnings for many areas and a severe flood warning for Tompkins County.
- **California**: No alerts provided in the given information.
- **Alaska**: No alerts provided in the given information.

For the most up-to-date and comprehensive weather alerts, it's recommended to check the local National Weather Service (NWS) website or apps specific to California and Alaska.

Code Agent

The code agent, on the other hand, wrote a compact Python snippet that called get_alerts("NY"), get_alerts("CA"), and get_alerts("AK"), all within a single step. What remains to do: execute the code, collect the results, and return them neatly.

  • ✅ All states covered
  • ✅ Single LLM call
  • ✅ Resolved in one compact code snippet

The output:

To fetch the weather alerts for New York (NY), California (CA), and Alaska (AK), you can use the `get_alerts` function. Here is the Python code to do so:
# Get weather alerts for New York
ny_alerts = get_alerts("NY")

# Get weather alerts for California
ca_alerts = get_alerts("CA")

# Get weather alerts for Alaska
ak_alerts = get_alerts("AK")

# Print the alerts
print("Weather Alerts for New York (NY):")
print(ny_alerts)
print("\nWeather Alerts for California (CA):")
print(ca_alerts)
print("\nWeather Alerts for Alaska (AK):")
print(ak_alerts)

This code will call the get_alerts function for each state and print out the weather alerts. If there are no alerts, the function may return an empty list or a message indicating that there are no current alerts.

What’s Next?

The next step is obvious: 💡 Build a tiny Python code executor for handling these generated code blobs safely and efficiently.

This will allow the agent to generate and run arbitrary Python.


If you're interested in lightweight, compositional, and async-first LLM workflows, I highly recommend exploring MCP tools and thinking about when a code agent might give you the upper hand.

You can find the full implementation and experiment code in the TinyAgents GitHub repository.

More experiments coming soon. Stay tiny 🧠

Community

Sign up or log in to comment