Skip to main content
Glama
README.md
# 🌲 Evergreen

**Documentation that writes and maintains itself.**

Evergreen is an AI knowledge layer on Cloudflare Workers. It drafts docs from your real sources β€” code, PRs, tickets, and Claude memory β€” you approve them in seconds, and it keeps them from rotting: when the source changes, the doc is flagged stale and a refresh is drafted for you. The same knowledge is readable and writable by AI agents over MCP.

> This repo is a **template**. Click **β€œUse this template”**, then follow *Quickstart* below. The entity dictionary and a few config values are placeholders β€” make them yours.
>
> πŸ“– **New here? Read [USAGE.md](./USAGE.md)** β€” full configuration checklist (exactly what to fill in), deploy steps, how to use every feature, and how to connect your Claude.

---

## The loop

```mermaid
flowchart LR
  subgraph SRC["Real sources"]
    direction TB
    C["Code / PRs"]
    T["Tickets"]
    M["Claude memory"]
  end
  SRC --> LLM["Claude<br/>(Bedrock)"]
  LLM --> DR["Drafts"]
  DR -->|"human approves<br/>in seconds"| KB[("Knowledge base<br/>D1: facts + entity graph")]
  KB --> UI["Web UI<br/>/evergreen"]
  KB --> MCP["MCP server<br/>agents read &amp; write"]
  KB -. "code &amp; facts change" .-> DFT["Drift +<br/>auto-maintain"]
  DFT -. "flag stale Β· draft refresh" .-> DR
```

Generate β†’ approve β†’ detect drift β†’ refresh β†’ repeat. The loop closes itself.

## What's inside

| Surface | What it does |
|---|---|
| **Generate** | Point at a GitHub repo, subtree, or PR β†’ Claude reads the source and drafts a doc. |
| **Coverage** | Find topics with lots of facts but no doc, and synthesize one from what's already known. |
| **Review** | Validate AI-distilled lessons harvested from your tracker in one click. |
| **Drift + Auto-maintain** | Docs refresh themselves as code & facts change β€” nightly and on demand. |
| **Ask** | Grounded Q&A over the knowledge base, every answer cited. |
| **Team memory** | Connect your Claude memory so teammates can pick up where you left off. |
| **Knowledge graph** | Entities (clients, systems, tickets…) auto-extracted and navigable. |
| **MCP** | An MCP server so AI agents read and extend the docs directly. |

## Architecture

- **Cloudflare Workers** + [Hono](https://hono.dev)
- **D1** (SQLite) with FTS5 full-text search β€” the knowledge base is a graph of facts ↔ entities
- **Amazon Bedrock** (Claude) for generation, synthesis, Q&A, and drift judgment
- **MCP** (streamable HTTP) for agent access
- Auth via **Cloudflare Access** (SSO) with a `WEB_PASSWORD` basic-auth fallback

The core knowledge base lives at `/`; the Evergreen doc surface is additive under `/evergreen/*`, in its own `hack_*` tables β€” generated docs only promote into the real knowledge base on human approval.

## Quickstart

```bash
bun install                                   # or npm install

# 1. Create the database + token store
wrangler d1 create evergreen                  # paste database_id into wrangler.jsonc
wrangler kv namespace create TOKENS           # paste id into wrangler.jsonc
bun run db:init:remote                         # apply migrations/

# 2. Secrets
wrangler secret put WEB_PASSWORD              # browser UI password
wrangler secret put MCP_SHARED_SECRET         # fallback MCP bearer
wrangler secret put BEDROCK_API_KEY           # Bedrock bearer token (for the LLM)
wrangler secret put LINEAR_API_KEY            # optional β€” ticket harvester
wrangler secret put GITHUB_TOKEN              # optional β€” private repos + higher rate limits

# 3. Set account_id / route / CF_ACCESS_TEAM_DOMAIN in wrangler.jsonc, then:
bun run deploy
```

### Local dev

```bash
cp .dev.vars.example .dev.vars                # set WEB_PASSWORD, BEDROCK_API_KEY, …
bun run db:init:local
bun run dev                                    # http://localhost:8787  (UI password from .dev.vars)
```

### Make it yours

- **`src/extraction.ts`** β€” replace the example entity dictionary (clients, products, people, systems) with your own vocabulary. This is how the graph auto-links.
- **`wrangler.jsonc`** β€” set `HARVEST_LINEAR_TEAM`, your custom domain, and `CF_ACCESS_TEAM_DOMAIN`.
- **`scripts/seed.ts`** β€” import your local Claude memory: `bun run scripts/seed.ts <memory-dir> --author "Your Name"` β†’ review the sensitive-content report β†’ `bun run db:seed:remote`.

## Connect a Claude (MCP)

Add to `~/.claude.json` (or a project `.mcp.json`):

```json
{
  "mcpServers": {
    "evergreen": {
      "type": "http",
      "url": "https://<your-worker>/evergreen/mcp",
      "headers": { "Authorization": "Bearer <token-or-MCP_SHARED_SECRET>" }
    }
  }
}
```

Per-person tokens (for authorship) go in the `TOKENS` KV:

```bash
wrangler kv key put --binding TOKENS <token> '{"name":"Alex"}'
```

MCP tools: `ask_docs` Β· `generate_doc` Β· `check_drift` Β· `coverage_gaps` Β· `entity_brief`.

## License

MIT β€” see [LICENSE](./LICENSE).