> ## Documentation Index
> Fetch the complete documentation index at: https://docs.metabind.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Sync Your First Project

> Pull a Metabind project to disk, make an edit in your own editor, and publish it with the CLI

In this tutorial, you'll pull an existing Metabind project to disk as files, edit one in your own editor, and send the change back: first as a draft you can inspect, then as a published release. By the end, you'll have run the flat-file loop once and know which step is safe to repeat and which one goes live.

Once the loop makes sense, the [flat-file sync guide](/cli/flat-file-sync) covers what this tutorial skips: conflicts, renames, and repairing local state.

## Prerequisites

<Note>
  Before you start, make sure you have:

  * The Metabind CLI installed and signed in. See [Install and Sign In](/cli/install). The CLI ships as a macOS binary through the Homebrew tap, with no Windows or Linux build and no `npx` form yet.
  * A project you can edit with at least one published UI tool, saved as your active context with `metabind use`. Run `metabind status` to confirm which project you're pointed at.
  * Any text editor. This tutorial changes one line of text in a BindJS component, but you don't need to know BindJS to finish it.
</Note>

## What You'll Build

You'll change one line of text in the component a UI tool renders, then publish that edit. Until you publish, the tool keeps serving its published version. The focus is the loop itself:

**Pull → edit → preview → push → publish.** `pull` and the preview write nothing you can't discard. `push` writes the component change as a draft. `publish` is the step that makes it live.

## Pull Before You Push

`push` reads a baseline that `pull` records in `.metabind/state.json` to tell your edits apart from server-side changes. **You have to `pull` a project before you can `push` it.** Run `push` in a directory you never pulled, and it stops before doing anything:

```text theme={null}
No .metabind/state.json under <dir>. Run metabind pull first
```

The loop always starts with a pull.

<Steps>
  <Step title="Pull the Project Into a Folder">
    Write the project to a new directory. `pull` is read-only: it fetches the files and records the baseline `push` needs later.

    ```bash theme={null}
    metabind pull --out ./my-project
    ```

    You now have a folder of files: `metabind.jsonc` for project settings, `components/` for BindJS source, `tools/` for tool definitions, a CLI-owned `.metabind/` directory holding the baseline, and `mcp-instructions.md` and `content/` if the project has instructions or content. Secret *values* are never written, only their names. For the full layout, see the [flat-file sync guide](/cli/flat-file-sync#project-layout).
  </Step>

  <Step title="Change One File">
    Open one of the files under `tools/view/` or `tools/layout/` in the folder you pulled. Its `rootComponent` field names the component that tool renders. Open that component's file under `components/` and change one piece of text it displays, such as a label or a heading.

    Save the file. This is an ordinary edit, detected by content rather than timestamp, so a file you didn't touch never registers as changed.
  </Step>

  <Step title="Preview What Would Change">
    Before writing anything back, preview the change. `push --plan` reports the changelist and exits without touching the server.

    ```bash theme={null}
    metabind push --plan --out ./my-project
    ```

    You should see the component file marked as updated and everything else unchanged. `--plan` never writes, so you can rerun it as often as needed.
  </Step>

  <Step title="Push the Change as a Draft">
    Apply the edit. `push` writes the component to the server as a draft, so nothing your published MCP app serves changes yet.

    ```bash theme={null}
    metabind push --out ./my-project
    ```

    If someone edited the same entity in Studio since you pulled, `push` refuses the whole batch rather than merging, so follow [Resolving Conflicts](/cli/flat-file-sync#resolving-conflicts) to reconcile it. It also stops before sending anything if an edit looks like it holds a secret value, so keep secrets in project secret bindings and reference them by name instead.
  </Step>

  <Step title="Publish the Release">
    Promote the draft to published. This is the step that changes what your live app serves: the same release action as publishing from Studio.

    ```bash theme={null}
    metabind publish
    ```

    If you only wanted to try the loop, stop before this step. The draft stays on the server, unpublished, until the project is next published.
  </Step>
</Steps>

## Verify It Works

Run the preview again from the same folder:

```bash theme={null}
metabind push --plan --out ./my-project
```

With your edit pushed and nothing else changed, it should report no changes to make. If you published, it also lists your published tools as behind the server, because publishing moved them to the new package version; run `metabind pull --out ./my-project` to pick that up. You can also open the project to see the change:

```bash theme={null}
metabind open
```

## What You've Built

You've run the full flat-file loop once: you pulled a project to disk, edited it in your own editor, previewed the change, pushed it as a draft, and published it. Two rules keep the loop safe: `pull` establishes the baseline `push` depends on, and `push` writes component changes as drafts, so `publish` is the deliberate step that makes them live.

## Next Steps

<CardGroup cols={2}>
  <Card title="Flat-File Sync" icon="folder-tree" href="/cli/flat-file-sync">
    The full workflow: project layout, conflicts, renames, and repairing local state.
  </Card>

  <Card title="CI Publish Lane" icon="github" href="/cli/ci-publish">
    Automate the push step with GitHub Actions, then publish separately.
  </Card>

  <Card title="Workflow Map" icon="list-tree" href="/cli/verbs">
    Every CLI command family, grouped by the job it does.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.