# Context Pack Specification v0.1

A Context Pack is a deterministic, machine-readable bundle of project-scoped context
assembled from a user's personal knowledge base. Its purpose is to give an AI coding
agent (Cursor, Claude Desktop, ChatGPT, Codex, etc.) everything it needs to start useful
work on a project in a single paste, drop-in, or MCP fetch.

This spec is intentionally small. A pack is plain text and plain JSON. No runtime, no
SDK, no custom file formats.

## Status

This specification is versioned. The current version is `0.1`. Breaking changes bump
the minor version until `1.0`, after which breaking changes require a major bump.

## Goals

1. **Agent-first.** Files are structured so an agent can parse them without guesswork.
2. **Source-traceable.** Every claim traces back to a cited source with a URL.
3. **Drop-in friendly.** `cursor.md` and `AGENTS.md` are placeable in a repo root.
4. **Deterministic.** Same inputs produce the same pack layout and frontmatter.
5. **Portable.** A pack is a folder. It can be zipped, committed, or served over HTTP.

## Non-goals

- Pack generation is not specified here. This is a format, not a builder.
- Pack consumption is not specified here. Agents read these files however they like.

## Layout

A Context Pack is a directory with the following files:

```
context-pack/
  pack.json
  cursor.md
  AGENTS.md
  skills.md
  sources.md
  prompts.md
  tasks.md
```

All files except `pack.json` are Markdown with YAML frontmatter. All files are UTF-8
encoded with LF line endings.

## pack.json (manifest)

The manifest is the only required file for a pack to be considered valid.

```json
{
  "spec_version": "0.1",
  "pack_id": "pk_01HXYZ...",
  "generated_at": "2026-04-24T14:22:03Z",
  "generator": {
    "name": "Skimless",
    "version": "0.1.0",
    "url": "https://skimless.com"
  },
  "project": {
    "name": "MCP server for Notion search",
    "description": "Build a local MCP server that indexes my Notion workspace and exposes search and fetch_page tools.",
    "stack": ["typescript", "node", "mcp-sdk"]
  },
  "user_prompt": "I'm building an MCP server that lets Cursor search my Notion workspace. Give me current best practices for MCP + Notion API.",
  "window": {
    "from": "2026-01-24T00:00:00Z",
    "to": "2026-04-24T14:22:03Z"
  },
  "files": [
    { "path": "cursor.md",  "sha256": "..." },
    { "path": "AGENTS.md",  "sha256": "..." },
    { "path": "skills.md",  "sha256": "..." },
    { "path": "sources.md", "sha256": "..." },
    { "path": "prompts.md", "sha256": "..." },
    { "path": "tasks.md",   "sha256": "..." }
  ],
  "sources": [
    {
      "id": "src_01HXYZ...",
      "url": "https://modelcontextprotocol.io/docs/concepts/servers",
      "title": "MCP Servers | Model Context Protocol",
      "kind": "docs",
      "published_at": "2026-03-11T00:00:00Z",
      "captured_at": "2026-04-22T09:04:11Z"
    }
  ]
}
```

### Field rules

- `spec_version`: SemVer string matching this document.
- `pack_id`: Opaque ULID or UUID. Unique per generation.
- `generated_at`: ISO-8601 UTC timestamp.
- `generator.name`: Free-form. `Skimless` when produced by Skimless.
- `project.name`: Short human label. Required.
- `project.description`: 1-3 sentence brief of intent. Required.
- `project.stack`: Array of free-form tokens. Optional.
- `user_prompt`: The exact chat prompt that triggered generation. Required when a
  prompt was used.
- `window.from` / `window.to`: The KB recency window considered. Optional but
  recommended.
- `files`: Array of paths relative to the pack root with a SHA-256 of the bytes.
- `sources`: Array of every cited source in the pack. Source `id` values are
  referenced by the `[^src_...]` footnote syntax in the other files.

## Frontmatter convention

Every Markdown file in a pack begins with a YAML frontmatter block:

```yaml
---
file: skills.md
pack_id: pk_01HXYZ...
spec_version: "0.1"
---
```

Agents should accept a file as valid pack content if and only if this frontmatter is
present and `pack_id` matches the manifest.

## cursor.md

Purpose: drop-in rules for Cursor. A copy can be placed at `.cursor/rules/skimless.md`
in any repo.

Structure:

```markdown
---
file: cursor.md
pack_id: pk_01HXYZ...
spec_version: "0.1"
---

# Project: {project.name}

## Summary
One paragraph.

## Stack
- bullet list

## Conventions
- bullet list

## Current focus
- bullet list of things the user is actively trying to do

## Don't
- bullet list of things to avoid (outdated APIs, deprecated patterns, etc.)

## Citations
Inline footnotes `[^src_...]` resolve against `sources.md`.
```

## AGENTS.md

Purpose: generic agent instructions, portable across Claude Code, Codex, Cursor, etc.
Follows the emerging community convention of a repo-root `AGENTS.md`.

Structure mirrors `cursor.md` but is phrased generically (no Cursor-specific language).

## skills.md

Purpose: relevant techniques, patterns, and APIs extracted from the knowledge base.

Each skill is a `##` section:

```markdown
## Streaming MCP responses with progress tokens
Context: When building MCP tools that take >2s, emit progress updates via the
progress token so clients can render a loader.

Pattern:
- Accept `progressToken` from the request
- Call `server.notifyProgress(token, 0.5, "halfway")` periodically
- Omit when `progressToken` is absent

Sources: [^src_01HXYZA], [^src_01HXYZB]
```

A pack should include 3-12 skills. More is noise.

## sources.md

Purpose: canonical bibliography. Every footnote in every other file resolves here.

```markdown
## [^src_01HXYZA]
- Title: MCP Servers | Model Context Protocol
- URL: https://modelcontextprotocol.io/docs/concepts/servers
- Kind: docs
- Published: 2026-03-11
- Captured: 2026-04-22
- Summary: 2-4 sentence summary of the source and why it matters for this pack.
- Key claims:
  - Claim 1 (short)
  - Claim 2 (short)
```

## prompts.md

Purpose: ready-to-use prompts for the project. These are meant to be pasted as-is
into Cursor, Claude, or ChatGPT.

```markdown
## Scaffold an MCP server in TypeScript
```text
You are an expert TypeScript engineer. Scaffold an MCP server using
@modelcontextprotocol/sdk that exposes the tools listed in tasks.md.
Follow the conventions in cursor.md. Cite source footnotes when making
technology choices.
```
Sources: [^src_01HXYZA]
```

A pack should include 3-8 prompts.

## tasks.md

Purpose: suggested implementation tasks, ordered by dependency.

```markdown
## 1. Set up project skeleton
- Initialize npm, add `@modelcontextprotocol/sdk`.
- Create `src/server.ts` with an empty MCP server.
- Acceptance: `npm run dev` starts without errors.

## 2. Implement `search_notion` tool
...
```

Each task has a checkable title (`## N. ...`), a bulleted body, and an
`Acceptance:` line. Dependencies between tasks are implicit via order.

## Validation

A pack is valid when:

1. `pack.json` parses as JSON and passes the schema above.
2. Every file listed in `pack.json.files` exists and its SHA-256 matches.
3. Every `[^src_...]` reference in any Markdown file resolves to a `sources.md`
   entry and to a `pack.json.sources[].id`.
4. `spec_version` in every file matches `pack.json.spec_version`.

A simple validator is planned: `npx @skimless/pack-validate ./context-pack`.

## Distribution formats

- **Directory**: the canonical form.
- **ZIP**: `context-pack.zip` with the directory as its root.
- **HTTP**: served behind a signed URL. `GET /packs/{id}/pack.json` etc.
- **MCP**: exposed as a resource by an MCP server (see the `generate_pack` tool).

## Versioning

This document lives at `docs/context-pack-spec.md` in the Skimless repo and is
mirrored to a dedicated public repository. Changes are announced in the changelog.

## License

CC0. Use this spec freely. Skimless does not claim ownership of the format;
the goal is a small, open convention that more tools can target.
