mc 0.1.0

Git-based knowledge management CLI — manage customers, projects, meetings, research and tasks with Markdown + YAML frontmatter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
# mc -- MissionControl CLI

A command-line tool for managing git-based knowledge repositories. Scaffolds new entities, validates repo structure, builds JSON indexes, exports archives, and serves a local dashboard.

## Installation

### From crates.io

```bash
cargo install mc
```

### Prebuilt binaries

Download the latest release for your platform from the [GitHub Releases](https://github.com/RaaSaaR-org/mission-control/releases) page:

| Platform | Archive |
|----------|---------|
| macOS (Apple Silicon) | `mc-macos-arm64.tar.gz` |
| macOS (Intel) | `mc-macos-amd64.tar.gz` |
| Linux (x86_64) | `mc-linux-amd64.tar.gz` |
| Linux (arm64) | `mc-linux-arm64.tar.gz` |

Extract and place `mc` somewhere on your `PATH`:

```bash
tar xzf mc-<platform>.tar.gz
sudo mv mc /usr/local/bin/
```

### Build from source

```bash
cargo install --git https://github.com/RaaSaaR-org/mission-control
```

Or clone and build locally:

```bash
git clone https://github.com/RaaSaaR-org/mission-control.git
cd mission-control
cargo build --release
# Binary is at target/release/mc
```

## Usage

```
mc [--root <PATH>] [-y|--yes] <COMMAND>
```

**Global flags:**

| Flag | Description |
|------|-------------|
| `--root <PATH>` | Path to repo root. Auto-detected by walking up the directory tree looking for `config/config.yml` if omitted. |
| `-y, --yes` | Skip interactive prompts and use defaults. |

## Commands

### `mc new` -- scaffold a new entity

Creates directories, files, and YAML frontmatter from templates. The next sequential ID is assigned automatically.

#### `mc new customer "<name>"`

| Option | Description |
|--------|-------------|
| `--owner <OWNER>` | Owner name |
| `--status <STATUS>` | Initial status (default: prompted interactively) |
| `--tags <TAGS>` | Comma-separated tags |

Creates `customers/CUST-NNN-slug/` with:
- `_index.md` -- customer overview with frontmatter
- `contacts.md` -- contact list template
- Subdirectories: `contracts/`, `meetings/`, `projects/`, `assets/`

#### `mc new project "<name>"`

| Option | Description |
|--------|-------------|
| `--owner <OWNER>` | Project owner |
| `--status <STATUS>` | Initial status |
| `--customers <IDS>` | Comma-separated customer IDs to link |
| `--tags <TAGS>` | Comma-separated tags |

Creates `projects/PROJ-NNN-slug/` with:
- `overview.md` -- project overview with frontmatter
- `roadmap.md` -- milestone tracking template
- `backlog.md` -- task tracking template
- Subdirectories: `specs/`, `releases/`, `infra/`

#### `mc new meeting "<title>"`

| Option | Description |
|--------|-------------|
| `--date <DATE>` | Date in `YYYY-MM-DD` format (defaults to today) |
| `--time <TIME>` | Time in `HH:MM` format (defaults to `10:00`) |
| `--duration <DUR>` | Duration string (e.g. `30m`, `1h`) |
| `--status <STATUS>` | Initial status |
| `--tags <TAGS>` | Comma-separated tags |
| `--customers <IDS>` | Comma-separated customer IDs to link |
| `--projects <IDS>` | Comma-separated project IDs to link |

Creates `meetings/YYYY-MM-DD-slug.md` with frontmatter and agenda/notes/action-items sections.

#### `mc new research "<title>"`

| Option | Description |
|--------|-------------|
| `--owner <OWNER>` | Research owner |
| `--agents <AGENTS>` | Comma-separated agent names (defaults to `claude,gemini,chatgpt,perplexity`) |
| `--tags <TAGS>` | Comma-separated tags |

Creates `research/RES-NNN-slug/` with:
- `_index.md` -- research overview with frontmatter
- One subdirectory per agent
- `final/` -- for the consolidated report

---

### `mc list` -- list entities

```
mc list <customers|projects|meetings|research> [OPTIONS]
```

| Option | Description |
|--------|-------------|
| `--status <STATUS>` | Filter by status (case-insensitive) |
| `--tag <TAG>` | Filter by tag (case-insensitive) |

Prints a formatted table with color-coded statuses:
- **Green:** active, completed, final
- **Yellow:** on-hold, draft, in-progress
- **Blue:** prospect, scheduled
- **Red:** inactive, cancelled, churned, outdated

---

### `mc show` -- display entity details

```
mc show <ID>
```

Accepts any entity ID (e.g. `CUST-001`, `PROJ-001`, `MTG-001`, `RES-001`). Prints all frontmatter fields and the first 20 non-empty lines of body content.

---

### `mc validate` -- check repo integrity

```
mc validate
```

Runs these checks across all entities:

| Check | Description |
|-------|-------------|
| Folder naming | Directories match `PREFIX-NNN-slug` pattern |
| Meeting filenames | Files match `YYYY-MM-DD-title.md` pattern |
| Index file presence | `_index.md` (customers, research) or `overview.md` (projects) exists |
| Frontmatter presence | YAML frontmatter block (`---`) is present |
| YAML validity | Frontmatter parses as valid YAML |
| Required fields | `id` is present; `name` for customers/projects; `title` for meetings/research |
| ID prefix | ID starts with the correct prefix for its entity type |
| Status validity | Status value is in the configured allowed list |
| Slug consistency | Frontmatter slug matches the directory name |

Exits with code 1 if any issues are found.

---

### `mc index` -- rebuild JSON indexes

```
mc index
```

Parses frontmatter from all entities and writes:
- `data/index.json` -- combined index of all entities
- `data/customers.json` -- customers only
- `data/projects.json` -- projects only
- `data/research.json` -- research only

Each record includes the frontmatter fields plus a `_source` path. These files are gitignored and regenerated on demand.

---

### `mc export` -- export to ZIP

```
mc export customer <ID_OR_SLUG>
```

Accepts a customer ID (`CUST-001`) or slug (`acme-inc`). Writes a ZIP archive to `archive/CUST-NNN-slug-YYYY-MM-DD.zip` containing the entire customer directory.

---

### `mc status` -- repo overview

```
mc status
```

Prints entity counts broken down by status with ASCII bar charts, plus the 5 most recently modified files.

---

### `mc serve` -- local dashboard

```
mc serve [--port <PORT>]
```

Starts a web server on `127.0.0.1` (default port: `5000`).

| Route | Description |
|-------|-------------|
| `/` | Dashboard with status counts and recent activity |
| `/customers` | Customer list (supports `?status=` and `?tag=` query params) |
| `/projects` | Project list (supports `?status=` and `?tag=` query params) |
| `/meetings` | Meeting list (supports `?status=` and `?tag=` query params) |
| `/research` | Research list (supports `?status=` and `?tag=` query params) |
| `/entity/{id}` | Entity detail page |

### `mc mcp` -- MCP server

Starts a [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server over stdio. This allows AI assistants (Claude Code, Cursor, Windsurf, VS Code + Copilot, etc.) to interact with MissionControl directly -- listing entities, creating new ones, validating the repo, and more.

```
mc mcp
```

The server communicates via JSON-RPC 2.0 over stdin/stdout. It is not meant to be run manually -- configure it in your editor/assistant instead (see [MCP Server Integration](#mcp-server-integration) below).

---

## Configuration

The CLI reads `config/config.yml` from the repo root. This file defines:

- **paths** -- directory names for each entity type, data, templates, and archive
- **id_prefixes** -- prefix strings per entity type (`CUST`, `PROJ`, `MTG`, `RES`)
- **statuses** -- allowed status values per entity type

See `config/config.yml` for the full schema and current values.

## MCP Server Integration

The `mc mcp` command exposes all CLI functionality as MCP tools and resources. Once connected, an AI assistant can create entities, query data, validate the repo, rebuild indexes, and more -- all without leaving the editor.

### Prerequisites

- Build `mc` from source (`cargo build --release`) or download a prebuilt binary.
- Know the **absolute path** to the `mc` binary and the repo root.

### Editor configuration

> **Note:** `--root` is a global flag and must come **before** the `mcp` subcommand in the args list.

#### Claude Code

One-line setup:

```bash
claude mcp add mc -- /absolute/path/to/mc --root /absolute/path/to/repo mcp
```

Or create `.mcp.json` in the project root manually:

```json
{
  "mcpServers": {
    "mc": {
      "command": "/absolute/path/to/mc",
      "args": ["--root", "/absolute/path/to/repo", "mcp"]
    }
  }
}
```

#### Cursor

Create `.cursor/mcp.json` in the project root:

```json
{
  "mcpServers": {
    "mc": {
      "command": "/absolute/path/to/mc",
      "args": ["--root", "/absolute/path/to/repo", "mcp"]
    }
  }
}
```

#### Windsurf

Edit `~/.codeium/windsurf/mcp_config.json`:

```json
{
  "mcpServers": {
    "mc": {
      "command": "/absolute/path/to/mc",
      "args": ["--root", "/absolute/path/to/repo", "mcp"]
    }
  }
}
```

#### VS Code

Create `.vscode/mcp.json` in the project root:

```json
{
  "servers": {
    "mc": {
      "type": "stdio",
      "command": "/absolute/path/to/mc",
      "args": ["--root", "/absolute/path/to/repo", "mcp"]
    }
  }
}
```

#### Claude Desktop

Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):

```json
{
  "mcpServers": {
    "mc": {
      "command": "/absolute/path/to/mc",
      "args": ["--root", "/absolute/path/to/repo", "mcp"]
    }
  }
}
```

### Available tools

| Tool | Description | Required params |
|------|-------------|-----------------|
| `list_entities` | List entities by kind with optional filters | `kind` |
| `get_entity` | Get detailed info about an entity | `id` |
| `read_entity_file` | Read full markdown content | `id` |
| `create_customer` | Create a new customer | `name` |
| `create_project` | Create a new project | `name` |
| `create_meeting` | Create a new meeting | `title` |
| `create_research` | Create a new research topic | `title` |
| `create_task` | Create a new task | `title` |
| `move_task` | Move a task to a new status | `id`, `status` |
| `list_tasks` | List tasks with rich filtering (project, customer, priority, sprint, owner) | _(none)_ |
| `print_meeting` | Export a meeting to PDF | `id` |
| `print_research` | Export a research topic to PDF | `id` |
| `validate_repo` | Check repo structure and frontmatter | _(none)_ |
| `build_index` | Rebuild JSON index files in `data/` | _(none)_ |
| `get_status` | Get status overview with counts and recent activity | _(none)_ |

### Available resources

| URI | Description |
|-----|-------------|
| `mc://config` | Repository configuration as JSON |
| `mc://entities/customers` | All customers |
| `mc://entities/projects` | All projects |
| `mc://entities/meetings` | All meetings |
| `mc://entities/research` | All research topics |
| `mc://entities/tasks` | All tasks |

### Usage examples

Once connected, you can ask your assistant things like:

- "List all active customers"
- "Create a new meeting called 'Sprint Review' for next Monday"
- "Validate the repo structure"

### Troubleshooting

- **Server failed to connect** -- check that the binary path is absolute and the file exists.
- **Server not responding** -- ensure `--root` comes before `mcp` in the args array.
- **Tools not appearing** -- restart the editor or assistant after changing the config file.

## CI/CD

### Continuous integration

Every push to `main` and every pull request runs the CI pipeline (`.github/workflows/ci.yml`):

1. `cargo fmt --check` -- formatting
2. `cargo clippy -- -D warnings` -- lints
3. `cargo test` -- tests
4. `cargo build --release` -- build

### Releasing a new version

Releases are fully automated via `.github/workflows/release.yml`. When you push a version tag, the pipeline builds platform binaries, creates a GitHub Release, and publishes to crates.io.

**Steps to release:**

1. Bump the version in `Cargo.toml`:
   ```toml
   version = "0.2.0"
   ```
2. Commit and push:
   ```bash
   git add Cargo.toml Cargo.lock
   git commit -m "Bump version to 0.2.0"
   git push
   ```
3. Tag and push the tag:
   ```bash
   git tag v0.2.0
   git push origin v0.2.0
   ```

The release workflow then:

| Job | What it does |
|-----|--------------|
| **build** | Cross-compiles binaries for Linux (amd64, arm64) and macOS (amd64, arm64) |
| **release** | Attaches the `.tar.gz` archives to a GitHub Release with auto-generated notes |
| **publish** | Publishes the crate to [crates.io]https://crates.io/crates/mc |

**One-time setup:** Add your crates.io API token as the GitHub secret `CARGO_REGISTRY_TOKEN` in repo **Settings > Secrets and variables > Actions**. Get the token from [crates.io/settings/tokens](https://crates.io/settings/tokens).

## Project structure

```
├── Cargo.toml
├── Cargo.lock
├── README.md
├── LICENSE
└── src/
    ├── main.rs          # Entry point and error display
    ├── cli.rs           # Clap argument definitions
    ├── config.rs        # Config loading and repo root detection
    ├── data.rs          # Entity collection and JSON index generation
    ├── entity.rs        # EntityKind enum, ID assignment
    ├── error.rs         # Error types with user-facing hints
    ├── frontmatter.rs   # YAML frontmatter parsing and serialization
    ├── html.rs          # Dashboard HTML rendering
    ├── mcp.rs           # MCP server implementation
    ├── template.rs      # Template scaffolding
    ├── util.rs          # Shared helpers
    └── commands/
        ├── new.rs       # mc new
        ├── list.rs      # mc list
        ├── show.rs      # mc show
        ├── index.rs     # mc index
        ├── validate.rs  # mc validate
        ├── export.rs    # mc export
        ├── serve.rs     # mc serve
        ├── status.rs    # mc status
        └── mcp.rs       # mc mcp
```

## Dependencies

| Crate | Purpose |
|-------|---------|
| clap | CLI argument parsing |
| serde / serde_yaml / serde_json | Serialization |
| walkdir | Directory traversal |
| chrono | Date/time handling |
| regex | Pattern matching for validation |
| colored | Terminal output styling |
| dialoguer | Interactive prompts |
| axum / tokio | Web server for `mc serve` |
| pulldown-cmark | Markdown-to-HTML conversion |
| zip | ZIP archive creation |
| rmcp | MCP server over stdio |
| schemars | JSON Schema generation for tool parameters |
| tracing-subscriber | Structured logging to stderr |
| thiserror | Error type derivation |

## Running tests

```bash
cargo test
```

## License

MIT