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