get_instructions
Retrieve the project's mandatory AI instructions at session start to follow workflow rules and avoid repeating past mistakes.
Instructions
Read the project's mandatory AI instructions.
MANDATORY: call this at session start. The instructions describe the
workflow rules you MUST follow while working in this project — they
are not advisory.Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/projectmem/mcp_server.py:178-189 (handler)Tool handler function: reads AI_INSTRUCTIONS.md via ai_instructions_path() and returns its contents, or a fallback message if not found. Decorated with @mcp.tool() and @safe_tool.
@mcp.tool() @safe_tool def get_instructions() -> str: """Read the project's mandatory AI instructions. MANDATORY: call this at session start. The instructions describe the workflow rules you MUST follow while working in this project — they are not advisory.""" path = ai_instructions_path() if path.exists(): return path.read_text(encoding="utf-8") return "No instructions found. Run `pjm init` first." - src/projectmem/mcp_server.py:178-180 (registration)Registered as an MCP tool via the @mcp.tool() decorator on the FastMCP instance named 'mcp'.
@mcp.tool() @safe_tool def get_instructions() -> str: - src/projectmem/storage.py:72-73 (helper)Helper function ai_instructions_path() used by the handler to resolve the path to AI_INSTRUCTIONS.md.
def ai_instructions_path(root: Path | None = None) -> Path: return require_mem_dir(root) / AI_INSTRUCTIONS_FILE - src/projectmem/storage.py:149-315 (helper)Helper function ai_instructions() that generates the default AI instructions content written during pjm init.
def ai_instructions() -> str: return ( "# projectmem AI Instructions\n\n" "These instructions are MANDATORY for all AI coding agents working in this " "project. Failure to follow them means your work is incomplete and the audit " "trail is corrupted.\n\n" "This file is stable operating guidance. Do not rewrite it unless the user " "asks or projectmem itself changes.\n\n" "## Start of every session\n\n" "**Step 1 — Identify your mode by reading `.projectmem/summary.md` and " "`.projectmem/PROJECT_MAP.md`.**\n\n" "- **Setup Mode** — `summary.md` and/or `PROJECT_MAP.md` still contain the " "**placeholder text** from `pjm init`. Concrete signals you are in Setup Mode:\n" " - `summary.md` contains the phrase *\"Replace this placeholder with a " "concise description...\"*\n" " - Section bodies say *\"None logged yet.\"*\n" " - `PROJECT_MAP.md` contains *\"Status: not created yet\"* or *\"This file " "should be created by the first AI assistant...\"*\n\n" " → **You MUST populate both files with real project content before doing " "any other work for the user.** This is not optional and not deferred — your " "first response in a Setup Mode session is the memory-population pass. " "Procedure:\n\n" " 1. Read `README.md`, `package.json` / `pyproject.toml` / `Cargo.toml`, " "entry-point files (typically `src/main.*`, `index.html`, " "`app/__init__.py`, etc.), and any obvious architectural files.\n" " 2. For **each architectural choice** you identify (frameworks, language, " "build system, deployment target, data flow): call `add_decision` (MCP) or " "`pjm decision` (CLI) — one call per decision.\n" " 3. For **each gotcha / setup detail / library quirk**: call `add_note` " "(MCP) or `pjm note` (CLI) — one call per gotcha.\n" " 4. Each `add_decision` / `add_note` call appends to `events.jsonl` AND " "auto-regenerates `summary.md`. **NEVER edit `summary.md` directly** — it is " "derived; your edits will be overwritten on the next event.\n" " 5. **DO edit `PROJECT_MAP.md` directly** to replace its placeholder. " "`PROJECT_MAP.md` is structural and is NOT derived from events. Write the " "project's purpose, main folders, entry points, important files, " "relationships, and suggested first reads. Make sure PROJECT_MAP.md has a " "`## Project purpose` section with a real description — that section is " "auto-copied into `summary.md`'s Project purpose on the next regeneration " "(the only path by which summary.md's Project purpose gets populated; " "there is intentionally no MCP tool for it).\n" " 6. After step 5, summary.md and PROJECT_MAP.md both contain real content " "(summary.md picks up the Project purpose from PROJECT_MAP.md on the next " "`add_decision` / `add_note` call's auto-regen — or you can force it now " "with `pjm regenerate`). The project is in Maintenance Mode for every " "subsequent session.\n\n" "- **Maintenance Mode** — `summary.md` AND `PROJECT_MAP.md` contain **real " "project content, NOT the `pjm init` placeholder text**. Concrete signals " "you are in Maintenance Mode:\n" " - `summary.md` describes the actual project, lists real issues / " "decisions / notes by content.\n" " - `PROJECT_MAP.md` has real folder descriptions, entry points, and file " "relationships — not *\"Status: not created yet.\"*\n\n" " → **STOP analyzing the project structure.** The memory is already built. " "Use the existing summary + map. Focus exclusively on the user's actual task " "and on logging your own work via the trigger table.\n" " - Do NOT re-scan source files. Trust the memory.\n" " - Do NOT re-write `summary.md` or `PROJECT_MAP.md`. They are already " "correct; if you find an out-of-date detail, fix it through the trigger " "table (`add_note` / `add_decision` / `log_issue`) — never via direct file " "edit on summary.md.\n\n" "**Step 2 — Read these three files (or call the MCP equivalents):**\n\n" "| File | MCP tool | Purpose |\n" "| --- | --- | --- |\n" "| `.projectmem/AI_INSTRUCTIONS.md` | `get_instructions()` | Workflow rules (this file) |\n" "| `.projectmem/summary.md` | `get_summary()` | Distilled project memory |\n" "| `.projectmem/PROJECT_MAP.md` | `get_project_map()` | Structural layout |\n\n" "Prefer the MCP tools when available — they're cheaper (~500 tokens) than " "reading files individually and they auto-resolve the project root regardless " "of your working directory.\n\n" "**Step 3 — Check `.projectmem/issues/` only when a logged issue looks " "relevant to the current task** (use `get_issue(issue_id)` via MCP, or read " "the file). Don't read every issue on every session — that's wasteful.\n\n" "**Step 4 — Treat `.projectmem/events.jsonl` as the append-only raw log.** " "Do not edit it by hand unless repairing corruption. Use write tools.\n\n" "## MANDATORY Triggers — You MUST act on these automatically\n\n" "When a trigger fires, you MUST call the corresponding tool IMMEDIATELY, " "before continuing any other work. **Prefer MCP tools** (left column) when " "you're connected via an MCP-capable client; **fall back to CLI** (right " "column) otherwise.\n\n" "| Trigger | MCP tool | CLI command |\n" "| --- | --- | --- |\n" "| Bug, error, or unexpected behavior | `log_issue(summary, location)` | `pjm log \"<text>\" --at \"<file:line>\"` |\n" "| Fix attempt FAILED | `record_attempt(summary, outcome=\"failed\")` | `pjm attempt \"<text>\" --failed --at \"<file:line>\"` |\n" "| Fix attempt PARTIAL (helped but didn't fully fix) | `record_attempt(summary, outcome=\"partial\")` | `pjm attempt \"<text>\" --partial --at \"<file:line>\"` |\n" "| Fix attempt WORKED | `record_attempt(summary, outcome=\"worked\")` | `pjm attempt \"<text>\" --worked --at \"<file:line>\"` |\n" "| Fix confirmed — close the issue | `record_fix(summary)` | `pjm fix \"<text>\" --at \"<file:line>\"` |\n" "| Architectural / design decision | `add_decision(summary)` | `pjm decision \"<text>\" --at \"<file:line>\"` |\n" "| Gotcha / setup detail / constraint discovered | `add_note(summary)` | `pjm note \"<text>\" --at \"<file:line>\"` |\n" "| Before finishing the session | `get_summary()` | `pjm show` |\n\n" "All write tools auto-append to `events.jsonl` AND auto-regenerate " "`summary.md`. You do NOT need to call a separate \"save\" or \"regenerate\" " "command after each tool. The summary follows the events automatically.\n\n" "## Execution Rules\n\n" "1. **Log BEFORE you fix.** When you see a bug, call `log_issue` (or " "`pjm log`) BEFORE writing fix code. The issue survives interruptions and " "session boundaries; in-flight fix work does not.\n" "2. **Record IMMEDIATELY after each attempt.** Do not batch multiple attempts " "into one entry. Each distinct approach gets its own `record_attempt` call.\n" "3. **Close with `record_fix` only after evidence.** Test passes, error is " "gone, or the user confirms — anything less and the issue stays open.\n" "4. **Never skip logging because it feels minor.** A small fix today is a " "mystery regression tomorrow. Log it.\n" "5. **NEVER edit `.projectmem/summary.md` or `.projectmem/events.jsonl` " "directly via filesystem write.** Both are derived/append-only. Use the " "write tools. (You MAY edit `PROJECT_MAP.md` directly when restructuring it; " "it's not derived from events.)\n\n" "## What to track\n\n" "Use projectmem to preserve the development story that would otherwise be " "lost between chats, terminal sessions, and commits.\n\n" "Track:\n\n" "- new issues, bugs, regressions, unclear behavior, or investigation topics\n" "- hypotheses about causes\n" "- attempted fixes or experiments (each as its own `record_attempt`)\n" "- whether each attempt worked, failed, or partially helped\n" "- final fixes and the files involved\n" "- architectural, product, or implementation decisions and their reasons\n" "- gotchas, setup requirements, flaky tests, environment notes, " "important constraints\n" "- key files future contributors or AI agents should read first\n\n" "Do NOT track secrets, credentials, private customer data, access tokens, " "or large transcripts.\n\n" "## Auto-Capture (active)\n\n" "Git hooks installed by `pjm init` automatically capture:\n\n" "- Commits (post-commit hook)\n" "- Reverts (auto-classified as failed approaches)\n" "- Merges (auto-classified as milestones)\n" "- File churn (the `pjm watch` daemon flags rapid same-file edits)\n\n" "You do NOT need to manually log any of those. You SHOULD still manually log:\n\n" "- Decisions with rationale (`add_decision` / `pjm decision`)\n" "- Pre-attempt context for complex fixes (`record_attempt` / `pjm attempt`)\n" "- External factors and gotchas (`add_note` / `pjm note`)\n" "- Failure context that commit messages don't capture\n\n" "## Pre-commit safety net\n\n" "Every `git commit` automatically runs `pjm precheck` against the staged " "files. If you're about to commit a file with unresolved issues, recent " "failed attempts, or high churn, you'll see a warning block before the " "commit lands. Read it; it exists to stop you from repeating known " "failures. To bypass once: `git commit --no-verify`.\n\n" "## Rules summary\n\n" "- **MANDATORY: Log before you exit.** Work is not finished until project " "memory reflects what happened.\n" "- **MANDATORY: Record failed and partial attempts.** Negative and " "partial-credit knowledge is often the most valuable part of project memory.\n" "- Keep entries concise but specific enough that another person or AI can " "avoid repeating work. Include file paths, error names, test names.\n" "- Prefer several small accurate entries over one vague long entry.\n" "- Do not claim something is fixed until tests, reproduction, or user " "confirmation supports it.\n" "- Do not overwrite history. `events.jsonl` is append-only; `summary.md` " "is derived from it.\n" "- If MCP is unavailable, use the CLI (`pjm log`, `pjm attempt`, " "`pjm fix`, `pjm decision`, `pjm note`). If neither is available, clearly " "tell the user what should be recorded.\n" "- **`pjm` is the canonical CLI command** (since v0.0.4). The legacy " "`projectmem` alias still works if installed.\n\n" "## Minimal prompt for AI tools (Universal Mode)\n\n" "Read `.projectmem/AI_INSTRUCTIONS.md`, `.projectmem/summary.md`, and " "`.projectmem/PROJECT_MAP.md` before working. This project uses mandatory " "memory tracking with auto-capture enabled. If summary.md contains " "placeholder text, populate it via `pjm decision` and `pjm note` (or the " "`add_decision` / `add_note` MCP tools) — never edit summary.md directly. " "Git hooks log commits, reverts, and merges automatically. You MUST still " "run `pjm log` when you find a bug, `pjm attempt` for fix attempts, " "`pjm fix` when confirmed, and `pjm decision` for architectural choices. " "Skipping these steps means your work is incomplete.\n" ) - src/projectmem/mcp_server.py:127-138 (registration)The FastMCP server's instructions= system prompt references get_instructions() as the first call in the session-start trio.
mcp = FastMCP( "projectmem", instructions=( "You are connected to projectmem — a mandatory project memory + " "judgment layer. The tools below are FAR cheaper than re-deriving " "the same information from source: a get_summary call costs ~500 " "tokens; re-scanning the project to answer the same question " "costs ~5,000.\n" "\n" "SESSION START — call these three tools, in this order, BEFORE\n" "answering ANY question about this project:\n" " 1. get_instructions() — loads the project's mandatory workflow\n"