Files
pi_mcps/docs/wiki/pages/Development-Conventions.md
T

5.3 KiB

🛠️ Development Conventions

Dev Conventions Banner

All MCP servers in this repo follow a consistent set of conventions to ensure maintainability, testability, and compatibility with Roo Code tooling.

Directory Structure

Each MCP server lives at mcp/<server-name>/ with this layout:

mcp/<server-name>/
├── src/
│   ├── __init__.py
│   └── server.py          ← FastMCP server entry point
├── tests/
│   ├── conftest.py        ← sys.path + shared fixtures
│   └── test_server.py     ← pytest test suite (100% mock coverage)
├── pyproject.toml         ← uv-managed dependencies
├── README.md              ← server documentation
├── PLAN.md                ← architecture plan (pre-implementation)
└── ASSESSMENT.md          ← pre-implementation assessment

FastMCP Pattern

from fastmcp import FastMCP

mcp = FastMCP("server-name")

@mcp.tool()
def my_tool(param: str) -> str:
    """Tool description shown to the AI."""
    return result

if __name__ == "__main__":
    mcp.run()

Package Management

All projects use uv — never pip directly:

# Create new server
uv init mcp/my-server
cd mcp/my-server
uv add fastmcp httpx

# Sync dependencies
uv sync

# Run server
uv run python src/server.py

# Run tests
uv run pytest tests/ -v

pyproject.toml Template

[project]
name = "mcp-my-server"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
    "fastmcp>=2.0.0",
    "httpx",
]

[project.optional-dependencies]
test = ["pytest", "pytest-mock", "pytest-cov"]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.pytest.ini_options]
testpaths = ["tests"]

Testing Conventions

  • Tests live in tests/test_server.py
  • conftest.py sets sys.path so imports work without install
  • Use pytest via uv run pytest
  • Mock all external calls (HTTP, filesystem, subprocess) with pytest-mock or respx
  • monkeypatch for env vars and module-level state
  • Aim for 100% tool function coverage
  • All tests must pass before committing

Branching Strategy

Never commit to main directly.

Branch format: type/scope/short-description

Types:   feat / fix / docs / chore / spike
Scopes:  bigmind / webscraper / cannamanage / workshop / roo / plans / homelab

Examples:
  feat/mcp/new-gitea-server
  fix/bigmind/achievement-card-images
  docs/wiki/update-conventions
  chore/roo/update-mcp-json

Merge to main with --no-ff after push to Gitea.

Commit Convention

Follow Conventional Commits format:

feat(mcp-webscraper): add webscraper_search_hint tool using Brave Search
fix(bigmind): achievement card images missing background-image CSS
docs(wiki): add Java projects pages
test(mcp-image-gen): add edge case tests for generate_image
refactor(bigmind): extract profile builder to separate module
chore(roo): update mcp.json with new server entry

Wiki Update Workflow

Wiki pages live as real Markdown files in docs/wiki/pages/. To update and deploy:

# 1. Edit the .md files in docs/wiki/pages/
# 2. Deploy to Gitea wiki git repo:
./docs/wiki/deploy_wiki.sh

The deploy script clones the wiki git repo (pi_mcps.wiki.git), syncs all .md files, and pushes.

Creating a New MCP Server

Use the new-mcp-server Roo skill in MCP Builder mode for full scaffolding:

1. Switch to 🔧 MCP Builder mode in Roo Code
2. Say: "Create a new MCP server for <purpose>"
3. Roo will load the new-mcp-server skill and scaffold everything

Web Research with mcp-webscraper

Before asking Patrick for information about a library, framework, API, or technology — search first.

The webscraper MCP server provides webscraper_search_hint (Brave Search, no API key, always available) as the entry point for all research tasks. Use the two-step pattern:

Step 1: webscraper_search_hint("topic or error message") → get candidate URLs
Step 2: webscraper_fetch(best_url)                       → read the full page
Situation Action
Need docs for a library or framework webscraper_search_hint("library-name official docs")
Investigating an error or stack trace webscraper_search_hint("exact error message language")
Planning a feature — need design patterns webscraper_search_hint("pattern-name best practices")
Checking latest version / changelog webscraper_search_hint("library-name changelog release")
Looking up API contracts webscraper_fetch(official_docs_url) directly

Especially useful in

  • 🏗️ Architect mode — look up patterns and docs before designing. Don't design blind.
  • 🪲 Debug mode — search the exact error message before forming hypotheses.
  • 🔧 MCP Builder mode — check FastMCP changelog for new patterns before implementing.

Known caveats

  • Reddit and Stack Overflow may return empty snippets (platform blocks)
  • Brave uses Svelte CSS classes that can change — if webscraper_search_hint returns 0 results, selectors may need updating (last verified: 2026-04-05)

Gitea Repository

Code is hosted at: http://192.168.188.119:30008/pplate/pi_mcps

Push with the gitea-push Roo skill to ensure conventional commit format and correct branch workflow.