project-context-engine
An OpenClaw plugin that dynamically injects relevant PROJECT.md context into the system prompt whenever the user mentions a project by name.
Problem
When an AI assistant starts a conversation it has no knowledge of your internal projects unless that context is explicitly provided. Loading every project file upfront wastes tokens; loading none leaves the model guessing.
Solution
This plugin reads a lightweight project registry from MEMORY.md, watches for project-name mentions in each message, and injects only the matching PROJECT.md files — nothing more.
How it works
User message arrives
│
▼
[hook: message:preprocessed]
┌──────────────────────────────────────────────────────────┐
│ 1. Parse MEMORY.md → project registry (TTL-cached 5 min)│
│ 2. Scan message for project-name mentions (case-insens.) │
│ 3. Write matched names to ctx.meta["pce:matched"] │
└──────────────────────────────────────────────────────────┘
│
▼
[assemble phase: context-engine "project-context"]
┌──────────────────────────────────────────────────────────┐
│ 4. Read ctx.meta["pce:matched"] (empty → return null) │
│ 5. Load PROJECT.md for each match (TTL-cached 5 min) │
│ 6. Return formatted markdown → systemPromptAddition │
└──────────────────────────────────────────────────────────┘
│
▼
Model sees project context only for mentioned projects
Installation
# In your OpenClaw workspace directory
openclaw plugin install project-context-engine
Or manually:
npm install project-context-engine
Then add the plugin to your OpenClaw workspace config (.openclaw/config.json or openclaw.config.json at the workspace root):
{
"plugins": ["project-context-engine"]
}
Setup
1. Add a project table to MEMORY.md
Create or edit MEMORY.md at your workspace root and add a markdown table with Project and File columns anywhere in the file:
| Project | File |
|---------------|------------------------------------|
| my-app | projects/my-app/PROJECT.md |
| infra | projects/infra/PROJECT.md |
| data-pipeline | docs/data-pipeline/PROJECT.md |
Note: All paths are relative to the workspace root. Absolute paths are rejected for security reasons. "Progetto" is accepted as a legacy alias for "Project".
2. Create each PROJECT.md
Use the included _TEMPLATE.md as a starting point:
cp node_modules/project-context-engine/_TEMPLATE.md projects/my-app/PROJECT.md
# Edit to fill in your project details
3. Use it
Just mention a project name in your message:
"Can you help me debug the my-app authentication flow?"
The plugin will automatically inject projects/my-app/PROJECT.md into the system prompt for that turn.
Token efficiency
| Scenario | Tokens added |
|---|---|
| No project mentioned | 0 |
| 1 project mentioned | That PROJECT.md only |
| N projects mentioned | Sum of those N files |
| Same project mentioned again (< 5 min) | 0 (served from cache) |
Error handling and graceful degradation
| Condition | Behavior |
|---|---|
MEMORY.md missing | Silent no-op — 0 tokens added |
MEMORY.md has no project table | Silent no-op — 0 tokens added |
PROJECT.md listed but missing from disk | That project is skipped silently |
Absolute path in File column | Rejected silently (security) |
Path traversal attempt (e.g. ../../etc/...) | Rejected silently (security) |
| Any internal error | Swallowed — pipeline never blocked |
Cache behavior
Both the registry (from MEMORY.md) and individual PROJECT.md files are cached in-memory with a 5-minute TTL.
- Changes to
MEMORY.mdtake effect within 5 minutes (or on next OpenClaw process start). - Changes to a
PROJECT.mdfile take effect within 5 minutes. - To pick up changes immediately, restart the OpenClaw process (e.g.
openclaw restart).
PROJECT.md format
See _TEMPLATE.md for the recommended structure. The engine imposes no format requirements — any markdown content is valid.
Contributing
- Fork the repo
npm installnpm run typecheck— must pass with zero errors- Submit a PR with a description of the change
License
MIT