skillc 0.2.1

A development kit for Agent Skills - the open format for extending AI agent capabilities
Documentation
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
<!-- GENERATED: do not edit. Source: RFC-0007 -->
<!-- SIGNATURE: sha256:5fff06d3900ec8ee5d2b6a2e5b002776ca87fceddec447166e6c73bdff566023 -->

# RFC-0007: CLI Reference

> **Version:** 0.1.0 | **Status:** normative | **Phase:** test

---

## 1. Summary

### [RFC-0007:C-OVERVIEW] Overview (Informative) <a id="rfc-0007c-overview"></a>

RFC-0007 is the single source of truth for skillc's command-line interface.

This RFC specifies:

1. **Command Registry** — All commands, their parameters, and interface availability (CLI vs MCP)
2. **Skill Resolution** — How skill names/paths are resolved to source directories
3. **Access Logging** — How command invocations are logged for analytics
4. **Sync Command** — How fallback logs are merged to primary locations
5. **MCP Interface** — The Model Context Protocol server for agent integration

**Relationship to other RFCs:**

- [RFC-0001]../rfc/RFC-0001.md — Skill Compilation (`build` command behavioral spec)
- [RFC-0002]../rfc/RFC-0002.md — Gateway Protocol (`outline`, `show`, `open`, `sources` behavioral specs)
- [RFC-0003]../rfc/RFC-0003.md — Usage Analytics (`stats` command behavioral spec)
- [RFC-0004]../rfc/RFC-0004.md — Search Protocol (`search` command behavioral spec)
- [RFC-0005]../rfc/RFC-0005.md — Error Code Registry (canonical error codes)
- [RFC-0006]../rfc/RFC-0006.md — Scaffolding (`init` command behavioral spec)

Each feature RFC owns the behavioral specification for its commands. RFC-0007 provides the cross-cutting infrastructure that all commands share.

*Since: v0.1.0*

---

## 2. Specification

### [RFC-0007:C-COMMANDS] Command Registry (Normative) <a id="rfc-0007c-commands"></a>

This clause defines all skillc commands, their parameters, and interface availability.

**Interface Legend:**
- **CLI**: Command-line interface (`skc <command>`)
- **MCP**: Model Context Protocol tool (`skc_<command>`)

## Command Registry

| Command | CLI | MCP | Description |
|---------|-----|-----|-------------|
| `init` ||| Initialize project or create skill |
| `list` ||| List all skillc-managed skills |
| `build` ||| Compile skill to runtime format |
| `lint` ||| Validate skill authoring quality |
| `outline` ||| List all sections in a skill |
| `show` ||| Retrieve section content |
| `open` ||| Retrieve file content |
| `sources` ||| List source files (tree-style) |
| `search` ||| Search skill content |
| `stats` ||| Usage analytics |
| `sync` ||| Merge fallback logs to primary (CLI-only) |
| `mcp` ||| Start MCP server (CLI-only) |

## Parameter Definitions

### init

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `name` | string | no || Skill name to create |
| `--global` | boolean | no | false | Create in global source store |

### list

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `--scope` | string | no | all | Filter: `project`, `global`, or `all` |
| `--status` | string | no | all | Filter: `normal`, `not-built`, `obsolete`, or `all` |
| `--limit` | number | no | unlimited | Maximum skills to return |
| `--pattern` | string | no || Filter by skill name (glob pattern) |
| `--check-obsolete` | boolean | no | false | Enable obsolete runtime detection |

See [RFC-0007:C-LIST](../rfc/RFC-0007.md#rfc-0007c-list) for full specification.

### build

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `skill` | string | yes || Skill name or path |
| `--global` | boolean | no | false | Force SSOT to global (~/.skillc/runtime/) |
| `--target` | string[] | no | claude | Target agents to deploy to (comma-separated) |
| `--copy` | boolean | no | false | Force copy instead of symlink/junction |
| `--force` | boolean | no | false | Overwrite existing skill during import |

**Behavior:**

- **Skill name**: Looks up skill in project source store (`.skillc/skills/`) then global (`~/.skillc/skills/`)
- **Path**: Imports skill to source store first, then builds (requires `--force` to overwrite existing)

Compiles to SSOT location (`.skillc/runtime/` for local sources, `~/.skillc/runtime/` for global) and deploys to agent directories via symlink. See [RFC-0001:C-DEPLOYMENT](../rfc/RFC-0001.md#rfc-0001c-deployment).

### lint

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `skill` | string | yes || Skill name or path |
| `--force` | boolean | no | false | Lint even if skill is compiled |

### outline

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `skill` | string | yes || Skill name or path |
| `level` | number | no | unlimited | Maximum heading level (1-6) |

### show

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `skill` | string | yes || Skill name or path |
| `section` | string | yes || Section heading to retrieve |
| `file` | string | no || Limit search to specific file |
| `max_lines` | number | no | unlimited | Maximum lines to return |

### open

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `skill` | string | yes || Skill name or path |
| `path` | string | yes || Relative path within skill |
| `max_lines` | number | no | unlimited | Maximum lines to return |

### sources

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `skill` | string | yes || Skill name or path |
| `depth` | number | no | unlimited | Maximum tree depth |
| `dir` | string | no || Scope to subdirectory |
| `limit` | number | no | 100 | Maximum entries |
| `pattern` | string | no || Glob pattern filter |

### search

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `skill` | string | yes || Skill name or path |
| `query` | string | yes || Search query |
| `limit` | number | no | 10 | Maximum results |

### stats

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `skill` | string | yes || Skill name or path |
| `group_by` | string | no | summary | Aggregation dimension: `summary`, `files`, `sections`, `commands`, `projects`, `errors`, `search` |
| `since` | string | no || Include accesses on or after (ISO 8601) |
| `until` | string | no || Include accesses on or before (ISO 8601) |
| `project` | string[] | no || Filter by project directory |

### sync (CLI-only)

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `skill` | string | no || Specific skill to sync |
| `project` | string | no | CWD | Project directory |
| `dry_run` | boolean | no | false | Preview without writing |

**Rationale for CLI-only commands:**

- **sync**: MCP servers run outside the sandbox and write directly to primary runtime locations. No fallback logs are created, so there is nothing to sync. See [RFC-0007:C-LOGGING]../rfc/RFC-0007.md#rfc-0007c-logging for fallback mechanism.
- **mcp**: Starts the MCP server itself; not callable from within MCP.

## MCP Tool Naming

MCP tools use snake_case with `skc_` prefix:

| CLI Command | MCP Tool |
|-------------|----------|
| `skc init` | `skc_init` |
| `skc list` | `skc_list` |
| `skc build` | `skc_build` |
| `skc lint` | `skc_lint` |
| `skc outline` | `skc_outline` |
| `skc show` | `skc_show` |
| `skc open` | `skc_open` |
| `skc sources` | `skc_sources` |
| `skc search` | `skc_search` |
| `skc stats` | `skc_stats` |

*Since: v0.1.0*

### [RFC-0007:C-RESOLUTION] Skill Resolution (Normative) <a id="rfc-0007c-resolution"></a>

All commands that operate on skills accept a `<skill>` argument that identifies the target skill.

**Source directory resolution (first match wins):**

1. If `<skill>` resolves to a valid directory path containing `SKILL.md`, use it directly (CWD-relative or absolute). This means a local path takes precedence over a global skill with the same name.
2. If project config exists (`.skillc/config.toml` relative to CWD), check project source store using `<skill>` as a name
3. Check global source store (`~/.skillc/skills/<skill>/`) using `<skill>` as a name
4. Resolution failed. Exit with error per [RFC-0005:C-CODES]../rfc/RFC-0005.md#rfc-0005c-codes:
   - If a directory was found at any step but it lacks `SKILL.md`: emit **E010**
   - Otherwise (no directory found at all): emit **E001**

**Runtime directory resolution (for logging):**

Derive `<skill-name>` from the resolved source directory's basename.
Resolve the runtime store using the same config precedence as storage layout (project config, then global config, then defaults).
The runtime directory is `<runtime-store>/<skill-name>/`.
If multiple source directories share the same basename within the same runtime store, they will share a log database; `skill_path` in the log distinguishes entries.

*Since: v0.1.0*

### [RFC-0007:C-LOGGING] Access Logging (Normative) <a id="rfc-0007c-logging"></a>

All commands that resolve skills MUST log access events for usage analytics.

**Log storage:**
Logs MUST be stored in a SQLite database at `.skillc-meta/logs.db` in the resolved runtime directory.

**Schema:**
The database MUST contain an `access_log` table with at minimum:
- `id` — Auto-incrementing primary key
- `timestamp` — RFC 3339 UTC timestamp (`YYYY-MM-DDTHH:MM:SSZ`)
- `run_id` — Session identifier
- `command` — Command name (the `skc` subcommand, e.g., `outline`, `show`, `open`, `search`, `build`, `stats`)
- `skill` — Skill name (directory basename)
- `skill_path` — Canonicalized absolute path to the resolved skill source directory
- `cwd` — Canonicalized absolute path of the current working directory when command was invoked
- `args` — JSON-encoded command arguments
- `error` — Error message if command failed (NULL on success)

Canonicalization MUST resolve `.` and `..` path segments and MUST resolve symlinks to their real paths.

**Run ID generation:**
If `SKC_RUN_ID` environment variable is set, use its value. Otherwise, generate a run ID in the format `YYYYMMDDTHHMMSSZ-<rand4>` where `<rand4>` is 4 random hex characters.

**Initialization:**
The command MUST attempt to create the runtime directory, `.skillc-meta/` subdirectory, database, and schema if they do not exist.

**Fallback logging (EAFP):**
The command MUST first attempt to write to the primary runtime directory. If the INSERT fails with a read-only error (e.g., sandboxed filesystem), the command MUST fall back to `<cwd>/.skillc/logs/<skill-name>/.skillc-meta/logs.db`. The fallback directory and database MUST be created if they do not exist.

If both primary and fallback locations fail, the command MUST emit a warning to stderr:
`warning: logging disabled; run 'skc sync' after session to merge logs`

**Stale fallback warning:**
If fallback logs exist for the current skill and the database file's mtime is older than 1 hour, the command SHOULD emit a warning to stderr:
`warning: stale local logs for '<skill>'; run 'skc sync' to upload`

This warning SHOULD be emitted at most once per command invocation (not per skill if multiple skills are accessed).

The command MUST continue execution regardless of logging success.

*Since: v0.1.0*

### [RFC-0007:C-SYNC] Sync Command (Normative) <a id="rfc-0007c-sync"></a>

**Syntax:** `skc sync [<skill>] [options]`

The sync command MUST move log entries from project-local fallback databases to the primary runtime log, then delete the local fallback.

**Source discovery:**
Scan `<cwd>/.skillc/logs/` for skill subdirectories containing `.skillc-meta/logs.db`. If `<skill>` is provided, sync only that skill's logs.

**Destination:**
The primary runtime directory per [RFC-0007:C-RESOLUTION](../rfc/RFC-0007.md#rfc-0007c-resolution). For global skills, this is typically `~/.skillc/runtime/<skill>/.skillc-meta/logs.db`.

**Behavior:**
1. For each discovered skill, copy all entries to the destination database
2. Skip entries that already exist (idempotent safety check)
3. After successful copy, delete the local fallback database directory
4. If destination is not writable (e.g., sandbox still active), emit error E041 and skip that skill

**Partial failure:**
If sync succeeds for skill A but fails for skill B, delete A's local logs and report B's error. Each skill is independent.

**Options:**

| Option | Description |
|--------|-------------|
| `--project <path>` | Sync from specified project directory instead of CWD |
| `--dry-run` | Show what would be synced without writing or deleting |

**Output:**

```
Synced 47 entries for 'rust' (local logs removed)
Synced 12 entries for 'cuda' (local logs removed)
```

With `--dry-run`:
```
Would sync 47 entries for 'rust'
Would sync 12 entries for 'cuda'
```

If no local logs exist:
```
No local logs to sync
```

**Exit codes:**
- 0: Success (including "nothing to sync")
- 1: Error (partial or complete failure). See [RFC-0005:C-CODES]../rfc/RFC-0005.md#rfc-0005c-codes for error codes E040–E042.

*Since: v0.1.0*

### [RFC-0007:C-LIST] List Command (Normative) <a id="rfc-0007c-list"></a>

**Syntax:** `skc list [options]`

The list command MUST enumerate all skillc-managed skills from source stores.

## Discovery

The command MUST discover skills from these locations in order:

1. **Project-local source store**: Recursive-up search for `.skillc/skills/` directories
2. **Global source store**: `~/.skillc/skills/`

A valid skill is a directory containing a `SKILL.md` file with valid frontmatter.

## Status Detection

### Default (Fast Mode)

Without `--check-obsolete`, status detection is fast:

| Status | Condition |
|--------|-----------|
| `normal` | Runtime directory exists with valid manifest.json |
| `not-built` | No runtime directory or no manifest.json |

### With --check-obsolete (Hash Comparison)

When `--check-obsolete` is provided, the command performs expensive source hash comparison:

| Status | Condition |
|--------|-----------|
| `normal` | Runtime exists and source hash matches manifest |
| `not-built` | No runtime directory or no manifest.json |
| `obsolete` | Runtime exists but source hash differs from manifest |

## Output Format

### Text Output (CLI default)

```
$ skc list
SKILL           SCOPE    STATUS
my-skill        project  normal
cuda            global   not-built
```

When `--verbose` is provided, include paths:

```
$ skc list --verbose
SKILL           SCOPE    STATUS     SOURCE
my-skill        project  normal     .skillc/skills/my-skill
cuda            global   not-built  ~/.skillc/skills/cuda
```

### JSON Output (MCP default)

```json
{
  "skills": [
    {
      "name": "my-skill",
      "scope": "project",
      "status": "normal",
      "source_path": "/path/to/.skillc/skills/my-skill",
      "runtime_path": "/path/to/.skillc/runtime/my-skill"
    }
  ],
  "total": 1,
  "filtered": 1
}
```

## Filtering

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `--scope` | `project\|global\|all` | `all` | Filter by skill scope |
| `--status` | `normal\|not-built\|obsolete\|all` | `all` | Filter by build status |
| `--limit` | number | unlimited | Maximum skills to return |
| `--pattern` | string || Filter by skill name (glob pattern) |
| `--check-obsolete` | boolean | false | Enable hash comparison for obsolete detection |

## Ordering

Skills MUST be ordered by:
1. Scope: project before global
2. Name: alphabetical within scope

## Error Handling

- If no skills are found, output an empty list (not an error)
- If a skill directory exists but `SKILL.md` is invalid, skip with warning

*Since: v0.1.0*

---

## 3. MCP Interface

### [RFC-0007:C-MCP-OVERVIEW] MCP Interface Overview (Informative) <a id="rfc-0007c-mcp-overview"></a>

The MCP (Model Context Protocol) interface provides structured access to skillc functionality for AI agents. Per [ADR-0003](../adr/ADR-0003.md), MCP is the recommended interface for agents because:

1. **No sandbox restrictions:** MCP servers run outside the IDE sandbox, enabling writes to global directories
2. **Structured I/O:** JSON input/output eliminates text parsing errors
3. **Native integration:** MCP is the designed protocol for agent tools
4. **Reduced latency:** No shell process spawn per command

The MCP interface mirrors CLI functionality. Each CLI command has a corresponding MCP tool with equivalent behavior but structured data exchange.

**Architecture:**

```
Human users:  Terminal → skc CLI → skillc core
AI agents:    MCP client → skillc MCP server → skillc core
```

*Since: v0.1.0*

### [RFC-0007:C-MCP-SERVER] MCP Server (Normative) <a id="rfc-0007c-mcp-server"></a>

**Syntax:** `skc mcp`

The MCP server command MUST start a long-running process that speaks the MCP protocol over stdio.

**Protocol:**

The server MUST implement the MCP stdio transport:
- Read JSON-RPC messages from stdin
- Write JSON-RPC messages to stdout
- Diagnostic output (if any) MUST go to stderr

**Server info:**

The server MUST respond to `initialize` with:
- `name`: `"skillc"`
- `version`: The skillc version string

**Tool discovery:**

The server MUST respond to `tools/list` with the MCP-enabled tools defined in [RFC-0007:C-COMMANDS](../rfc/RFC-0007.md#rfc-0007c-commands).

**Configuration:**

The MCP server is configured in the agent's MCP settings:

```json
{
  "mcpServers": {
    "skillc": {
      "command": "skc",
      "args": ["mcp"]
    }
  }
}
```

**Logging:**

All tool invocations MUST be logged per [RFC-0007:C-LOGGING](../rfc/RFC-0007.md#rfc-0007c-logging). Since the MCP server runs outside the sandbox, logging SHOULD write directly to the primary runtime location (no fallback needed).

*Since: v0.1.0*

---

## Changelog

### v0.1.0 (2026-01-30)

Initial release