Skip to content

Instantly share code, notes, and snippets.

@simonw
Last active April 18, 2025 09:43
Show Gist options
  • Save simonw/e444a81440bda2f37b0fef205780074a to your computer and use it in GitHub Desktop.
Save simonw/e444a81440bda2f37b0fef205780074a to your computer and use it in GitHub Desktop.

Pydantic AI Python MCP with Ollama and mistral-small3.1

Background here. I had to adjust the prompt to this:

How many days between 2000-01-01 and 2025-03-18? Use your python tool.

I used Ollama with mistral-small3.1 (a 15 GB model download):

ollama pull mistral-small3.1:24b

Then I ran this:

uv run --with devtools --with pydantic-ai python -c '
import asyncio
from devtools import pprint
from pydantic_ai import Agent, capture_run_messages
from pydantic_ai.models.openai import OpenAIModel
from pydantic_ai.providers.openai import OpenAIProvider
from pydantic_ai.mcp import MCPServerStdio

server = MCPServerStdio(
    "deno",
    args=[
        "run",
        "-N",
        "-R=node_modules",
        "-W=node_modules",
        "--node-modules-dir=auto",
        "jsr:@pydantic/mcp-run-python",
        "stdio",
    ],
)

agent = Agent( 
    OpenAIModel(                          
        model_name="mistral-small3.1:latest",
        provider=OpenAIProvider(base_url="http://localhost:11434/v1"),                
    ),            
    mcp_servers=[server],
)

async def main():
    with capture_run_messages() as messages:
        async with agent.run_mcp_servers():
            result = await agent.run("How many days between 2000-01-01 and 2025-03-18? Use your python tool.")
    pprint(messages)
    print(result.output)

asyncio.run(main())'

Here's the trace it showed me:

[
    ModelRequest(
        parts=[
            UserPromptPart(
                content='How many days between 2000-01-01 and 2025-03-18? Use your python tool.',
                timestamp=datetime.datetime(2025, 4, 18, 5, 38, 23, 426900, tzinfo=datetime.timezone.utc),
                part_kind='user-prompt',
            ),
        ],
        instructions=None,
        kind='request',
    ),
    ModelResponse(
        parts=[
            TextPart(
                content='',
                part_kind='text',
            ),
            ToolCallPart(
                tool_name='run_python_code',
                args=(
                    '{"python_code":"from datetime import datetime\\n\\ndef calculate_days_between_dates(start_date, end'
                    "_date):\\n    # Parse the input dates\\n    start = datetime.strptime(start_date, '%Y-%m-%d')\\n    "
                    "end = datetime.strptime(end_date, '%Y-%m-%d')\\n    # Calculate the difference in days\\n    delta "
                    "= end - start\\n    return delta.days\\n\\n# Dates\\ndate1 = '2000-01-01'\\ndate2 = '2025-03-18'\\n\\n# "
                    'Calculate the number of days between the two dates\\nnumber_of_days = calculate_days_between_dates'
                    '(date1, date2)\\nnumber_of_days"}'
                ),
                tool_call_id='call_6vvkljhb',
                part_kind='tool-call',
            ),
        ],
        model_name='mistral-small3.1:latest',
        timestamp=datetime.datetime(2025, 4, 18, 5, 38, 38, tzinfo=datetime.timezone.utc),
        kind='response',
    ),
    ModelRequest(
        parts=[
            ToolReturnPart(
                tool_name='run_python_code',
                content=CallToolResult(
                    meta=None,
                    content=[
                        TextContent(
                            type='text',
                            text=(
                                '<status>success</status>\n'
                                '<return_value>\n'
                                '9208\n'
                                '</return_value>'
                            ),
                            annotations=None,
                        ),
                    ],
                    isError=False,
                ),
                tool_call_id='call_6vvkljhb',
                timestamp=datetime.datetime(2025, 4, 18, 5, 38, 39, 791345, tzinfo=datetime.timezone.utc),
                part_kind='tool-return',
            ),
        ],
        instructions=None,
        kind='request',
    ),
    ModelResponse(
        parts=[
            TextPart(
                content='There are 9208 days between January 1, 2000, and March 18, 2025.',
                part_kind='text',
            ),
        ],
        model_name='mistral-small3.1:latest',
        timestamp=datetime.datetime(2025, 4, 18, 5, 38, 42, tzinfo=datetime.timezone.utc),
        kind='response',
    ),
]

There are 9208 days between January 1, 2000, and March 18, 2025.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
OSZAR »