Get startedGet started for free

Building the Message and Calling the LLM

With your get_context_from_mcp(user_query) helper function created to return the resource text and prompt text, it's time to pass that information to the LLM!

The currency server, get_context_from_mcp(), get_tools_from_mcp(), call_mcp_tool(), and the Claude client are set up in the background. You need to complete the function that builds the prompt, calls the model, and handles either a direct message or a tool call. You've been provided with an ambiguous and an unambiguous user input to see if your MCP prompts made the difference!

This exercise is part of the course

Introduction to Model Context Protocol (MCP)

View Course

Exercise instructions

  • On line 37, build full_prompt by concatenating prompt_text, the string "\n\nSupported currencies:\n", and resource_text.
  • On line 47, send the full_prompt (as the user message content) and the anthropic_tools list to the model.
  • On lines 52-55, if the response's stop_reason is "end_turn", return str(text).
  • On lines 58-60, if the response's stop_reason is "tool_use", pass the tool use block's .name and .input to call_mcp_tool().

Hands-on interactive exercise

Have a go at this exercise by completing this sample code.

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

async def get_context_from_mcp(user_query: str) -> tuple[str, str]:
    params = StdioServerParameters(command=sys.executable, args=["currency_server.py"])
    async with stdio_client(params) as (reader, writer):
        async with ClientSession(reader, writer) as session:
            await session.initialize()
            resource_result = await session.read_resource("file://currencies.txt")
            resource_text = resource_result.contents[0].text
            prompt_result = await session.get_prompt("convert_currency_prompt",
                arguments={"currency_request": user_query})
            prompt_text = prompt_result.messages[0].content.text
            return resource_text, prompt_text

async def get_tools_from_mcp():
    params = StdioServerParameters(command=sys.executable, args=["currency_server.py"])
    async with stdio_client(params) as (reader, writer):
        async with ClientSession(reader, writer) as session:
            await session.initialize()
            response = await session.list_tools()
            return response.tools

async def call_mcp_tool(tool_name: str, arguments: dict) -> str:
    params = StdioServerParameters(command=sys.executable, args=["currency_server.py"])
    async with stdio_client(params) as (reader, writer):
        async with ClientSession(reader, writer) as session:
            await session.initialize()
            result = await session.call_tool(tool_name, arguments)
            return str(result.content[0].text)

async def call_llm_with_context(user_query: str):
    """Call the LLM with resource and prompt context from MCP."""
    resource_text, prompt_text = await get_context_from_mcp(user_query)

    # Combine the resource and prompt text
    full_prompt = ____ + "\n\nSupported currencies:\n" + ____

    client = AsyncAnthropic(api_key="")
    mcp_tools = await get_tools_from_mcp()
    anthropic_tools = [{"name": t.name, "description": t.description or "", "input_schema": t.inputSchema} for t in mcp_tools]

    # Send full_prompt (as a user message) and the tools list to the model
    response = await client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        messages=[{"role": "user", "content": ____}],
        tools=anthropic_tools,
    )

    # Return the text response
    if response.stop_reason == "____":
        text = next((block.text for block in response.content if block.type == "text"), "")
        print(f"\nAssistant: {text}")
        return str(____)

    # Call the tool requested in the LLM's tool use
    if response.stop_reason == "____":
        tool_use = next(block for block in response.content if block.type == "tool_use")
        result = await call_mcp_tool(____.name, ____)
        followup = await client.messages.create(
            model="claude-sonnet-4-6",
            max_tokens=1024,
            messages=[
                {"role": "user", "content": full_prompt},
                {"role": "assistant", "content": response.content},
                {"role": "user", "content": [{"type": "tool_result", "tool_use_id": tool_use.id, "content": result}]},
            ],
            tools=anthropic_tools,
        )
        final_text = next((block.text for block in followup.content if block.type == "text"), None)
        if final_text:
            print(f"\nAssistant: {final_text}")
            return str(final_text)

print("=== Ambiguous request (prompt asks for clarification) ===")
asyncio.run(call_llm_with_context("Convert some euros to dollars"))
print("\n=== Unambiguous request (model calls tool) ===")
asyncio.run(call_llm_with_context("How much is 50 GBP in euros?"))
Edit and Run Code