Perch - MCP HexLayer Scaffolding CLI
Perch is a developer-friendly command-line tool for scaffolding and managing MCP HexLayer Architecture server projects.
It helps you build modular, maintainable MCP servers using clean structure and naming conventions based on primarily on CGUDL (Create, Get, Update, Delete, List), but you can use ACTION type naming conventions.
Features
- Scaffold full MCP HexLayer projects
- Add integrations, tools, services, and schemas
- Works with uv
- Built with Typer
Installation
To install Perch, use pip:
pip install perch-py
For more details, visit the Perch-Py PyPI page.
Usage
Perch provides commands to initialize new projects, create new projects in separate directories, and add various components (integrations, tools, services, schemas) to an existing project.
Initialize Project in Current Directory (perch init)
Initializes a Perch project in the current working directory.
perch init
With an optional integration:
perch init --integration github
To initialize a project where the -mcp-server suffix is not enforced on the project name:
perch init --normal # Note: Not Recommended
Create New Project (perch create)
Creates a new Perch project in a new directory. By default, if no --normal flag is used, the project name for an MCP server will be strictly suffixed with -mcp-server (e.g., my-server becomes my-server-mcp-server).
perch create my-mcp-server
With an optional integration:
perch create my-mcp-server --integration github
To create a project where the -mcp-server suffix is not enforced on the project name:
perch create my-normal-project --normal # Note: Not Recommended
After Project Initialization/Creation
After perch init or perch create, navigate into your project directory and activate the virtual environment:
cd my-mcp-server # or my-normal-project
uv venv activate
python main.py
Add Commands (perch add)
The perch add command is used to add various components to an existing Perch project.
Add Integration (perch add integration)
Adds a new integration by creating its directory structure and a client.py file.
perch add integration github
Creates:
integrations/github/
interfaces/tools/github/
interfaces/resources/github/
schemas/github/
services/github/
integrations/github/client.py
And the content of integrations/github/client.py:
# integrations/github/client.py
class GithubClient:
def __init__(self):
pass
def connect(self):
# Implement connection logic here
print(f"Connecting to {self.__class__.__name__}...")
pass
Add Tool (perch add tool)
Adds a new tool file for a given integration and entity.
perch add tool github user
Creates:
# interfaces/tools/github/user.py
from core.data.tool import ToolResponse
from pydantic import Field
from schemas.github.user import UserInputSchema, UserResponseSchema
from services.github.user import create_user
def create_user_tool(
sample1: str = Field(..., description="The sample1 of the user."),
sample2: str = Field(..., description="The sample2 of the user.")
) -> ToolResponse:
"""
Creates a new user with the provided sample1 and sample2.
"""
user = create_user(UserInputSchema.model_validate({"sample1": sample1, "sample2": sample2}))
if not user:
return ToolResponse(status="error", message="User creation failed.")
return ToolResponse(
status="success",
message="User created successfully",
data=UserResponseSchema.model_validate(user)
)
Add Service (perch add service)
Adds a new service file for a given integration and entity.
perch add service github user
Creates:
# services/github/user.py
from schemas.github.user import UserInputSchema, UserResponseSchema
import uuid
import datetime
def create_user(input_data: UserInputSchema) -> UserResponseSchema:
# Example Process
item = {
"sample1": input_data.sample1,
"sample2": input_data.sample2,
}
return UserResponseSchema(**item)
Add Schema (perch add schema)
Adds a new schema file for a given integration and entity.
perch add schema github user
Creates:
# schemas/github/user.py
from pydantic import BaseModel
from typing import Optional
class UserInputSchema(BaseModel):
sample1: str
sample2: str
class UserResponseSchema(BaseModel):
sample1: str
sample2: str
# Add other fields as necessary, e.g., id, created_at
Add All Layers (perch add all)
Adds tool, service, and schema files for a given integration and entity in one go.
perch add all github user
Creates:
# interfaces/tools/github/user.py
# services/github/user.py
# schemas/github/user.py
Constraints and Flags
Perch commands often support flags to modify their behavior.
--integration(-i): Used to specify an initial integration when creating or initializing a project.--normal(-n): This flag allows you to create a standard Python project instead of an MCP server project. When used, Perch will scaffold a basic Python project structure without the MCP-specific server components. For projects created with--normal, the-mcp-serversuffix is not enforced on the project name, allowing for more flexible naming for non-MCP projects.
- Naming Convention for MCP Server Projects: By default, when creating an MCP server project (i.e., without the
--normalflag), Perch strictly enforces that the project directory name ends with-mcp-server. For example, if you runperch create my-server, the created directory will bemy-server-mcp-server. This suffix is mandatory for all MCP server projects to ensure consistency and clear identification.
Architecture Explanation
Overview
Perch is designed to facilitate the development of MCP HexLayer Architecture servers. It promotes a clean, modular structure by separating concerns into distinct layers: integrations, interfaces (tools, resources, prompts), schemas, and services. This approach, inspired by the Hexagonal Architecture (Ports and Adapters) and primarily based on CGUDL (Create, Get, Update, Delete, List) principles, ensures maintainability, testability, and scalability. The name "Perch" signifies this elevated and clear perspective that clean architecture provides over system layers.
Detailed Architecture
For a comprehensive explanation of the MCP HexLayer Architecture, please refer to the MCP Python SDK repository.
Example Project Structure
my-mcp-server/
├── main.py
├── core/
│ ├── server.py
│ └── data/
│ └── tool.py
├── config/
├── integrations/
│ └── github/
├── interfaces/
│ ├── tools/
│ │ └── github/
│ ├── resources/
│ │ └── github/
│ └── prompts/
├── schemas/
│ └── github/
├── services/
│ └── github/
└── .venv/
Local Development
Installation
add git clone then cd or etc.
To set up Perch for local development:
uv pip install -e .
Then, you can run the CLI:
perch --help
Uninstall
uv pip uninstall perch-py
Reinstall After Edits
uv pip install -e .
License
This project is licensed under the MIT License. See LICENSE for details.
Metadata
Release files for perch-py 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| perch_py-0.1.3.tar.gz | 34.6 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| perch_py-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 48.3 kB
Release files / perch_py-0.1.3.tar.gz
| Download URL | perch_py-0.1.3.tar.gz |
|---|---|
| Size | 34.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
23df02f1f1f04ed1fb0f7b9fbb54c9516c9fbd4eefbb2140b4b0801d8bed1099
|
|
BLAKE2b-256 checksum How to use checksums |
b98b99bbd11a0b062b53affa6afb36a242b8aa3f2923bb615125177d00918db8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 10, 2025.
Transparency logRelease files / perch_py-0.1.3-py3-none-any.whl
| Download URL | perch_py-0.1.3-py3-none-any.whl |
|---|---|
| Size | 13.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f95f6d374b4fdf7d550927290d0dff13049e59bb59fadbdcd8d839ae37a5e992
|
|
BLAKE2b-256 checksum How to use checksums |
1a03ffab8d864ac397cb4b4af6d10564ca64357c35283b54f0054a2591127cdb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 10, 2025.
Transparency logSecurity for perch-py 0.1.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for perch_py-0.1.3.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 10, 2025.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.