Content
# MD Ops
**Website and docs:** [about7sharks.github.io/md-ops](https://about7sharks.github.io/md-ops/)
MD Ops is a **local-first Markdown operations workspace**. It gives one trusted operator a browser UI, a small HTTP API, and a stdio MCP server for safe work inside an allowlisted set of Markdown roots.
This repository is a clean distribution source. It intentionally excludes user vaults, screenshots, infrastructure notes, absolute host paths, service addresses, credentials, and Git history from earlier private development.
## What is included
- `packages/ui` — React/Vite user interface for file browsing, Markdown preview, graphing, and guarded edits.
- `packages/api` — Bun HTTP API. It exposes only logical root IDs and relative paths.
- `packages/mcp` — stdio Model Context Protocol server that uses the HTTP API. It starts read-only.
- `skills/` — portable agent instructions for HTTP and MCP operation.
- `example-vault/` — synthetic content only.
## Security boundary
MD Ops is **not** a hosted multi-user product. The supplied deployment binds the service to the configured loopback address and disables mutations by default. It has no user login, tenant isolation, or recoverable delete. Do not publish it to the Internet, attach it to an untrusted network, or use it with irreplaceable content.
Read [SECURITY.md](SECURITY.md) before changing the bind address or enabling writes.
## Quick start: safe demo
Prerequisites:
- Docker Engine with Compose v2
- A Unix-like host that can run the supplied container
```bash
cp .env.example .env
docker compose build
docker compose up -d
docker compose ps
```
Open the address made from `MD_OPS_BIND_ADDRESS` and `MD_OPS_PORT` in `.env`. The demo mounts only `example-vault/`. It is read-only until you explicitly enable mutations.
Check status without exposing root paths:
```bash
curl --fail "http://${MD_OPS_BIND_ADDRESS}:${MD_OPS_PORT}/readyz"
```
Stop the demo:
```bash
docker compose down
```
## Configure a real Markdown root
1. Create a narrow dedicated directory. Do not use a home directory, filesystem root, shared drive root, or a directory containing secrets.
2. Copy `.env.example` to `.env` and set `MD_OPS_VAULT_PATH` to that directory.
3. Keep `MD_OPS_ALLOW_MUTATIONS=false` for initial review.
4. Build and start again. The API rejects missing, nested, overlapping, or unreadable roots.
5. Back up the root outside MD Ops before any mutation use.
To enable editing on a trusted local machine, set `MD_OPS_ALLOW_MUTATIONS=true`, restart the container, and recheck `/readyz`. This changes the readiness field `writes` from `disabled` to `enabled`.
## API contract
The browser and MCP server use logical paths only:
```text
<root-id>/<relative/path.md>
```
The service does not return physical paths. Core read endpoints are `/api/roots`, `/api/tree`, `/api/search`, `/api/file`, and `/api/system-graph`. Mutating endpoints require both `MD_OPS_ALLOW_MUTATIONS=true` and `X-Confirm-Write: 1`. Updates can use `If-Match` for ETag conflict detection.
## MCP for agents
Install MCP dependencies from the repository root:
```bash
npm ci --workspace=@md-ops/mcp
npm --prefix packages/mcp run build
```
Set `MD_OPS_API_URL` to the already trusted MD Ops service address. The MCP server has **no default service address**. It refuses URLs with embedded credentials, fragments, or query strings.
Start it in a terminal that has `MD_OPS_API_URL`:
```bash
npm --prefix packages/mcp run start
```
Use the configuration template in [`docs/mcp-config.example.json`](docs/mcp-config.example.json). The server exposes read tools by default:
- `md_ops_list_roots`
- `md_ops_list_files`
- `md_ops_search`
- `md_ops_read_file`
Set `MD_OPS_MCP_WRITE_ENABLED=true` only after the API separately reports `writes: enabled`. The write tool still requires its `confirm_write` argument to be true. Every successful `md_ops_read_file` and `md_ops_write_file` response also includes a browser Read-view deep link. Agents should send the returned `url` when they create a requested file. See [`skills/md-ops-mcp/SKILL.md`](skills/md-ops-mcp/SKILL.md).
## AI agent setup prompt (copy-paste)
Give this prompt to a coding agent (Claude Code, Codex, Cursor, etc.) and it will set up, verify, and run this repository end to end:
```text
Set up the MD Ops repository at the current directory. Complete every step and
report concrete results; do not stop at a plan.
Environment:
- Bun 1.3.13 is required (api + tests). Install it if missing:
curl -fsSL https://bun.sh/install | bash # then open a new shell
- Node 24 with npm is required (ui + mcp).
Steps:
1. Read README.md, SECURITY.md, CONTRIBUTING.md, and the package manifests.
2. Install dependencies:
npm ci
cd packages/api && bun install --frozen-lockfile && cd ../..
3. Run the full verification gate from the repository root:
npm run verify
This builds the UI, stages the bundle for the API, runs every test suite
(api, ui, mcp), typechecks the API, and builds the MCP server.
All suites must report 0 failures. If any step fails, fix the cause and
re-run until green.
4. Run the public-tree audit (must pass):
./scripts/audit-public-tree.sh
5. Start the API in dev mode against the synthetic example vault:
cd packages/api
MD_OPS_ROOTS='[{"id":"demo","label":"Demo vault","path":"'$PWD'/example-vault"}]' bun run dev
In a second shell, verify the endpoints:
curl -s http://127.0.0.1:3098/healthz # expect 200
curl -s http://127.0.0.1:3098/readyz # expect {"ready":true,...}
curl -s "http://127.0.0.1:3098/api/tree?root=demo" # expect file list
6. Build and start the full Docker demo (separate from step 5; stop the dev
API first):
cp .env.example .env
docker compose build && docker compose up -d
curl --fail http://127.0.0.1:3098/readyz
Then: docker compose down
7. Report: test counts per suite, audit result, the exact /readyz JSON, the
tree endpoint output, and confirm the Docker demo started and stopped.
Rules: never commit .env files, tokens, or real vault content; keep the
loopback-only default; do not expose the service to the network; do not push
any branch or open PRs unless explicitly asked.
```
## Development and verification
Use the pinned package managers listed in each package manifest. One-command gate from the repository root:
```bash
npm run verify
```
This runs `scripts/prepare-ui-bundle.sh` (builds the UI and stages `dist/` into `packages/api/ui/`, which the API serves and its `/readyz` test requires), then the API tests, API typecheck, UI tests, MCP tests, and the MCP build. `scripts/with-bun.sh` resolves Bun for npm scripts, so `bun` does not need to be on your login shell PATH.
If you prefer to run the steps individually:
```bash
npm ci
bash scripts/with-bun.sh bash -c 'cd packages/api && bun install --frozen-lockfile'
# api
bash scripts/with-bun.sh bun --cwd packages/api test
bash scripts/with-bun.sh bash -c 'cd packages/api && bunx tsc --noEmit'
# ui
bash scripts/with-bun.sh bash -c 'cd packages/ui && bun test'
npm --prefix packages/ui run build
# mcp
bash scripts/with-bun.sh bash -c 'cd packages/mcp && bun test'
npm --prefix packages/mcp run build
./scripts/audit-public-tree.sh
docker compose build
```
## Open source
MD Ops is released under the [MIT License](LICENSE). You are free to use, modify, and redistribute it under the license terms.
Contributions are welcome. Read [CONTRIBUTING.md](CONTRIBUTING.md) for the scope and data-hygiene rules before proposing a change.
To report a security issue, follow the private reporting steps in [SECURITY.md](SECURITY.md) — do not open a public issue with exploit details.
Thanks for checking out MD Ops — we hope it is useful to you.
Connection Info
You Might Also Like
ai-native-pm-os
The exhaustive guide to mastering Claude for Product Managers. Build your...
Train-in-Silence
The first Task-Aware MCP server and automated VRAM calculator for LLM...
stacklit
108,000 lines of code. 4,000 tokens of index. One command makes any repo...
AppClaw
AI-powered mobile automation agent — describe what you want in plain...
pdf-mcp
Production-ready MCP server for PDF processing with intelligent caching....
kotadb
Local-only code intelligence API for AI developer workflows (Bun +...