Skip to content

pypypypy5/morph-mcp

Repository files navigation

Morph-MCP

LLM-powered MCP server generator for static site scraping.

Overview

Morph-MCP is a meta-MCP server that uses LLM to generate custom scrapers for static websites. It starts in "morph mode" and transforms into a specialized scraper for your target site.

Features

  • One-time transformation: Morph once into a specialized scraper
  • LLM-powered: Uses GPT-4 or Claude to generate scraper code
  • Self-testing: Tests generated code until it works
  • Simple interface: Just 2 commands: morph and fetch

Installation

# Clone repository
git clone <repo-url>
cd morph-mcp

# Install dependencies
pip install -r requirements.txt

Usage

1. Set API Key

# For OpenAI
export OPENAI_API_KEY="sk-..."

# Or for Anthropic
export ANTHROPIC_API_KEY="sk-ant-..."

2. Run MCP Server

fastmcp run src/main.py

3. Use in Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "morph-mcp": {
      "command": "fastmcp",
      "args": ["run", "/path/to/morph-mcp/src/main.py"]
    }
  }
}

4. Morph the Server

# In Claude Desktop, the assistant will call:
morph(
    target="나무위키",
    description="키워드로 문서 검색 및 내용 가져오기",
    test_query="Python"
)

This generates a scraper and saves it to generated/scraper.py.

5. Use the Scraper

# After morphing, use fetch:
fetch(query="인공지능")
# Returns HTML content from 나무위키

Commands

morph(target, description, test_query, provider, api_key)

Generate a scraper for a target site.

  • target: Site name (e.g., "나무위키")
  • description: What to scrape (e.g., "키워드로 문서 검색")
  • test_query: Sample query to test (e.g., "Python")
  • provider: "openai" or "anthropic" (default: "openai")
  • api_key: Optional if set in environment

fetch(query)

Use the generated scraper to fetch content.

  • query: Search keyword, URL, etc.

status()

Check current state (morph mode or morphed).

reset()

Reset to morph mode (deletes generated scraper).

Architecture

src/
├── main.py          # FastMCP server (morph/fetch tools)
├── llm_client.py    # LLM abstraction (OpenAI/Anthropic)
└── agent.py         # Generate-test-retry loop

generated/
└── scraper.py       # Generated scraper code

state.json           # {"morphed": bool, "target": str}

How It Works

  1. Morph: LLM generates scraper code → tests it → retries if failed → saves when successful
  2. Fetch: Imports generated scraper → runs it → returns result

Example

# Initial state
$ status()
🔄 Morph mode: Ready to generate scraper

# Morph into 나무위키 scraper
$ morph("나무위키", "키워드로 검색", "Python")
[Agent] Attempt 1/10
[Agent] Generated 450 characters of code
[Agent] ✅ Success on attempt 1!
✅ 나무위키 scraper generated successfully!

# Check status
$ status()
📡 Morphed into: 나무위키-server

# Fetch content
$ fetch("Python")
<html>... 나무위키 Python 페이지 내용 ...</html>

Testing

# Run all tests
pytest

# Run specific test
pytest tests/test_agent.py -v

# Run with coverage
pytest --cov=src tests/

Limitations

  • One-time morph: Cannot change target after morphing (use reset() first)
  • Static sites only: No JavaScript rendering (no Playwright)
  • Max 10 retries: Fails if LLM can't generate working code

Development

See docs/PROJECT.md for detailed architecture and module specifications.

License

MIT

About

A self-evolving MCP server that morphs into any site crawler on demand

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages