Enhancing Tools
Many MCP servers lack output schemas. For example, all tools of the GitHub MCP server return a JSON string without defining an output schema. Without an output schema, the run() function of the generated tool API returns a plain string instead of a structured Result type.
Without knowing output structure beforehand, an agent cannot reliably write code that processes tool output inside a code action. It must retrieve raw results into context for inspection, then write processing logic in another inference round.
Freeact's bundled output-parsers skill solves this by generating output parsers that enhance tool APIs with a run_parsed() function that returns a structured output type. With output types known, the agent can generate processing logic in a single inference round.
This tool enhancement persists across sessions and is an example of the agent acting as a toolsmith, enhancing its own tool library rather than just executing tasks.
Output Parser Generation
Recorded session
A recorded session of this example is appended below.
Create a workspace and initialize the configuration directory:
mkdir my-workspace && cd my-workspace
uvx freeact init
Add the GitHub MCP server to ptc-servers in .freeact/servers.json:
{
"ptc-servers": {
"github": {
"url": "https://api.githubcopilot.com/mcp/",
"headers": {"Authorization": "Bearer ${GITHUB_API_KEY}"}
}
}
}
Set your GitHub personal access token (PAT) as the GITHUB_API_KEY environment variable or add it to .env.
Then start the CLI tool to automatically generate Python APIs to mcptools/github/:
uvx freeact
When asked to
create an output parser for search_repositories
the agent
- Loads the
output-parsersskill and the generatedsearch_repositories.pytool API - Calls the
search_repositories.run()function with example inputs to observe outputs - Identifies parseable JSON with fields like
name,description,stargazers_count, etc. - Creates an enhanced tool API with
ParseResult,Repositoryandrun_parsed() - Saves the parser to a separate
mcpparse/github/search_repositories.py - Resets the IPython kernel to re-import the tool for testing
run_parsed()
The enhanced tool can now be composed with other tools in a single code action, with full type information available for processing intermediate results.