Output Parsers for mcptools
Generate output parsers for Python tools in the mcptools package that have unstructured return types.
Identifying Unstructured Return Types
A tool has an unstructured return type when its run() function returns:
- •A
strdirectly - •A
Resultmodel with a singlestrfield (namedresult,content,output, etc.) plus onlymodel_config
A Result model with multiple fields (beyond model_config) has a structured return type and does not need a parser.
Workflow
1. Test the Python tool
Run the Python tool with ipybox_execute_ipython_cell tool using 2-3 example inputs to observe return value patterns:
from mcptools.<category>.<tool> import run, Params result = run(Params(...)) print(result) # or print(result.result) for Result types
2. Identify structure
Examine the output for parseable structure (JSON, JSONL, XML, delimited text, etc.). If no consistent structure exists, a parser cannot be generated.
3. Extend the Python tool module
Preservation rules when extending tool modules:
- •Never modify existing
Paramsclass or other existing model definitions - •Never remove or modify existing imports (they may be used by existing code)
- •Only add new imports, models, and functions
Docstring guidelines:
- •Derive docstrings from the original
run()function docstring - •
ParseResultdocstring should describe the parsed data structure - •
run_parsed()docstring must be exactly the same as therun()docstring - •Field descriptions should explain what each field contains
Add to mcptools/<category>/<tool>.py:
- •A
ParseResultmodel:
class ParseResult(BaseModel):
"""<Describe parsed data, derived from run() docstring>."""
model_config = ConfigDict(
use_enum_values=True,
)
<field_name>: <field_type> = Field(..., title="<Title>", description="<What this field contains>")
- •A
run_parsed()function:
def run_parsed(params: Params) -> ParseResult:
"""<Copy exact docstring from run() function>."""
from mcpparse.<category>.<tool> import parse
result = run(params)
# For str return: return parse(result)
# For Result return: return parse(result.result)
return parse(result)
4. Create parser module
Create mcpparse/<category>/<tool>.py with:
from mcptools.<category>.<tool> import ParseResult
class <Tool>ParseError(Exception):
"""Exception raised when parsing <tool> results fails."""
pass
def parse(result: str) -> ParseResult:
"""Parse <tool> result into structured data.
Args:
result: Raw string result from the tool
Returns:
ParseResult with structured data
Raises:
<Tool>ParseError: If parsing fails
"""
# Implementation based on observed output structure
...
return ParseResult(...)
5. Test run_parsed()
Call the ipybox_reset tool to restart the IPython kernel so the next import loads the modified module.
Then test with ipybox_execute_ipython_cell using the same example inputs from step 1:
from mcptools.<category>.<tool> import run_parsed, Params result = run_parsed(Params(...)) print(result)
Verify that the ParseResult fields are correctly populated.
Examples
str return type (web_search)
Original: run(params: Params) -> str returns JSONL
Extended with:
- •
SearchResultmodel for individual items - •
ParseResultwithresults: list[SearchResult] - •
run_parsed()that parses JSONL into structured objects
Result return type (search_abstracts)
Original: run(params: Params) -> Result where Result.result: str
Extended with:
- •
Articlemodel for individual items - •
ParseResultwitharticles: list[Article] - •
run_parsed()that parsesresult.resultinto structured objects