Skip to main content
Glama
vdonthireddy

GemmaJnana

by vdonthireddy
README.md
# MCP Skills

A lightweight, robust, and decoupled CLI/Agent framework demonstrating **progressive disclosure of Agent Skills** over the **Model Context Protocol (MCP)**. 

This project implements a complete local agentic loop that communicates with a backend MCP server using `stdio` transport. It enables the agent to discover tools and fetch complex instructions (skills) dynamically and on-demand only when relevant.

## πŸ—ΊοΈ Obsidian Vault Map
*Quickly navigate the documentation inside Obsidian:*
- 🏠 **Home (README)**: [[README]]
- πŸ“– **Layman's Guide**: [[LAYMAN_GUIDE|A Layman's Guide to MCP Skills]]
- βš™οΈ **System Flow & Walkthrough**: [[FLOW|How it works β€” an end-to-end walkthrough]]
- πŸ΄β€β˜ οΈ **Example Skill**: [[skills/pirate-speak/SKILL|Pirate Speak Skill (SKILL.md)]]

---

## Key Features

- **Decoupled Architecture**: Process A (CLI/Agent) communicates with Process B (MCP Server) strictly via JSON-RPC over the Model Context Protocol. No importing of server tools or skill loader logic in the agent.
- **Progressive Skill Disclosure**: The agent first lists metadata (names and descriptions) of available skills cheaply and only pulls the token-heavy instructions when the LLM determines the skill is relevant.
- **AST-based Calculator**: A safe math evaluation tool restricting execution to basic numbers and arithmetic operations, fully protected against remote code execution.
- **Robust Local Testing**: Built-in rule-based and scripted `DummyClient` allowing deterministic, offline testing of multi-step agent behaviors without needing LLM API keys.
- **Real LLM Integration**: Seamless toggle to real OpenAI-compatible endpoints using environment configuration.
- **Modern Package Layout**: Structured clean package layout using a Click-based CLI and pyproject.toml setup.

---

## System Architecture

```mermaid
graph LR
    subgraph CLI_PROC["Process A β€” CLI / Agent"]
        CLI["cli.py<br/>run command"]
        AG["Agent<br/>ReAct Loop"]
        LLM["LLMClient<br/>(Dummy / OpenAI)"]
        MC["MCPClient<br/>(stdio client)"]
        CLI --> AG
        AG --> LLM
        AG --> MC
    end

    subgraph SRV_PROC["Process B β€” MCP Server"]
        SRV["FastMCP Server<br/>app.py"]
        TOOLS["Tools<br/>calculator, echo"]
        SKILLS["Skills<br/>list_skills / load_skill<br/>+ prompts"]
        SRV --> TOOLS
        SRV --> SKILLS
    end

    MC <-->|"MCP stdio<br/>(JSON-RPC on stdin/stdout)"| SRV
    LLM -.->|"OpenAI Chat API"| EXT["LLM API Endpoint"]
```

---

## Project Layout

```text
mcp-skills-new/
β”œβ”€β”€ chatbot-ui/                 # Premium Chatbot Web UI
β”œβ”€β”€ start.sh                    # Starts MCP server & UI in background
β”œβ”€β”€ stop.sh                     # Stops background services
β”œβ”€β”€ pyproject.toml              # Build backend and dependencies config
β”œβ”€β”€ FLOW.md                     # Walkthrough explaining how the framework runs
β”œβ”€β”€ README.md                   # This overview file
β”œβ”€β”€ skills/                     # Builtin skills catalog
β”‚   └── pirate-speak/
β”‚       └── SKILL.md            # Pirate-speak instructions with frontmatter
β”œβ”€β”€ src/
β”‚   └── mcp_skills/
β”‚       β”œβ”€β”€ __init__.py
β”‚       β”œβ”€β”€ cli.py              # Click commands entry point
β”‚       β”œβ”€β”€ config.py           # Configuration parser settings
β”‚       β”œβ”€β”€ agent/              # CLI Agent components
β”‚       β”‚   β”œβ”€β”€ __init__.py
β”‚       β”‚   β”œβ”€β”€ agent.py        # ReAct orchestration loop
β”‚       β”‚   β”œβ”€β”€ mcp_client.py   # MCP stdio client wrapper
β”‚       β”‚   └── prompts.py      # System prompts
β”‚       β”œβ”€β”€ llm/                # LLM connectors (Dummy & OpenAI)
β”‚       β”‚   β”œβ”€β”€ __init__.py
β”‚       β”‚   β”œβ”€β”€ base.py
β”‚       β”‚   β”œβ”€β”€ dummy.py
β”‚       β”‚   └── openai_client.py
β”‚       └── server/             # Stdio/SSE MCP server
β”‚           β”œβ”€β”€ __init__.py
β”‚           β”œβ”€β”€ __main__.py
β”‚           β”œβ”€β”€ app.py          # FastMCP server wiring
β”‚           β”œβ”€β”€ skills/         # Skill markdown loader
β”‚           β”‚   β”œβ”€β”€ __init__.py
β”‚           β”‚   β”œβ”€β”€ loader.py
β”‚           β”‚   └── models.py
β”‚           └── tools/          # Registry and builtin tools
β”‚               β”œβ”€β”€ __init__.py
β”‚               β”œβ”€β”€ base.py
β”‚               β”œβ”€β”€ registry.py
β”‚               └── builtins.py
└── tests/                      # 18 pytest unit/integration tests
```

> [!TIP]
> **Obsidian Navigation Tip:** You can open and edit key files directly inside Obsidian using these links:
> - [[FLOW]] β€” Detailed technical walkthrough of the ReAct agent loop and the stdio communication.
> - [[LAYMAN_GUIDE]] β€” High-level, developer-friendly overview with analogies.
> - [[skills/pirate-speak/SKILL]] β€” The example skill instruction template.

---

## Installation

Install the package and its development dependencies in editable mode:

```bash
python3 -m pip install -e ".[dev]"
```

---

## Usage

### 1. Run the Agent Loop
Trigger the agent to answer questions. It will spawn the stdio MCP server subprocess automatically, inspect active tools, reason through steps, call appropriate tools, and return a summary.

#### Math execution (uses AST calculator tool):
```bash
mcp-skills run "what is 6 * 7?"
```

#### Skills discovery & lazy loading:
```bash
mcp-skills run "what skills exist?"
```

### 2. Explore Discovered Skills via CLI
Explore loaded skill templates without starting the agent loop:
```bash
mcp-skills skills list
```

### 3. Run Standalone MCP Server
Start a raw MCP server listening on stdin/stdout:
```bash
mcp-skills serve
```

Inspect tools and prompts interactively via the [MCP Inspector](https://github.com/modelcontextprotocol/inspector):
```bash
npx @modelcontextprotocol/inspector mcp-skills serve
```

### 4. Web UI & Background Server
We provide scripts to run the MCP Server and a static web UI in the background:
```bash
./start.sh
```
This starts the `mcp-skills serve` on port 8000 via SSE and a Python HTTP server on port 8080. Navigate to `http://127.0.0.1:8080` to access the Chatbot UI.

To stop the background processes, run:
```bash
./stop.sh
```

---

## Running with a Real LLM

To switch from the offline `DummyClient` to a real model, create a `.env` file in the project root:

```ini
MCP_SKILLS_LLM_PROVIDER=openai
MCP_SKILLS_MODEL=gpt-4o-mini
MCP_SKILLS_OPENAI_BASE_URL=https://api.openai.com/v1
MCP_SKILLS_OPENAI_API_KEY=your-api-key-here
```

---

## Running Tests

Execute the test suite to run 18 offline verification checks:

```bash
pytest -v
```