# https://github.com/rudi193-cmd/willow-mcp Project Manual

Generated at: 2026-07-14 04:01:56 UTC

## Table of Contents

- [Project Overview](#page-overview)
- [System Architecture and Storage Backends](#page-architecture)
- [Authorization, Schema Adaptation, and Identity Binding](#page-auth-schema-identity)
- [Deployment, Operations, and Extensibility](#page-deployment-ops)

<a id='page-overview'></a>

## Project Overview

### Related Pages

Related topics: [System Architecture and Storage Backends](#page-architecture), [Deployment, Operations, and Extensibility](#page-deployment-ops)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/rudi193-cmd/willow-mcp/blob/main/README.md)
- [src/willow_mcp/__init__.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/__init__.py)
- [src/willow_mcp/__main__.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/__main__.py)
- [pyproject.toml](https://github.com/rudi193-cmd/willow-mcp/blob/main/pyproject.toml)
</details>

# Project Overview

`willow-mcp` is a Python project that ships a Model Context Protocol (MCP) server named **Willow**. The repository uses a standard `src/` layout, declares its build configuration in `pyproject.toml`, and exposes an executable entry point through `python -m willow_mcp`. The package appears positioned as a small, focused MCP server that can be wired into MCP-aware clients (such as LLM tool-using agents) to expose project-specific tools and resources.

This page summarizes the structure and role of the project based on the files listed above. It does not attempt to document individual tools or runtime behavior beyond what is observable from the top-level configuration and entry points.

## 1. Purpose and Scope

The project is named `willow-mcp` and is structured as a single importable Python package, `willow_mcp`. Based on the repository layout and naming convention, the project's primary purpose is to function as an **MCP server implementation** that can be launched as a standalone process and communicate with MCP clients over the protocol's standard transport.

The scope is intentionally narrow:

- The repository contains exactly one Python package, `willow_mcp`, located under `src/willow_mcp/`.
- The presence of `__main__.py` indicates the package is invokable directly via `python -m willow_mcp`.
- Configuration is centralized in a single `pyproject.toml`, with no additional build files (no `setup.py`, no `setup.cfg`) referenced from the listed files.

Source: [README.md](https://github.com/rudi193-cmd/willow-mcp/blob/main/README.md)
Source: [pyproject.toml](https://github.com/rudi193-cmd/willow-mcp/blob/main/pyproject.toml)

## 2. Package Layout and Entry Points

The package follows the conventional Python `src/` layout:

```
willow-mcp/
├── pyproject.toml
├── README.md
└── src/
    └── willow_mcp/
        ├── __init__.py
        └── __main__.py
```

- `src/willow_mcp/__init__.py` — marks the directory as a Python package and is the conventional location for top-level imports, version metadata, and re-exports.
- `src/willow_mcp/__main__.py` — provides the `python -m willow_mcp` entry point. MCP servers in this style typically read protocol messages on `stdin` and write responses on `stdout`, which is the default transport for many lightweight MCP clients.

This minimal layout signals that the project favors a small, dependency-light deployment footprint rather than a framework-heavy application structure.

Source: [src/willow_mcp/__init__.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/__init__.py)
Source: [src/willow_mcp/__main__.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/__main__.py)

## 3. Build System and Distribution

The project relies on `pyproject.toml` as its single source of build and packaging metadata. This PEP 621–compliant configuration is the modern Python standard for:

- Declaring the project name, version, and author metadata.
- Specifying runtime and optional dependencies (commonly `mcp` and any tool-specific libraries).
- Defining the console script entry point, which typically maps a `willow-mcp` command to a callable inside the package.

Because no other build files are included in the listed sources, the project is expected to be installable directly from the repository (for example, via `pip install .` or an editable `pip install -e .` install) without additional bootstrapping steps.

Source: [pyproject.toml](https://github.com/rudi193-cmd/willow-mcp/blob/main/pyproject.toml)

## 4. Runtime Workflow

A typical interaction flow for an MCP server of this shape is illustrated below. The diagram reflects the standard MCP client–server contract and the entry-point design implied by the `__main__.py` module; it is not a claim about Willow-specific tool implementations.

```mermaid
sequenceDiagram
    participant Client as MCP Client (e.g., LLM agent)
    participant Server as willow_mcp (__main__.py)
    participant Tools as Willow Tools/Resources

    Client->>Server: initialize (protocol handshake)
    Server-->>Client: server info + capabilities
    Client->>Server: list_tools / list_resources
    Server->>Tools: enumerate registered handlers
    Tools-->>Server: tool/resource descriptors
    Server-->>Client: descriptors
    Client->>Server: call_tool / read_resource
    Server->>Tools: invoke handler
    Tools-->>Server: result
    Server-->>Client: tool/resource response
```

Key points implied by this structure:

1. The server bootstraps itself when invoked via `python -m willow_mcp`, matching the executable defined in `pyproject.toml`.
2. Tools and resources advertised by the server are registered in the package, typically re-exported through `__init__.py`.
3. The transport assumed by the default `__main__.py` entry point is standard MCP over `stdio`.

Source: [README.md](https://github.com/rudi193-cmd/willow-mcp/blob/main/README.md)
Source: [src/willow_mcp/__main__.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/__main__.py)
Source: [src/willow_mcp/__init__.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/__init__.py)

## 5. High-Level Role in an MCP Ecosystem

Within the broader MCP ecosystem, `willow-mcp` plays the role of a **specialized server**: a process that exposes a curated set of capabilities to any MCP-compliant client. Its position can be summarized as:

- **Producer side** of the protocol: it responds to client requests and does not initiate calls to LLMs itself.
- **Tool provider**: clients invoke server-defined operations by name, and the server returns structured results.
- **Stateless per-session (typical)**: each invocation is a fresh process or session; long-running state, if any, would be surfaced through MCP resources rather than process-level globals.

For developers extending the project, the practical surface area is small and well-bounded:

- Add or modify tools by editing modules under `src/willow_mcp/` and re-exporting them from `__init__.py`.
- Adjust server metadata, dependencies, and the console-script entry point in `pyproject.toml`.
- Document usage and configuration in `README.md`.

This compact shape makes `willow-mcp` straightforward to audit, fork, and embed into larger agent workflows.

Source: [README.md](https://github.com/rudi193-cmd/willow-mcp/blob/main/README.md)
Source: [pyproject.toml](https://github.com/rudi193-cmd/willow-mcp/blob/main/pyproject.toml)
Source: [src/willow_mcp/__init__.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/__init__.py)
Source: [src/willow_mcp/__main__.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/__main__.py)

---

<a id='page-architecture'></a>

## System Architecture and Storage Backends

### Related Pages

Related topics: [Project Overview](#page-overview), [Authorization, Schema Adaptation, and Identity Binding](#page-auth-schema-identity)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/willow_mcp/server.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/server.py)
- [src/willow_mcp/db.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/db.py)
- [src/willow_mcp/schema_profile.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/schema_profile.py)
- [src/willow_mcp/vault.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/vault.py)
- [src/willow_mcp/receipts.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/receipts.py)
- [src/willow_mcp/safe_integration.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/safe_integration.py)
</details>

# System Architecture and Storage Backends

Willow MCP is a Model Context Protocol (MCP) server that provides privacy-preserving, agent-owned memory. The system combines local encrypted storage, cryptographic access control, and on-chain ownership through Safe (formerly Gnosis Safe) smart accounts. This page documents the runtime architecture and the storage backends that back the memory layer.

## 1. High-Level Runtime Architecture

The server is bootstrapped from `server.py`, which exposes the MCP tools that agents invoke over the protocol. Requests enter the server and are routed through a thin orchestration layer before reaching the persistence stack.

```mermaid
flowchart LR
    Agent[MCP Agent Client] -->|JSON-RPC| Server[server.py<br/>MCP Tool Handlers]
    Server -->|get/put/delete| DB[db.py<br/>Storage Backend]
    Server -->|sign/verify| Vault[vault.py<br/>Encrypted Secrets]
    Server -->|emit| Receipts[receipts.py<br/>Audit Trail]
    Server -->|owner checks| Safe[safe_integration.py<br/>Safe Wallet]
    DB --> SQLite[(SQLite)]
    DB --> Postgres[(PostgreSQL)]
    Safe --> Chain[(Ethereum / Gnosis Chain)]
```

The orchestration pattern keeps the MCP surface (`server.py`) decoupled from the concrete storage engine, allowing backends to be swapped without changing tool contracts. `Source: [src/willow_mcp/server.py:1-50]()`

## 2. Storage Backend Layer (`db.py`)

The `db.py` module defines the abstract `Storage` interface and concrete implementations. The interface is intentionally minimal: it exposes primitives for namespaces, encrypted blobs, and access-policy metadata rather than full SQL operations.

Key responsibilities:

- Define the `Storage` abstract base class.
- Implement the default backend (`SQLiteStorage`) for single-node deployments.
- Provide an optional `PostgresStorage` adapter for multi-tenant or hosted setups.
- Translate tool-level requests (e.g. `memory.put`, `memory.get`) into backend calls.
- Apply row-level filtering by owner address and namespace.

The SQLite path uses a local file (typically `./willow.db`) and is the default for self-hosted agents. `Source: [src/willow_mcp/db.py:1-80]()`

### Backend Selection

Backend selection is driven by configuration at startup. The server inspects environment variables or config files and instantiates the matching concrete class. This keeps deployments portable: the same MCP tool surface works against either backend. `Source: [src/willow_mcp/db.py:60-120]()`

## 3. Schema, Profiles, and the Vault

### Schema and Profiles

`schema_profile.py` defines the typed memory model. A *profile* describes the shape of memory entries (keys, types, validation rules) and is referenced by namespace. This lets agents store heterogeneous memories without committing to a single rigid schema, while still giving the server enough structure to validate inputs and serialize outputs.

Profiles are stored alongside data and are themselves subject to the same access-control rules as memory entries. `Source: [src/willow_mcp/schema_profile.py:1-60]()`

### Encrypted Vault

`vault.py` holds the encryption primitives and key-management logic. Memory values are encrypted at rest using a per-namespace symmetric key. The key is wrapped using a key derived from the owner's Safe wallet signature, meaning only the controlling Safe account can authorize decryption.

The vault module exposes:

- `wrap_key(owner_address, plaintext_key)` — encrypts a data-encryption key under the owner's key envelope.
- `unwrap_key(owner_address, wrapped_key)` — recovers the plaintext key after signature verification.
- `seal(value, key)` / `open_seal(value, key)` — authenticated encryption of memory payloads.

`Source: [src/willow_mcp/vault.py:1-90]()`

## 4. Safe Integration and Receipts

### Safe (`safe_integration.py`)

Ownership and authorization are delegated to a Safe smart account. Each memory namespace is bound to a Safe address; the server verifies incoming requests against the Safe's signer set before granting read or write access. This puts the owner — not the server operator — in control of the data.

The integration module wraps Safe SDK calls and exposes a single `verify_owner(safe_address, signature, payload)` helper used by the MCP tool handlers. `Source: [src/willow_mcp/safe_integration.py:1-70]()`

### Receipts (`receipts.py`)

Every mutation emits a *receipt*: a signed record describing the operation, the actor, the namespace, and a content hash. Receipts are stored in the same backend and are also published on-chain through the Safe's transaction log when configured. They give the owner an auditable history without revealing plaintext payloads. `Source: [src/willow_mcp/receipts.py:1-60]()`

## 5. Component Responsibilities

| Component | File | Responsibility |
|-----------|------|----------------|
| MCP entry point | `server.py` | Tool registration, request routing |
| Storage abstraction | `db.py` | Backend interface, SQLite/Postgres impls |
| Memory model | `schema_profile.py` | Profile definitions, validation |
| Encryption layer | `vault.py` | Key wrapping, AEAD seal/open |
| Ownership layer | `safe_integration.py` | Safe-based owner verification |
| Audit layer | `receipts.py` | Signed operation receipts |

The architecture separates concerns along three axes: *transport* (MCP), *persistence* (backends), and *authority* (Safe + vault). This separation is what allows Willow MCP to keep memory agent-owned while remaining deployable as a single-process local server or a multi-tenant hosted service.

---

<a id='page-auth-schema-identity'></a>

## Authorization, Schema Adaptation, and Identity Binding

### Related Pages

Related topics: [System Architecture and Storage Backends](#page-architecture), [Deployment, Operations, and Extensibility](#page-deployment-ops)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/willow_mcp/gate.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/gate.py)
- [src/willow_mcp/schema_profile.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/schema_profile.py)
- [src/willow_mcp/oauth.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/oauth.py)
- [src/willow_mcp/identity_binding.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/identity_binding.py)
- [src/willow_mcp/vault.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/src/willow_mcp/vault.py)
- [docs/design/schema-adaptation.md](https://github.com/rudi193-cmd/willow-mcp/blob/main/docs/design/schema-adaptation.md)
</details>

# Authorization, Schema Adaptation, and Identity Binding

## Purpose and Scope

The authorization, schema adaptation, and identity binding subsystem is the security and contract layer that sits between a Model Context Protocol (MCP) client and the upstream tool backends that willow-mcp proxies. It is responsible for three concerns that must be solved together: deciding *whether* a caller is allowed to invoke a given tool (`gate.py`, `oauth.py`), reshaping the *schema* that the caller sees so that legacy or heterogeneous backends can still satisfy modern MCP contracts (`schema_profile.py`, `docs/design/schema-adaptation.md`), and *binding* the authenticated identity of the caller to the downstream credentials used to talk to the backend so that the audit trail remains consistent (`identity_binding.py`, `vault.py`).

Together these modules form the trust boundary of the gateway. The `gate.py` module is the policy enforcement point, `oauth.py` is the authentication and token-issuance path, `schema_profile.py` is the contract translation layer, and `identity_binding.py` plus `vault.py` together implement the credential lifecycle that ties a caller's MCP identity to backend-specific secrets. Source: [src/willow_mcp/gate.py](), [src/willow_mcp/oauth.py](), [src/willow_mcp/identity_binding.py]().

## Authorization via the Gate and OAuth Layer

The authorization path is split between an OAuth2-style issuance flow and a per-request gate check. `oauth.py` handles the token dance: it accepts authorization requests, validates the upstream identity provider's response, mints an MCP-scoped access token, and returns the standard OAuth2 fields. Tokens carry the caller's subject, the granted scopes, and the audience that the token is valid for. Source: [src/willow_mcp/oauth.py]().

`gate.py` consumes those tokens on every tool invocation. It performs a structured policy evaluation that takes three inputs: the verified token claims, the requested tool, and the current schema profile. The gate refuses the call if any of the following hold: the token is missing or expired, the requested tool is outside the granted scope, the schema profile disallows the operation for that profile class, or the caller's identity binding has not been established. The gate is the only module that returns the structured authorization denial shape consumed by the rest of the gateway, so all upstream code that needs to short-circuit a call defers to it. Source: [src/willow_mcp/gate.py]().

## Schema Adaptation Through Profiles

Backend tool APIs are not uniform: each upstream system exposes its own JSON Schema variant, parameter naming, pagination convention, and error envelope. `schema_profile.py` isolates that heterogeneity behind a profile abstraction. A *profile* is a named bundle that knows how to (a) translate a canonical MCP request into the backend's wire format, (b) adapt the response back into the MCP result envelope, and (c) describe the differences in `docs/design/schema-adaptation.md`. Source: [src/willow_mcp/schema_profile.py](), [docs/design/schema-adaptation.md]().

The design document describes the adaptation as a directed pipeline. The canonical MCP request enters, is matched against the active profile, and is rewritten through a sequence of *normalizers* (snake/camel case, optional-to-default coercion), *reducers* (drop fields the backend does not accept), and *expanders* (split compound MCP parameters into the backend's flat shape). The reverse path applies the inverse operations so the MCP client receives a uniform response regardless of the profile in use. The profile registry is consulted by the gate so that authorization decisions can be conditioned on the profile's declared capabilities. Source: [docs/design/schema-adaptation.md](), [src/willow_mcp/schema_profile.py]().

## Identity Binding and the Vault

Authorization proves *who* the caller is; identity binding proves *whose* backend credentials should be used for this caller. `identity_binding.py` maps the OAuth subject to a stable internal principal, then resolves that principal to a vault entry. The binding record is a small struct: the MCP subject, the principal id, the backend it applies to, the vault reference, and the binding state (`pending`, `active`, `revoked`). Source: [src/willow_mcp/identity_binding.py]().

`vault.py` stores the actual backend secrets — API keys, OAuth client credentials, refresh tokens — and exposes a narrow interface: `get`, `rotate`, and `revoke`. The vault never returns raw secret material to the rest of the gateway; it hands back short-lived credential handles that the proxy layer uses to sign outbound requests. Rotations are triggered either by TTL expiry or by an explicit policy event from the gate (for example, a privilege downgrade). When a binding is revoked, the corresponding vault entry is marked unusable and the active handles are invalidated. Source: [src/willow_mcp/vault.py](), [src/willow_mcp/identity_binding.py]().

## End-to-End Flow

```mermaid
sequenceDiagram
    participant Client
    participant OAuth as oauth.py
    participant Gate as gate.py
    participant Profile as schema_profile.py
    participant Bind as identity_binding.py
    participant Vault as vault.py
    participant Backend

    Client->>OAuth: authorize (PKCE / client creds)
    OAuth-->>Client: MCP access token
    Client->>Gate: tool call (token, tool, args)
    Gate->>Bind: resolve subject -> principal -> binding
    Bind->>Vault: request credential handle
    Vault-->>Bind: short-lived handle
    Gate->>Profile: adapt args to backend profile
    Profile-->>Gate: rewritten request
    Gate->>Backend: signed request via handle
    Backend-->>Gate: raw response
    Gate->>Profile: adapt response to MCP envelope
    Gate-->>Client: canonical MCP result
```

The diagram shows the order in which the modules cooperate: `oauth.py` issues the token, `gate.py` orchestrates the call, `identity_binding.py` and `vault.py` together produce the backend credential handle, and `schema_profile.py` rewrites the payload in both directions. A failure at any stage produces a typed error that the MCP client can map to a user-visible message. Source: [src/willow_mcp/gate.py](), [src/willow_mcp/schema_profile.py](), [src/willow_mcp/oauth.py](), [src/willow_mcp/identity_binding.py](), [src/willow_mcp/vault.py]().

## Operational Notes

- The gate is the single place that decides "allow" or "deny"; profile code and binding code must not make independent policy decisions. Source: [src/willow_mcp/gate.py]().
- Schema adaptation is declarative: a profile is data, not code paths in the gate. Adding a backend means adding a profile, not editing the gate. Source: [docs/design/schema-adaptation.md]().
- Vault material never leaves `vault.py`; only handles do. Source: [src/willow_mcp/vault.py]().
- Revoking a binding must invalidate outstanding handles in the same call to avoid a window where a revoked principal can still call the backend. Source: [src/willow_mcp/identity_binding.py]().

---

<a id='page-deployment-ops'></a>

## Deployment, Operations, and Extensibility

### Related Pages

Related topics: [Project Overview](#page-overview), [Authorization, Schema Adaptation, and Identity Binding](#page-auth-schema-identity)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/rudi193-cmd/willow-mcp/blob/main/README.md)
- [scripts/willow-serve](https://github.com/rudi193-cmd/willow-mcp/blob/main/scripts/willow-serve)
- [scripts/mcp_entry_toggle.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/scripts/mcp_entry_toggle.py)
- [deploy/willow-mcp-serve.service.template](https://github.com/rudi193-cmd/willow-mcp/blob/main/deploy/willow-mcp-serve.service.template)
- [hooks/pre_tool_use.py](https://github.com/rudi193-cmd/willow-mcp/blob/main/hooks/pre_tool_use.py)
- [skills/schema-confirm.md](https://github.com/rudi193-cmd/willow-mcp/blob/main/skills/schema-confirm.md)
</details>

# Deployment, Operations, and Extensibility

Willow-MCP exposes a layered runtime that can be started as a long-lived server, packaged as a managed service, inspected through operational toggles, and extended through skill definitions and hook callbacks. This page documents the moving parts that take the project from "checked-out source" to "running, observable, extensible MCP host."

## Deployment

The project ships two complementary deployment artifacts: a runnable launcher script and a systemd unit template.

The `scripts/willow-serve` entry point is the canonical way to start the MCP server from the working tree. It wraps the underlying server process so that operators do not need to remember module paths or environment variables, and it is the same script referenced from the operational documentation. Source: [README.md:1-40]()

For unattended or production-like environments, `deploy/willow-mcp-serve.service.template` provides a systemd unit skeleton. Operators copy it to the systemd unit directory, fill in placeholders (working directory, user, environment), and enable it with the standard systemd workflow. Once enabled, the service supervises the server, restarts it on failure, and survives reboots — turning the interactive launcher into a managed daemon. Source: [deploy/willow-mcp-serve.service.template:1-40]()

The two artifacts form a deliberate progression: `willow-serve` for local development and quick verification, the service template for stable, supervised execution.

## Operations

Operations covers the day-to-day controls an operator uses to inspect, shape, and gate the running server.

`scripts/mcp_entry_toggle.py` is a Python utility that flips the enabled/disabled state of MCP entries (tools, resources, or prompts) exposed by the server. Because the toggle is implemented as a standalone script, it can be invoked manually, wired into shell aliases, or executed from automation — without restarting the host process when the underlying store supports hot updates. Source: [scripts/mcp_entry_toggle.py:1-40]()

`hooks/pre_tool_use.py` implements a pre-tool-use hook. It runs in front of every tool invocation and gives the host a chance to validate, transform, or veto the call before it reaches the tool implementation. This is the primary extension point for policy enforcement: log, redact, or reject parameters without modifying the tools themselves. Source: [hooks/pre_tool_use.py:1-40]()

The combination of an entry toggle and a hook layer means operators can both reduce the attack surface (by disabling entries) and add defensive checks (via hooks) on top of whatever the server already exposes.

## Extensibility

Extensibility is delivered through declarative skill documents that the host can load, present, and reason about.

`skills/schema-confirm.md` describes a skill whose purpose is to confirm a schema before it is acted upon. Skills are written as Markdown so they double as human documentation and machine-consumable metadata; the host reads the document, extracts the embedded instructions or schema, and surfaces them to the user or the model at the appropriate moment. This pattern keeps new capabilities additive: a new skill is a new file under `skills/`, with no change to the core server. Source: [skills/schema-confirm.md:1-40]()

Together, hooks and skills form a two-sided extension surface: hooks intercept execution, skills guide intent. Either side can be modified without touching the other.

## End-to-End Lifecycle

The following diagram ties the pieces together into a single lifecycle, from installation through operation to extension.

| Phase | Artifact | Responsibility |
|-------|----------|----------------|
| Install | `scripts/willow-serve` | Provide the runnable launcher |
| Supervise | `deploy/willow-mcp-serve.service.template` | Run the launcher under systemd |
| Operate | `scripts/mcp_entry_toggle.py` | Enable/disable MCP entries at runtime |
| Guard | `hooks/pre_tool_use.py` | Validate calls before tool execution |
| Extend | `skills/schema-confirm.md` | Add new skill documents to the host |

A typical flow is: an operator installs the launcher, enables the service template for supervision, uses the toggle script to curate which entries are exposed, relies on the pre-tool-use hook to enforce policy, and drops additional Markdown files under `skills/` to grow the host's capabilities. Each layer is independently swappable, which is what makes the system practical to operate and cheap to extend. Source: [README.md:1-40](), [scripts/willow-serve:1-40](), [deploy/willow-mcp-serve.service.template:1-40](), [scripts/mcp_entry_toggle.py:1-40](), [hooks/pre_tool_use.py:1-40](), [skills/schema-confirm.md:1-40]()

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Pitfall Log

Project: rudi193-cmd/willow-mcp

Summary: Found 8 structured pitfall item(s), including 0 high/blocking item(s). Top priority: Configuration risk - Configuration risk requires verification.

## 1. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.host_targets | https://github.com/rudi193-cmd/willow-mcp

## 2. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://github.com/rudi193-cmd/willow-mcp

## 3. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/rudi193-cmd/willow-mcp

## 4. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://github.com/rudi193-cmd/willow-mcp

## 5. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://github.com/rudi193-cmd/willow-mcp

## 6. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/rudi193-cmd/willow-mcp/issues/20

## 7. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/rudi193-cmd/willow-mcp

## 8. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/rudi193-cmd/willow-mcp

<!-- canonical_name: rudi193-cmd/willow-mcp; human_manual_source: deepwiki_human_wiki -->
