# Initialize a project

> Run `ok init` to scaffold `.ok/`, initialize git, install project and user skills, and register MCP entries for detected editors (Claude Code, Cursor, Codex).

- Repository: sashimikun/open-knowledge
- GitHub: https://github.com/sashimikun/open-knowledge
- Human docs: https://grok-wiki.com/public/docs/sashimikun-open-knowledge-5c45105c876e
- Complete Markdown: https://grok-wiki.com/public/docs/sashimikun-open-knowledge-5c45105c876e/llms-full.txt

## Source Files

- `packages/cli/src/commands/init.ts`
- `packages/server/src/init-project.ts`
- `packages/cli/src/integrations/write-project-skill.ts`
- `packages/cli/src/commands/editors.ts`
- `packages/cli/src/commands/seed.ts`
- `packages/cli/src/sharing/git-exclude.ts`

---

---
title: "Initialize a project"
description: "Run `ok init` to scaffold `.ok/`, initialize git, install project and user skills, and register MCP entries for detected editors (Claude Code, Cursor, Codex)."
---

`ok init` is the one-shot bootstrap command that turns any directory into an Open Knowledge project. It resolves the project root, scaffolds `.ok/` and `.okignore`, initializes git when needed, registers the `open-knowledge` MCP server in detected agent editors, installs bundled skills at both project and user scope, and optionally configures config-sharing posture. The command is idempotent: re-running updates MCP entries and merges missing `.ok/.gitignore` lines without destroying existing configuration.

## Prerequisites

Before running `ok init`, ensure the following are available on the machine:

| Requirement | Why |
| --- | --- |
| [Installation](/installation) of `@inkeep/open-knowledge` or OK Desktop | Provides the `ok` CLI and bundled skill assets |
| `git` on `PATH` | Required to initialize a parent repo when none exists |
| At least one supported editor config directory | MCP registration skips editors whose config root is absent |
| Network access (first run) | User-global skill install invokes `npx skills@~1.5.0` |

Supported editors: **Claude** (Claude Code), **Claude Desktop**, **Cursor**, and **Codex**. Init detects installed editors by probing each editor's config directory; editors without a detectable config root are skipped with `skipped-missing`.

## Quick start

<Steps>
<Step title="Navigate to your project directory">

```bash
cd /path/to/my-knowledge-base
```

Init uses the current working directory unless you pass `--cwd` through a parent command.

</Step>
<Step title="Run init">

```bash
ok init
```

On an interactive terminal, init prompts for MCP scope (user-level, project-level, or both) and sharing mode (shared vs local-only). Non-interactive runs default MCP scope to `both` and sharing mode to `shared` (or preserve an existing local-only posture).

</Step>
<Step title="Verify scaffold and editor wiring">

Confirm these artifacts exist:

- `.ok/config.yml` — project marker (required for `ok seed` and server commands)
- `.ok/.gitignore` — excludes machine-local runtime files under `.ok/local/`
- `.okignore` — document-index exclusions (gitignore syntax)
- Editor MCP entries showing `registered` or `updated` in the command output

</Step>
<Step title="Approve MCP in your editor">

Open a configured editor, approve the `open-knowledge` MCP server when prompted, and run a simple tool call (for example, `exec` with `pwd`) to confirm connectivity.

</Step>
</Steps>

## What init creates

Init does **not** scaffold content folders (`articles/`, `research/`, etc.) or starter templates. Those come from a separate `ok seed` step. Init only lays down project infrastructure and editor integration.

:::files
my-project/
├── .git/                          # created if absent (branch: main)
├── .gitignore                     # seeded on fresh git init (.DS_Store)
├── .okignore                      # index-exclusion template
├── .ok/
│   ├── config.yml                 # commented defaults + JSON Schema pointer
│   └── .gitignore                 # ignores .ok/local/, locks, PII sidecars
├── .mcp.json                      # project MCP (Claude Code), if scope includes project
├── .cursor/
│   ├── mcp.json                   # project MCP (Cursor), if scope includes project
│   └── skills/open-knowledge/     # project skill bundle
├── .claude/
│   ├── launch.json                # UI preview server (Claude Code only)
│   └── skills/open-knowledge/     # project skill bundle
├── .codex/
│   └── config.toml                # project MCP (Codex), if scope includes project
└── .agents/skills/open-knowledge/ # project skill bundle (Codex)
:::

### `.ok/config.yml`

The scaffolded config is entirely commented defaults with a `$schema` URL pointing at the published JSON Schema. No keys are active until uncommented. The file serves as the project marker (`OK_PROJECT_MARKER` = `.ok/config.yml`); commands like `ok seed` refuse to run without it.

### `.ok/.gitignore`

Auto-ignores machine-local runtime artifacts:

- `.ok/local/` (caches, locks, manifests)
- `principal.json`, `state.json`, `server.lock`, `ui.lock`, `sync-state.json`, `last-spawn-error.log`

Only `config.yml` at the `.ok/` root is intended for version control.

### `.okignore`

A commented template for paths excluded from the Open Knowledge document index. Patterns use gitignore syntax and combine with `.gitignore` via a single ignore-lib instance.

## Init pipeline

```mermaid
sequenceDiagram
    participant User
    participant CLI as ok init
    participant Root as resolveProjectRoot
    participant Git as ensureProjectGit
    participant Content as initContent
    participant MCP as writeEditorMcpConfig
    participant Skills as writeProjectSkill / installUserSkill
    participant Share as applySharingMode

    User->>CLI: ok init
    CLI->>Root: resolve project root
    Root-->>CLI: projectRoot, promotion flags
    CLI->>Git: ensureProjectGit(projectRoot)
    Git-->>CLI: didInit
    CLI->>Content: initContent(projectRoot)
    Content-->>CLI: created / updated / skipped
    CLI->>MCP: register per editor + scope
    MCP-->>CLI: written / overwritten / skipped
    CLI->>Skills: project skills + user-global skill
    Skills-->>CLI: installed / skip-current / failed
    CLI->>Share: applySharingMode
    Share-->>CLI: shared / local-only outcome
    CLI-->>User: formatted summary + preview
```

### Project root resolution

Before scaffolding, `resolveProjectRoot` walks ancestors (up to 30 levels) looking for an existing `.ok/config.yml`. If found, init opens that ancestor project instead of creating a nested one.

If no ancestor project exists and the cwd sits inside a git working tree below the home directory, init promotes to the git root. A message explains the promotion:

```
[ok] Initialized OK at <git-root> — opened parent of <subdir> because it contains a .git folder
```

Otherwise, init uses the realpath of the current directory as `projectRoot`.

## Git initialization

`ensureProjectGit` runs before content scaffolding:

| Condition | Behavior |
| --- | --- |
| No `.git/` and not inside an existing work tree | Runs `git init --initial-branch=main` |
| Valid `.git/HEAD` present | Skips init (`didGitInit: false`) |
| Partial `.git/` missing `HEAD` | Repairs via `git init` |
| Inside an existing work tree (subdirectory of a repo) | Skips init |

On a fresh `git init`, init also seeds a root `.gitignore` with `.DS_Store` when none exists.

If `git init` fails (git not installed, permission error), init exits with code 1 and prints:

```
open-knowledge requires git to initialize a parent repo. Install git or run 'git init' yourself, then re-run.
```

## MCP server registration

By default, MCP registration is enabled (`--mcp` defaults to `true`). Pass `--no-mcp` to scaffold `.ok/` only.

### Detected editors and config paths

| Editor | User-level config | Project-level config | MCP key |
| --- | --- | --- | --- |
| Claude (Code) | `~/.claude.json` | `.mcp.json` | `mcpServers` |
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) | — | `mcpServers` |
| Cursor | `~/.cursor/mcp.json` | `.cursor/mcp.json` | `mcpServers` |
| Codex | `~/.codex/config.toml` (or `$CODEX_HOME/config.toml`) | `.codex/config.toml` | `mcp_servers` |

All editors register the server name `open-knowledge`.

### MCP entry format

Published mode (default) writes a shell chain entry that resolves the CLI in order: OK Desktop user bundle → system bundle → `npx @inkeep/open-knowledge@latest mcp` → common Node install paths.

<RequestExample>

```json title="Claude Code MCP entry (published)"
{
  "command": "/bin/sh",
  "args": ["-l", "-c", "# ok-mcp-v1\n...chain resolves to ok mcp..."]
}
```

</RequestExample>

Dev mode (`--dev-mcp`) replaces the chain with a direct `node packages/cli/dist/cli.mjs mcp` invocation and sets `MCP_DEBUG=1` plus `OK_LOG_FILE=/tmp/ok-mcp.log`. Intended for contributors running the local CLI from the monorepo.

### MCP scope

<ParamField body="--scope" type="user | project | both">
Controls where MCP config is written. Default on TTY: interactive checkbox (both checked). Default non-TTY: `both`.

- `user` — writes only to home-directory editor configs
- `project` — writes only to project-local configs (`.mcp.json`, `.cursor/mcp.json`, `.codex/config.toml`)
- `both` — writes to both levels
</ParamField>

Claude Desktop does not support project-level MCP config; when project scope is selected, init reports that Claude Desktop was skipped for project-level registration.

### Claude Code launch.json

When Claude is detected and MCP is enabled, init also creates or merges `.claude/launch.json` with an `open-knowledge-ui` configuration. This wires Claude Code Desktop's embedded browser to start the OK web editor via a published shell chain (`ok start --ui-port`).

### MCP overwrite semantics

Init **replaces** the entire `open-knowledge` MCP entry on each run. Custom fields (`cwd`, `env`, alternate commands) on a prior entry are not merged — they are overwritten with the managed chain. Other MCP servers in the same config file are preserved.

## Skill installation

Init installs skills at two scopes. Skill packs are bundled file assets copied from the CLI package — they are provider-neutral and work with any MCP-connected agent host.

### Project-local skills

For every editor that defines a `projectSkillPath`, init copies the bundled **project** skill directory:

| Editor | Project skill path |
| --- | --- |
| Claude | `.claude/skills/open-knowledge/SKILL.md` |
| Cursor | `.cursor/skills/open-knowledge/SKILL.md` |
| Codex | `.agents/skills/open-knowledge/SKILL.md` |

Existing skill directories are removed and replaced (overwrite semantics). Writes are guarded against symlink escape outside the project root.

### User-global skill

`installUserSkill` runs on every init via `npx skills@~1.5.0 add <discovery-bundle> --agent '*' -g -y --copy`. This installs the **discovery** skill bundle to `~/.agents/skills/open-knowledge-discovery` across detected agent hosts.

| Outcome | Meaning |
| --- | --- |
| `installed` | Fresh install at current package version |
| `skip-current` | Already at current version with files present |
| `failed` | `npx` unavailable, timeout, or subprocess error — MCP config still written |

On failure, init prints a manual recovery command. MCP registration is independent of skill install success.

If Claude Desktop is detected, init suggests running `ok install-skill` separately for Claude Chat and Cowork (a `.skill` zip handoff, not part of the standard init path).

## Config sharing mode

Init configures whether OK artifacts are committed with project content or kept per-clone via `.git/info/exclude`.

<Tabs>
<Tab title="Shared (default)">

OK config files (`.ok/`, `.mcp.json`, project skills, `.claude/launch.json`, `.okignore`) are intended for version control. Teammates inherit the same MCP and skill setup on clone.

```bash
ok init --shared
```

</Tab>
<Tab title="Local only">

OK artifacts are appended to `.git/info/exclude` — a per-clone, uncommitted file. Teammates do not see your OK wiring.

```bash
ok init --local-only
```

Switch back later with `ok config-sharing share`.

</Tab>
</Tabs>

### Artifacts managed by sharing mode

The exclude list covers:

- `.ok/`
- `.okignore`
- `.mcp.json`
- `.cursor/mcp.json` and `.cursor/skills/open-knowledge/`
- `.claude/skills/open-knowledge/` and `.claude/launch.json`
- `.codex/config.toml`
- `.agents/skills/open-knowledge/`

### Sharing failure modes

| Situation | Behavior |
| --- | --- |
| `--local-only` but no git repo | Option ignored; warning printed |
| `--local-only` but OK files already tracked upstream | Refused with `git rm --cached` remediation steps; init still exits 0 |
| Re-run without flags on local-only repo | Preserves local-only posture |
| Explicit `--shared` after local-only | Removes OK paths from exclude file |

## CLI flags reference

<ParamField body="--mcp" type="boolean" default="true">
Register the MCP server for detected editors.
</ParamField>

<ParamField body="--no-mcp" type="boolean">
Scaffold `.ok/` only. Skips all MCP config, launch.json, and editor registration. Project skills are still written.
</ParamField>

<ParamField body="--dev-mcp" type="boolean">
Register a local dev MCP entry using `node packages/cli/dist/cli.mjs mcp` with debug logging. For monorepo contributors.
</ParamField>

<ParamField body="--scope" type="user | project | both">
Non-interactive MCP scope selection. Conflicts with TTY checkbox prompt when omitted on a terminal.
</ParamField>

<ParamField body="--shared" type="boolean">
Commit OK config alongside content. Default for fresh repos. Conflicts with `--local-only`.
</ParamField>

<ParamField body="--local-only" type="boolean">
Keep OK config out of git via `.git/info/exclude`. Conflicts with `--shared`.
</ParamField>

## Exit codes and output

| Exit code | Condition |
| --- | --- |
| `0` | Success, or partial success (e.g., sharing refusal, skill install failure without MCP failure) |
| `1` | Any editor MCP write failed, or `ProjectGitInitError` |

The formatted output includes:

- Git init status and `.gitignore` seed confirmation
- Content scaffold summary (`Created` / `Updated` / `Skipped`)
- Per-editor MCP registration status with relative config paths
- Project-local skill install status
- User-global skill install status
- Sharing mode outcome
- Content preview block (when preview loads successfully)
- Next-steps checklist when at least one MCP entry was written

## Idempotent re-runs

Re-running `ok init` on an initialized project is safe:

- `.ok/config.yml` and `.okignore` are not overwritten if they already exist
- `.ok/.gitignore` gains any missing required lines
- MCP entries for `open-knowledge` are refreshed to the current managed chain
- Project skills are replaced with the latest bundled version
- User-global skill skips install when version matches and files exist
- Sharing posture is preserved unless an explicit `--shared` or `--local-only` flag overrides

Init does **not** start the collaboration server, index documents, or create starter content.

## What comes after init

<AccordionGroup>
<Accordion title="Scaffold starter content">

```bash
ok seed              # Karpathy three-layer knowledge base (default pack)
ok seed --list-packs # see all starter packs
```

`ok seed` requires `.ok/config.yml` from init. Without it, seed exits with a prerequisite error.

</Accordion>
<Accordion title="Start the editor">

```bash
ok start --open
```

See [Quickstart](/quickstart) for the full first-edit path.

</Accordion>
<Accordion title="Repair stale editor wiring">

If MCP or skills drift after an upgrade:

```bash
ok repair-skills
```

Or re-run `ok init` to refresh MCP entries and project skills.

</Accordion>
</AccordionGroup>

## Troubleshooting

| Symptom | Likely cause | Fix |
| --- | --- | --- |
| `No supported editor config directories detected` | No editor installed or config dir missing | Install an editor, create its config directory, re-run `ok init` |
| `git init failed` | Git not installed | Install git or run `git init` manually, then re-run |
| `open-knowledge install failed` | `npx` unavailable or network error | Run the manual `npx skills@~1.5.0 add ...` command from output |
| `Content scaffolding failed` | Symlink at `.ok/` or permission error | Remove untrusted symlinks, check write permissions |
| `Refusing to write through a symbolic link` | Symlink in project skill path | Remove the symlink, re-run |
| MCP `FAILED` for one editor | Corrupt or locked config file | Fix JSON/TOML syntax or remove stale lock file, re-run |
| `--local-only` ignored | No git repo at project root | Run `git init`, then `ok config-sharing unshare` |
| Sharing switch refused | OK files already tracked in git | Follow `git rm --cached` remediation in output |

For deeper diagnostics, see [Troubleshooting](/troubleshooting).

## Related pages

<Card href="/quickstart" title="Quickstart" icon="rocket">
Run `ok init`, `ok start --open`, and verify MCP tools respond from a connected agent.
</Card>

<Card href="/project-scaffold" title="Project scaffold" icon="folder-tree">
`.ok/` directory layout, config scopes, `.okignore`, and `content.dir` semantics.
</Card>

<Card href="/wire-agent-editors" title="Wire agent editors" icon="plug">
MCP registration details, bundled skills, `ok repair-skills`, and verification prompts.
</Card>

<Card href="/cli-reference" title="CLI reference" icon="terminal">
All `ok` subcommands, global flags, and server management commands.
</Card>

<Card href="/configuration-reference" title="Configuration reference" icon="settings">
YAML config keys, precedence order, and published JSON Schema paths.
</Card>
