dapr-agents/cookbook/mcp/basic
Casper Nielsen f129754486
Fix/30 add linter action (#95)
* Fix: Fix Setup lint GitHub action #30

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Remove branch filter on PR and remove on push

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Remove on mergequeue

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: Add tox.ini file

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Return on push

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Chore: tox -e ruff

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Ignore .ruff_cache

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Chore: Update tox file

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Chore: Add mypy.ini

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Ignore if line is too long

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: Set the ignore in command instead

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: W503

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: F541

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: 541

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: W503

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: F541

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Chore: Ignore F401, unused imports as __init__ files has them

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Return linebreak as tox -e ruff yields that

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Ignore W503 as ruff introduces it

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: F841

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: E203

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: W293

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: W291

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: F541

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: E203

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: E203

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: W291

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: F541

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: F811

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: F841

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: F811

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: F541

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: F541

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: F841

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: F811

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: W291

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: F811

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: F541

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: F541

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Ruff want's the space before :

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Ignore space before :

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: E291

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: Add dev-requirements.txt

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: Correct python version

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: Ref dev-requirements.txt

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: Add mypy cache dir

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Chore: Update mypy version

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Fix: Exclude cookbook and quicstarts

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Remove unused import

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Chore: Add specific sub module ignore on error for future smaller fixing

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Reintroduce branches filter on push and pull_request

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* chore: Ruff

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Chore: ruff formatting

* Chore: F541

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Chore: E401

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Chore: Ruff

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Chore: F811

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Chore: F841

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Chore: Ruff

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Chore: E711

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

* Chore: ruff

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>

---------

Signed-off-by: Casper Guldbech Nielsen <scni@novonordisk.com>
2025-04-23 22:58:48 -07:00
..
README.md Integrate MCP Client + Enable Async Tool Execution for Agent Framework (#72) 2025-04-10 14:31:03 -07:00
requirements.txt Integrate MCP Client + Enable Async Tool Execution for Agent Framework (#72) 2025-04-10 14:31:03 -07:00
server.py Fix/30 add linter action (#95) 2025-04-23 22:58:48 -07:00
sse.ipynb Integrate MCP Client + Enable Async Tool Execution for Agent Framework (#72) 2025-04-10 14:31:03 -07:00
stdio.ipynb Integrate MCP Client + Enable Async Tool Execution for Agent Framework (#72) 2025-04-10 14:31:03 -07:00
tools.py Fix/30 add linter action (#95) 2025-04-23 22:58:48 -07:00

README.md

🧪 Basic MCP Agent Playground

This demo shows how to use a lightweight agent to call tools served via the Model Context Protoco (MCP). The agent uses a simple pattern from dapr_agents — but without running inside Dapr.

Its a minimal, Python-based setup for:

  • Exploring how MCP tools work
  • Testing stdio and SSE transport
  • Running tool-calling agents (like ToolCallingAgent or ReActAgent)
  • Experimenting without durable workflows or Dapr dependencies

🧠 Looking for something more robust?
Check out the full dapr_agents repo to see how we run these agents inside Dapr workflows with durable task orchestration and state management.


🛠️ Project Structure

.
├── tools.py         # Registers two tools via FastMCP
├── server.py        # Starts the MCP server in stdio or SSE mode
├── stdio.ipynb    # Example using ToolCallingAgent over stdio
├── sse.ipynb      # Example using ToolCallingAgent over SSE
├── requirements.txt
└── README.md

Installation

Before running anything, make sure to install the dependencies:

pip install -r requirements.txt

🚀 Starting the MCP Tool Server

The server exposes two tools via MCP:

  • get_weather(location: str) → str
  • jump(distance: str) → str

Defined in tools.py, these tools are registered using FastMCP.

You can run the server in two modes:

▶️ 1. STDIO Mode

This runs inside the notebook. It's useful for quick tests because the MCP server doesn't need to be running in a separate terminal.

  • This is used in stdio.ipynb
  • The agent communicates with the tool server via stdio transport

🌐 2. SSE Mode (Starlette + Uvicorn)

This mode requires running the server outside the notebook (in a terminal).

python server.py --server_type sse --host 127.0.0.1 --port 8000

The server exposes:

  • /sse for the SSE connection
  • /messages/ to receive tool calls

Used by sse.ipynb

📌 You can change the port and host using --host and --port.

📓 Notebooks

There are two notebooks in this repo that show basic agent behavior using MCP tools:

Notebook Description Transport
stdio.ipynb Uses ToolCallingAgent via mcp.run("stdio") STDIO
sse.ipynb Uses ToolCallingAgent with SSE tool server SSE

Each notebook runs a basic ToolCallingAgent, using tools served via MCP. These agents are not managed via Dapr or durable workflows — it's pure Python execution with async support.

🔄 Whats Next?

After testing these lightweight agents, you can try:

  • Running the full dapr_agents workflow system
  • Registering more complex MCP tools
  • Using other agent types (e.g., ReActAgent, AssistantAgent)
  • Testing stateful, durable workflows using Dapr + MCP tools