{
  "markdown": "# Peil MCP server\n\n<!-- Ownership proof for the official MCP registry: it fetches\n     https://pypi.org/pypi/peil-mcp/json and requires this exact line in the\n     README (which PyPI serves as the package description) to match the `name`\n     in server.json. Do not remove or reword it. -->\n\nmcp-name: app.peil/peil-mcp\n\nConnect [Peil](https://peil.app) to Claude (or any MCP client): log hours,\ndraft invoices from unbilled hours, and check where you stand — from a prompt.\n\n- **Website:** https://peil.app\n- **Docs:** https://peil.app/en/docs/mcp\n- **Source:** https://github.com/Luminc/peil-mcp\n\nThe server is a pure client of Peil's public API. It authenticates with a\n**scoped API key** you create in Peil under **Settings → Developer** (Pro).\n\n## Draft-by-default\n\n`draft_invoice` only ever creates a **draft** — nothing is sent to your\nclients. Sending is a separate tool (`send_invoice`) that also requires the\nseparate **invoices:send** permission on your key. A key without that\npermission can never email anything on your behalf.\n\n## Tools\n\n**Reads** (`read`)\n\n| Tool | What it does |\n|---|---|\n| `list_clients` | List your clients |\n| `get_client_details` | One client's details, incl. whether a default rate is set |\n| `list_unbilled` | Unbilled hours per client for a period |\n| `list_invoices` | List invoices, filterable by status / client |\n| `orientation_snapshot` | Outstanding / overdue / drafts / YTD position |\n| `get_reminder_copy` | Your custom reminder email copy + schedule |\n\n**Hours** (`timesheet:write`)\n\n| Tool | What it does |\n|---|---|\n| `log_hours` | Add a timesheet entry (client default rate unless given) |\n| `edit_hours` | Edit an entry (only the fields you pass change) |\n| `delete_hours` | Delete an entry (blocked if on a sent/paid invoice) |\n\n**Clients** (`clients:write`)\n\n| Tool | What it does |\n|---|---|\n| `create_client` / `update_client` / `delete_client` | Client CRUD (delete blocked if it has projects/sent invoices) |\n\n**Invoices** (`invoices:write`)\n\n| Tool | What it does |\n|---|---|\n| `draft_invoice` | Draft an invoice from unbilled hours (summary / by_project / per_day) |\n| `set_invoice_status` | Change status (e.g. mark paid) — does **not** email anyone |\n| `update_invoice` | Edit safe fields (due date, payment date, notes) |\n| `delete_invoice` / `archive_invoice` | Delete (paid ones blocked) / archive |\n| `set_reminder_copy` | Write custom reminder email copy for one tone/language |\n\n**Client-facing email** (`invoices:send` — irreversible, always confirm first)\n\n| Tool | What it does |\n|---|---|\n| `send_invoice` | Email an invoice to the client now |\n| `schedule_send` | Schedule a draft to be emailed at a future time |\n| `cancel_scheduled_send` | Cancel a scheduled send |\n| `send_reminder` | Email a payment reminder for a sent/overdue invoice |\n\n---\n\n## 1. Create your key\n\nIn Peil: **Settings → Developer** → create a key with the permissions you want.\nStart with **read + Log hours + Draft invoices**; leave **Send invoices** off\nunless you truly want an assistant emailing clients. You'll paste this key into\nyour assistant's config as `PEIL_API_KEY` below.\n\n## 2. Install the server\n\n**The easy way — no clone, no install** (once `peil-mcp` is published to PyPI):\n\n```sh\nuvx peil-mcp          # runs the latest release on demand\n# or, with pipx:\npipx run peil-mcp\n```\n\n→ Your launch command is `uvx peil-mcp` (or `pipx run peil-mcp`). Skip to\n[step 3](#3-connect-your-assistant). Everything below is only needed if you're\nrunning **from source** (e.g. before the first release, or to hack on it).\n\n### From source\n\nYou need **Python 3.11 or newer** and a local copy of this `mcp-server/` folder.\nCheck your Python with `python3 --version`.\n\n> **Which method?** Run `which uv pipx` first. If you already have `uv`, use A —\n> it's the least work. If not, `pipx` (B) gives you a clean global command. If\n> you have neither and don't want to install tooling, the plain-`venv` path (C)\n> works with nothing but the Python that's already on your machine.\n\nEverywhere below, replace `/ABS/PATH/TO/mcp-server` with the real absolute path\nto this folder (run `pwd` inside it to get it).\n\n### A. With `uv` (no install step)\n\n`uv` builds and runs on demand — nothing to install first:\n\n```sh\nuv run --directory /ABS/PATH/TO/mcp-server peil-mcp\n```\n\n→ Your launch command is: `uv run --directory /ABS/PATH/TO/mcp-server peil-mcp`\n\nDon't have `uv`? `curl -LsSf https://astral.sh/uv/install.sh | sh` (macOS/Linux)\nor `pip install uv`.\n\n### B. With `pipx` (isolated global command)\n\n`pipx` installs the server into its own isolated environment and puts a\n`peil-mcp` command on your PATH:\n\n```sh\npipx install /ABS/PATH/TO/mcp-server\n```\n\n→ Your launch command is simply: `peil-mcp`\n\nDon't have `pipx`? `python3 -m pip install --user pipx && python3 -m pipx ensurepath`.\n\n### C. Plain `venv` + `pip` (works with only stock Python)\n\nNo extra tooling — just the `python3` you already have:\n\n```sh\ncd /ABS/PATH/TO/mcp-server\npython3 -m venv .venv\n.venv/bin/pip install .\n```\n\n→ Your launch command is: `/ABS/PATH/TO/mcp-server/.venv/bin/peil-mcp`\n(equivalently `/ABS/PATH/TO/mcp-server/.venv/bin/python -m peil_mcp`).\n\n> Use a **plain** `pip install .` (not `-e`/editable) for running. An editable\n> install relies on a `.pth` path hook that can silently fail to load on some\n> setups, giving `ModuleNotFoundError: No module named 'peil_mcp'`. Editable is\n> only needed if you're modifying the server itself — see\n> [Local development](#local-development).\n\n## 3. Connect your assistant\n\n**The only thing that changes between assistants is where the config lives.**\nEvery MCP client needs the same three things:\n\n- **command** — your launch command from step 2\n- **env** — `PEIL_API_KEY` set to the key from step 1\n- (optional) **`PEIL_API_URL`** — only if you're pointing at a non-production\n  Peil (see [Local development](#local-development)); defaults to\n  `https://api.peil.app/api/v1`.\n\nThe canonical config block (used by Claude Desktop, Cursor, Windsurf, Cline, and\nmost others) looks like this — `command` + `args` are just your launch command\nsplit on spaces:\n\n```jsonc\n{\n  \"mcpServers\": {\n    \"peil\": {\n      \"command\": \"peil-mcp\",          // or \"uv\", or the venv's python path\n      \"args\": [],                     // e.g. [\"run\",\"--directory\",\"/ABS/PATH/TO/mcp-server\",\"peil-mcp\"] for uv\n      \"env\": { \"PEIL_API_KEY\": \"your-key\" }\n    }\n  }\n}\n```\n\n### Claude Desktop\n\nEdit `claude_desktop_config.json`\n(macOS: `~/Library/Application Support/Claude/`,\nWindows: `%APPDATA%\\Claude\\`), add the block above, and restart Claude Desktop.\n\n### Claude Code (CLI)\n\n```sh\n# pipx / venv (single-command launcher):\nclaude mcp add peil -e PEIL_API_KEY=your-key -- peil-mcp\n\n# uv:\nclaude mcp add peil -e PEIL_API_KEY=your-key -- uv run --directory /ABS/PATH/TO/mcp-server peil-mcp\n```\n\nAnything after `--` is the launch command. Verify with `claude mcp get peil`\n(look for `Status: ✔ Connected`) and use `/mcp` in a session to reconnect.\n\n### Cursor\n\nAdd the canonical block to `.cursor/mcp.json` (this project) or\n`~/.cursor/mcp.json` (all projects), then enable **peil** in\n**Settings → MCP**.\n\n### Windsurf\n\nAdd the canonical block to `~/.codeium/windsurf/mcp_config.json`, then hit\n**Refresh** in the Cascade MCP panel.\n\n### Cline / Roo (VS Code)\n\nOpen the extension's **MCP Servers → Configure** panel and add the canonical\nblock to `cline_mcp_settings.json`.\n\n### VS Code (native Copilot agent mode)\n\nVS Code uses a slightly different shape — `servers` (not `mcpServers`) and an\nexplicit `type` — in `.vscode/mcp.json`:\n\n```jsonc\n{\n  \"servers\": {\n    \"peil\": {\n      \"type\": \"stdio\",\n      \"command\": \"peil-mcp\",\n      \"args\": [],\n      \"env\": { \"PEIL_API_KEY\": \"your-key\" }\n    }\n  }\n}\n```\n\n### Any other MCP client\n\nGive it the same **command + args + `PEIL_API_KEY` env**. The server speaks MCP\nover stdio; if a client can launch a stdio command, it can run Peil.\n\n## First prompts\n\nOnce connected, try:\n\n- *\"Where do I stand?\"* → `orientation_snapshot`\n- *\"Log 6 hours to De Correspondent today for editing work.\"* → `log_hours`\n- *\"Draft an invoice from my unbilled hours for De Correspondent.\"* → `draft_invoice`\n\nWith **Send invoices** left off your key, an assistant can prepare everything\nbut physically cannot email a client — you send from Peil yourself.\n\n---\n\n## Local development\n\nPoint the server at a local backend with `PEIL_API_URL`:\n\n```sh\nPEIL_API_URL=http://localhost:8000/api/v1 PEIL_API_KEY=your-local-key peil-mcp\n```\n\nIf you're modifying the server, an editable install picks up your changes\nwithout reinstalling:\n\n```sh\n.venv/bin/pip install -e \".[dev]\"\n```\n\nTests (mocked HTTP, no backend needed — `pythonpath = [\"src\"]` in\n`pyproject.toml` makes them independent of the install mechanism):\n\n```sh\n.venv/bin/pytest\n```\n",
  "bytes": 8807,
  "sha": "4dfc098526056fb9d35b6c929c47ea320ef087c797d92064e6cbb97d30bb7b09",
  "repo_slug": "luminc/peil-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_app_peil_peil_mcp_7433c3e4/readme"
}