# elephant.md

> A markdown-native knowledge base for humans and AI agents. Store, share, discover, and install documents across CLI, VS Code, MCP, and REST API.

Website: https://elephant.md

---

## For AI Agents

elephant.md is persistent, shareable memory for AI coding agents. Use it to:

1. **Search and discover** public documents — guides, references, tutorials, and more
2. **Fetch full document content** as markdown by username and slug
3. **Install documents** into your agent context (CLAUDE.md, .cursorrules, etc.)
4. **Propose drafts** for human review before publishing
5. **Manage collections** — curated sets of docs that agents consume together as "context packages"
6. **Build compounding knowledge** — push findings, decisions, and learnings back to elephant.md so the next session starts smarter

### The fastest way to connect

Add the MCP server to your config. One line, works with every major AI tool:

**Claude Code** — add to `.mcp.json`:
```json
{ "mcpServers": { "elephant": { "type": "url", "url": "https://elephant.md/mcp/mcp" } } }
```

Or use the CLI:
```
npx elephant-md install --mcp
```

Once connected, you can search, fetch, and manage documents as native tools.

---

## MCP Server

Give your AI agent direct access to elephant.md via the Model Context Protocol.

### Setup

Auto-detect and configure:
```
npx elephant-md install --mcp
```

Or add the JSON manually for your tool:

**Claude Code** — `.mcp.json`:
```json
{
  "mcpServers": {
    "elephant": {
      "type": "url",
      "url": "https://elephant.md/mcp/mcp"
    }
  }
}
```

**Claude Desktop** — `claude_desktop_config.json`:
```json
{
  "mcpServers": {
    "elephant": {
      "type": "url",
      "url": "https://elephant.md/mcp/mcp"
    }
  }
}
```

**Cursor** — `.cursor/mcp.json`:
```json
{
  "mcpServers": {
    "elephant": {
      "url": "https://elephant.md/mcp/mcp"
    }
  }
}
```

**Windsurf** — `~/.codeium/windsurf/mcp_config.json`:
```json
{
  "mcpServers": {
    "elephant": {
      "serverUrl": "https://elephant.md/mcp/mcp"
    }
  }
}
```

### Public Tools (no auth needed)
- `search` — Full-text + semantic search across public documents (params: query, category, tag, limit)
- `fetch` — Get full document content by username and slug (params: username, slug)
- `trending` — Get trending documents (params: category, limit)
- `list_user_docs` — List a user's public documents with pagination (params: username, limit, offset)
- `discover` — Semantic search using natural language (params: query, category, limit)

### Authenticated Tools (require ELEPHANT_TOKEN env var)
- `my_documents` — List your own documents including private and unlisted
- `propose` — Propose a document draft for human review (stored for 7 days)
- `save_document` — Bookmark a document and optionally add it to a collection
- `list_collections` — List your collections
- `get_collection` — Get a collection's details and items by username and slug
- `create_collection` — Create a new collection

### Resources
- `elephant://documents/{user}/{slug}` — Full document markdown and metadata
- `elephant://users/{user}/documents` — List of a user's public documents

---

## CLI (elephant-md)

Publish, pull, and manage documents from your terminal.

### Install & Login
```
npx elephant-md                    # No install needed
npm i -g elephant-md               # Or install globally for `tusk` shorthand
npx elephant-md login github       # Log in with GitHub
npx elephant-md login google       # Log in with Google
```

### Core Commands
```
npx elephant-md push <file> [options]       # Publish or update a document
npx elephant-md pull @user/slug -o file.md  # Download a document
npx elephant-md list                        # List your documents
npx elephant-md search "query"              # Search public documents
npx elephant-md trending --category guide   # Show trending docs
npx elephant-md whoami                      # Show current user
```

### push options
- `--public` / `--private` — Set visibility (default: unlisted)
- `--name <title>` — Override document title (single file only; defaults to first H1 or filename)
- `--slug <slug>` — Custom URL slug (default: derived from title)
- `--category <cat>` — skills, guides, specs, standards, templates, plans, proposals, reference, runbooks
- `--doc-type <type>` — context, skill, command, rule (auto-detected from path)
- `--tags <t1,t2>` — Comma-separated tags
- `--burn <ttl>` — Create a burn link (1h, 24h, 7d, 30d)
- `--forked-from <@user/slug>` — Mark as forked from another document
- `--to <collection>` — Add to collection (auto-creates if missing)
- `--to-visibility <vis>` — Visibility for auto-created collection
- `--upsert` — Update existing document on slug or content conflict
- `--batch` — Continue on errors in multi-file push

### Document Tracking
The CLI tracks pushed files in `.elephant.json` so re-pushing updates the existing document instead of creating a duplicate.
- **In a git repo**: `.elephant.json` at the repo root (relative paths, committable)
- **Outside a git repo**: `~/.config/elephant/tracking.json` (absolute paths)

When a tracked file is unchanged, push prints "Already up to date" and skips the API call.

### Agent Integration
```
npx elephant-md install @user/slug     # Install doc into agent context (CLAUDE.md, etc.)
npx elephant-md install --mcp          # Configure MCP server for your agent
npx elephant-md update                 # Check for and apply upstream updates to installed docs
```

### Burn Links (self-destructing documents)
```
npx elephant-md share secret.md --mode viewonce          # Destroyed after first read
npx elephant-md share notes.md --mode timed --ttl 1h     # Auto-expires after duration
npx elephant-md share notes.md --mode timed --ttl 24h
npx elephant-md share notes.md --mode timed --ttl 7d
```

### Bookmarks & Collections
```
npx elephant-md save @user/slug                     # Bookmark a document
npx elephant-md save @user/slug --to my-collection  # Bookmark + add to collection
npx elephant-md unsave @user/slug                   # Remove bookmark
npx elephant-md collections list                    # List your collections
npx elephant-md collections create "Name" --public  # Create collection
npx elephant-md collections show my-collection      # Show collection details
npx elephant-md collections add col @user/slug      # Add doc to collection
npx elephant-md collections remove col @user/slug   # Remove doc from collection
npx elephant-md collections delete my-collection    # Delete a collection
```

### Edit metadata
```
npx elephant-md edit @user/slug --title "New Title" --tags "ai,agents" --visibility public
```

### Configuration
Auth token stored in `~/.tusk/config.json`. Saved after `login`, used automatically for all authenticated commands.

---

## VS Code Extension

Publish and manage documents directly from your editor. Works in VS Code, Cursor, and Windsurf.

### Install
Search "Elephant.md" in extensions (`Cmd+Shift+X` / `Ctrl+Shift+X`), or install from the VS Code Marketplace: https://marketplace.visualstudio.com/items?itemName=Elephant.elephant-vscode

### Login
Run `Elephant: Login` from the command palette (`Cmd+Shift+P` / `Ctrl+Shift+P`).

### Commands
- `Elephant: Publish` — Create a new document with full metadata form
- `Elephant: Push` — Push the active file as an update to an existing document
- `Elephant: Pull` — Download a document into your workspace
- `Elephant: Create Burn Link` — Create a self-destructing link from the active file
- `Elephant: Create Collection` — Create a new collection
- `Elephant: Create Collection from Folder` — Publish all markdown files in a folder as a collection
- `Elephant: Add to Collection` — Add a tracked document to a collection
- `Elephant: Toggle Bookmark` — Bookmark or unbookmark a document

### Document Tracking
The extension creates `.elephant.json` in your workspace root to map local files to remote documents:
```json
{
  "documents": {
    "README.md": {
      "id": "abc123",
      "username": "you",
      "slug": "readme",
      "lastPushedHash": "a1b2c3..."
    }
  }
}
```
This enables `Push` to know which document to update when you save changes. The CLI uses the same format (see CLI > Document Tracking above).

---

## REST API

Base URL: `https://elephant.md/api/v1`

### Authentication
```
Authorization: Bearer <your-token>
```
Get a token: `npx elephant-md login github`, then read `~/.tusk/config.json`. Public endpoints work without auth.

### Documents
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | /api/v1/documents | Yes | Create a document |
| GET | /api/v1/documents | Yes | List your documents (query: visibility, category, limit, offset) |
| GET | /api/v1/documents/@:user/:slug | No | Fetch document content and metadata |
| POST | /api/v1/documents/:id/versions | Yes | Push a new version |
| PATCH | /api/v1/documents/:id | Yes | Update metadata (title, visibility, tags, category, pin_order) |
| DELETE | /api/v1/documents/:id | Yes | Delete document permanently |
| POST | /api/v1/documents/:id/restore | Yes | Restore a version by content hash |

#### Create document request body
```json
{
  "title": "My Document",
  "content": "# Hello world",
  "category": "guides",
  "visibility": "public",
  "slug": "my-document",
  "docType": "context",
  "tags": ["ai", "agents"]
}
```
Required: title, content, category. Optional: visibility (default: unlisted), slug (auto-generated), tags, docType.

Categories: skills, guides, specs, standards, templates, plans, proposals, reference, runbooks.
Doc types: context, skill, command, rule.

### Burn Links
Add burn fields to the create document endpoint:
```json
{
  "title": "Secret",
  "content": "...",
  "category": "note",
  "isBurn": true,
  "burnMode": "viewonce",
  "burnExpiresAt": "2025-12-31T00:00:00Z"
}
```
Modes: `timed` (expires at timestamp) or `viewonce` (destroyed after first read).

### Search & Discovery
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | /api/v1/search?q=query | Hybrid full-text + semantic search (params: q, category, tag, limit) |
| GET | /api/v1/trending | Trending documents (params: category, limit) |

### Bookmarks
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | /api/v1/documents/:id/bookmark | Yes | Toggle bookmark |
| GET | /api/v1/bookmarks | Yes | List bookmarks (params: limit, offset) |

### Collections
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | /api/v1/collections | Yes | Create collection |
| GET | /api/v1/collections | Yes | List your collections |
| GET | /api/v1/collections/:id | No | Get collection details + items |
| PATCH | /api/v1/collections/:id | Yes | Update collection |
| DELETE | /api/v1/collections/:id | Yes | Delete collection (items kept) |
| POST | /api/v1/collections/:id/items | Yes | Add document to collection |
| DELETE | /api/v1/collections/:id/items/:docId | Yes | Remove document |
| PATCH | /api/v1/collections/:id/items | Yes | Reorder items |

### Users
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | /api/v1/users/@:username | Public profile + documents (params: limit, offset) |
| PATCH | /api/v1/users/me | Update your profile (auth required) |

### Installs
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | /api/v1/installs | Yes | Record a document install (body: documentId, agentType) |
| GET | /api/v1/installs | Yes | List installed documents |

### Rate Limits
Rates scale with trust tier (0–3). Headers on every response:
```
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1709836800
```
Returns 429 with `retryAfter` (seconds) when rate limited.

### Raw Markdown Access
Any document page or share link supports `?raw` query parameter or `Accept: text/markdown` header to get raw markdown instead of HTML:
```
GET https://elephant.md/@user/slug?raw
GET https://elephant.md/share/abc123?raw
```

### Errors
```json
{ "error": { "code": "NOT_FOUND", "message": "Document not found" } }
```
Codes: UNAUTHORIZED (401), NOT_FOUND (404), VALIDATION_ERROR (400), CONFLICT (409), RATE_LIMITED (429), CONTENT_BLOCKED (422).
