felipemelendez
MCP Serverfelipemelendezpublic

mcp agent experiments

A sandbox for experimenting with the Model Context Protocol and custom LLM agents.

Repository Info

0
Stars
0
Forks
0
Watchers
0
Issues
Python
Language
-
License

About This Server

A sandbox for experimenting with the Model Context Protocol and custom LLM agents.

Model Context Protocol (MCP) - This server can be integrated with AI applications to provide additional context and capabilities, enabling enhanced AI interactions and functionality.

Documentation

🛠️ MCP Quickstart

MCP lets any LLM use real‑world tools in 3 lines of code—from browsing the web to querying databases, all with an open protocol.

Connect any LLM to any MCP server — no proprietary client required

Model Context Protocol (MCP) is a lightweight spec that lets large language models reach outside their training data by calling remote servers that expose tools such as browser automation, database queries, 3‑D renderers, and more.


📑 Table of Contents

  • 🚀 Why MCP Matters
  • 🤖 What’s an Agent?
  • ⚡ Quickstart Checklist
  • 🧰 Why We Use mcp-use
  • 🧩 Example Agents
  • 💡 Tips & Troubleshooting
  • 📚 Common Commands
  • 🌐 Appendix — Protocols Primer
  • 📡 Appendix — MCP Protocol Details
  • ⚖️ License

🚀 Why MCP Matters

MCP is “REST for AI tools” — where REST standardized data exchange, MCP standardizes capability exchange.

Just as HTTP and REST transformed web development, MCP creates a standard way for AI models to discover and use real‑world tools:

  1. Vendor‑agnostic – Any JSON‑emitting LLM can drive any MCP server
  2. Safety & control – Tool schemas make capabilities explicit; risky actions can be whitelisted or sandboxed
  3. Composability – Mix‑and‑match servers (browser + vector DB + email) just as REST let us compose micro‑services

🤖 What's an Agent?

An agent is a super‑smart assistant that can reason, choose a tool, and use it on your behalf.

The Agent Loop

  1. Listen — reads your goal in plain language
  2. Plan — decides whether the answer needs outside information or action
  3. Act — if needed, picks the best tool (search engine, database, email‑sender, etc.) and calls it with the right inputs
  4. Learn — looks at the tool's reply and figures out what to do next
  5. Respond — once it has everything, explains the final answer back to you

📎 Analogy:
Imagine asking a human assistant, “Book me a hotel in Paris under $200 a night.”
They think (compare options) → use a browser (look up hotels) → read results (price, location) → decide (which fits) → reply (the choice).
An MCP agent does the same loop, but lightning‑fast and with computer tools.

🛠️ Behind the Scenes (but simplified)

StepUnder‑the‑hood action
ThinkThe language model brainstorms possible next moves
Tool‑CallIt sends a short, structured request (JSON) to the chosen tool
ObserveGets structured results back (numbers, URLs, text)
Repeat or FinishLoops until it's confident enough to answer you

No coding is required from you—the agent and MCP handle all the “plumbing,” so your only job is to ask the question.


⚡ Quickstart Checklist (from zero)

1  Start in a fresh terminal

mkdir mcp-quickstart
cd mcp-quickstart

2  Open the folder in Cursor (optional)

open -a "Cursor" .

3  Create & activate the virtual env (repeat inside any new shell)

python3 -m venv venv
source venv/bin/activate

4  Install dependencies

pip install mcp-use langchain-openai python-dotenv

Need Anthropic, Groq, etc.? Swap in langchain-anthropic, langchain-groq, …

5  Add your LLM API key in a .env file

echo "OPENAI_API_KEY=sk-..." > .env

6  Create browser_mcp.json

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest"],
      "env": { "DISPLAY": ":1" }
    }
  }
}

7  Create agent.py

import asyncio, os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from mcp_use import MCPClient, MCPAgent

load_dotenv()

async def main():
    client = MCPClient.from_config_file("browser_mcp.json")
    llm    = ChatOpenAI(model="gpt-4o")
    agent  = MCPAgent(llm=llm, client=client, max_steps=30)
    result = await agent.run("Find the best coffee shop in Brooklyn")
    print(result)

if __name__ == "__main__":
    asyncio.run(main())

8  Run the agent

python agent.py

⌛ First launch downloads the Playwright MCP server via npx, so it may take a minute.

Project tree should now look like:

mcp-quickstart/
├── agent.py
├── browser_mcp.json
├── .env
└── venv/

🧰 Why We Use mcp-use

A tiny Python toolkit that erases the boilerplate you'd normally write to talk to MCP servers.

mcp-use is a plug‑and‑play agent harness that:

  1. Boots or attaches to every MCP server you list (Playwright, Postgres, custom tools, …)
  2. Fetches each tool's JSON schema so the LLM sees a live catalog of capabilities
  3. Keeps sessions alive, meaning heavyweight resources (an open browser, a DB connection) persist across calls
  4. Exposes two high‑level classes:
    • MCPClient – manages connections and routes calls
    • MCPAgent – wraps your LLM and runs the classic think → act → observe loop for you

🚀 Why It Feels “Serverless”

Everything runs right inside your terminal (or any Python script). There’s no separate daemon or hosted gateway—your process speaks directly to MCP servers over WebSocket/stdio.

async def main():
    client = MCPClient.from_config_file("browser_mcp.json")
    llm    = ChatOpenAI(model="gpt-4o")
    agent  = MCPAgent(llm=llm, client=client)
    result = await agent.run("Find me ramen in Portland under $20")
    print(result)

🆚 How It Differs (in one breath)

Unlike heavyweight “agent platforms” that ship their own orchestration layer, mcp-use stays minimal: no extra protocol, no hosted runtime, no vendor lock‑in—just a thin Python wrapper around the open MCP spec.


🧩 Example Agents

AgentPurposeMCP Servers Used
Quick Restaurant FinderOne‑liner demo that uses a Playwright browser to fetch “best restaurant” results for San FranciscoPlaywright (browser automation)
Airbnb FinderSurfaces top holiday rentals that meet price, amenity, and date constraintsPlaywright (browser) + Airbnb MCP
Restaurant ScoutRanks the best restaurants in any city via live Google search and review‑site scrapingPlaywright (browser automation)
Equity ScreenerScrapes live fundamentals and returns growth/value/dividend shortlists on demandPlaywright (browser automation)

💡 Tips & Troubleshooting

  • venv gotcha – Opening a new terminal (or the built‑in one inside Cursor) starts a fresh shell, so re‑activate the venv with source venv/bin/activate. (Closing your terminal without deactivating does not break anything—just reactivate next time.)
  • ModuleNotFoundError: fastembed – Install with pip install "mcp-use[search]" or pip install fastembed
  • Step limit – Raise max_steps if your agent stops too early
  • Safety filter – Block risky tools by passing disallowed_tools=[...] to MCPAgent

📚 Common Commands

  • pip install mcp-use – unified MCP client library
  • pip install "mcp-use[search]" – pulls fastembed & tiny data files when you need semantic search tools
  • pip install langchain-openai – LangChain wrapper for OpenAI models
  • python3 -m venv venv – create venv/
  • source venv/bin/activate – enter the venv in the current shell
  • deactivate – leave the venv (closing the terminal also resets env‑vars)

🌐 Appendix: Understanding Protocols

A 90‑second refresher on why standard handshakes matter, from web pages to AI tools.

📄 HTTP — the web's means of communication

  • What it is: The HyperText Transfer Protocol
  • What it solved: Early browsers and servers spoke different dialects. HTTP standardized the rules—verbs such as GET and POST, status codes like 200 OK or 404 Not Found, headers that describe the payload—so any browser could fetch any page from any server
  • Why it matters: One common contract let developers build on a stable foundation instead of reinventing networking for every site

🔄 RESTful APIs — a shared playbook for data

  • What it is: Conventions layered on top of HTTP that map CRUD actions to HTTP verbs:
    • GET → read
    • POST → create
    • PUT/PATCH → update
    • DELETE → remove
  • What it solved: Web, mobile, and IoT apps could exchange structured data the same predictable way, unlocking speed and interoperability

🤖 MCP — a protocol for agent super‑powers

  • What it is: Model Context Protocol, a spec that standardizes how large‑language‑model (LLM) agents discover, call, and coordinate external tools—from a headless browser to a SQL database or 3‑D renderer
  • What it solves:
    1. Discovery – Tools publish self‑describing JSON schemas, so the agent knows exactly which functions exist and what arguments they expect
    2. Transport – A single bi‑directional channel (WebSocket or HTTP‑stream) carries both requests and responses, eliminating custom glue code
    3. Session state – MCP keeps long‑running resources (e.g., an open browser tab) alive across calls, letting the LLM think → act → observe without constant re‑initialization

📡 Appendix — MCP Protocol Details

For developers who want to see exactly what goes over the wire.


Transport & Envelope

LayerTechnologyWhy It’s Used
WireJSON‑RPC 2.0 over WebSocket, stdio, or SSEGives request/response IDs, typed errors, and streaming without reinventing framing
SessionStateful connection negotiated via initializeKeeps heavyweight resources (e.g., an open browser tab) alive across many calls

Handshake in two messages (client → server):
1️⃣ initialize — declares client name, version, and transports
2️⃣ initialize/complete ← server returns metadata + advertised features (tools, resources, prompts)


🔍 Tool Discovery — “What buttons can I press?”

The agent first asks the server which tools it exposes.
This happens as two separate JSON‑RPC messages.

1. Client → Server

{
  "jsonrpc": "2.0",
  "id": 42,
  "method": "tools/list"
}

2. Server → Client

{
  "jsonrpc": "2.0",
  "id": 42,
  "result": {
    "tools": [
      {
        "name": "calculate_sum",
        "description": "Add two numbers together",
        "inputSchema": {
          "type": "object",
          "properties": {
            "a": { "type": "number" },
            "b": { "type": "number" }
          },
          "required": ["a", "b"]
        },
        "annotations": {
          "idempotentHint": true,
          "openWorldHint": false
        }
      }
    ]
  }
}
FieldMeaning
nameCall‑sign the agent will use later in tools/call.
descriptionNatural‑language cue that steers the LLM.
inputSchemaJSON Schema that enforces argument names, types, & required fields.
annotations.idempotentHinttrue ⇒ safe to call twice with same inputs (no side‑effects).
annotations.openWorldHintfalse ⇒ bounded effects; good for safety filters.

☑️ Because both messages share id = 42, the client can pair request and response even if several calls are inflight.


🛠️ Tool Invocation — “Press the button”

Once the agent knows a tool exists, it can invoke it.

1. Client → Server

{
  "jsonrpc": "2.0",
  "id": 43,
  "method": "tools/call",
  "params": {
    "name": "calculate_sum",
    "arguments": { "a": 5, "b": 7 }
  }
}

2. Server → Client

{
  "jsonrpc": "2.0",
  "id": 43,
  "result": {
    "content": [
      { "type": "text", "text": "12" }
    ]
  }
}

The LLM reads the plain‑text "12", decides whether that satisfies the user’s goal, and either responds or plans another action.


⏱️ Timeline at a Glance

Agent → Server : tools/list      (id 42)
Server → Agent : result.tools…   (id 42)

Agent → Server : tools/call…     (id 43)
Server → Agent : result "12"     (id 43)

Each arrow is a standalone JSON object on the wire — never a bundled request + response.

With just these two primitives—discover & invoke—an LLM agent can explore any MCP server’s capabilities and wield them intelligently with zero hard‑coded API calls.

Call Flow Cheat‑Sheet

sequenceDiagram
  participant Host as LLM Host
  participant Client as MCP Client
  participant Server as MCP Server

  Host->>Client: initialize
  Client->>Server: initialize
  Server-->>Client: initialize/complete
  Client-->>Host: initialize/complete

  Host->>Client: tools/list
  Client->>Server: tools/list
  Server-->>Client: list result
  Client-->>Host: list result

  Host->>Client: tools/call (name, args)
  Client->>Server: tools/call
  Server-->>Client: result
  Client-->>Host: result

Quick Recap

  • JSON‑RPC 2.0 keeps the wire format dead‑simple
  • Tool schemas make capabilities explicit & type‑safe
  • Persistent sessions avoid re‑spinning heavy resources
  • Uniform prefixes (tools/, resources/, prompts/) keep the mental model flat

With these pieces, you can crack open any MCP message log and know exactly what's happening—and, more importantly, why.


⚖️ License

MIT – see LICENSE for details

Quick Start

1

Clone the repository

git clone https://github.com/felipemelendez/mcp-agent-experiments
2

Install dependencies

cd mcp-agent-experiments
npm install
3

Follow the documentation

Check the repository's README.md file for specific installation and usage instructions.

Repository Details

Ownerfelipemelendez
Repomcp-agent-experiments
LanguagePython
License-
Last fetched8/10/2025

Recommended MCP Servers

💬

Discord MCP

Enable AI assistants to seamlessly interact with Discord servers, channels, and messages.

integrationsdiscordchat
🔗

Knit MCP

Connect AI agents to 200+ SaaS applications and automate workflows.

integrationsautomationsaas
🕷️

Apify MCP Server

Deploy and interact with Apify actors for web scraping and data extraction.

apifycrawlerdata
🌐

BrowserStack MCP

BrowserStack MCP Server for automated testing across multiple browsers.

testingqabrowsers

Zapier MCP

A Zapier server that provides automation capabilities for various apps.

zapierautomation