They Quietly Killed Package Install. So I added it back in Mockingbird.
If you've been doing Sitecore long enough, you've installed a package. Probably hundreds. You built a .zip in the Package Designer, handed it to a teammate or a deployment step, opened the Installation Wizard, clicked through, and watched items land in the target database. It wasn't glamorous. It was reliable. And for the better part of two decades, it was the default, boring, everybody-knows-it way to move content and items between Sitecore environments.
And then one day, it just went away.
A moment of silence for the Installation Wizard
Now, XM Cloud SitecoreAI has been around a while, and package install came right along with it - the Installation Wizard, still there, still working, same as it ever was. Then, a few weeks ago, quietly, it wasn't. This wasn't some casualty of a years-ago migration. It's a tool that survived the whole move to the cloud just fine, and then got pulled out from under us the other day.
There was no long deprecation runway, no "here's your migration path, you have 18 months" grace period that I ever caught wind of. One day package install was the answer to "how do I get these items over there," and the next it wasn't part of the platform. The official replacement was, roughly, "here's an API, go build your own content movement." Which is a fine thing to offer and a rough thing to lead with when you've just removed the tool everyone was already using.
I get why, mostly. The CM isn't yours to poke at anymore; it's a managed thing in the cloud, and a "upload this arbitrary zip and let it write to the database" endpoint is exactly the kind of surface a managed platform wants to close. Fine. But the need didn't go away just because the button did. We still have to move items and content between places.
Env-to-env is a solved problem (mostly)
To be fair, Sitecore didn't leave the whole problem unsolved. Moving content between environments that already live in SitecoreAI - prod down to UAT, UAT down to dev - is handled. The Content Transfer API exists for exactly that, and it works well. I liked it enough that I built a little browser tool on top of it, called Rift, to make environment-to-environment transfers a point-and-click affair instead of a scripting exercise.
So if your problem is "copy today's prod content into UAT for QA," you're covered. Rift, the Content Transfer API, or the dotnet sitecore ser CLI - pick your poison, they all move content between live SitecoreAI environments just fine.
The hole is somewhere else.
The gap nobody filled: local to SitecoreAI
Here's the workflow that fell through the cracks.
You're doing feature development locally. Maybe you're using Mockingbird as your local content layer (I hope you are), authoring new templates, renderings, and content against your repo's serialized YAML, with clean git diffs and no Windows-container CM in sight. Life is good.
Now you need to get that work up into a real SitecoreAI environment. Your new datasource items, your new page, that media asset. Up to dev so a teammate can see it, or up to an integration environment so the pipeline can pick it up.
The Content Transfer API doesn't help you here - it moves content between SitecoreAI environments, and your laptop is not a SitecoreAI environment. Rift can't help either, and I'll come back to why in a minute. You can wrestle dotnet sitecore ser push into shape, and I've written about scripting exactly that, but it's the CLI, from a folder, with its own scoping config, from outside the tool you were just happily working in.
What I actually wanted was the spirit of the old package install, pointed the right direction: select some items, pick a target, send them up. From the same tree I'm already looking at.
Deploy to SitecoreAI
So that's what Mockingbird does now, as of the 0.16 release.
Mockingbird can push items and media from your local workspace straight up to a live SitecoreAI environment. GUID-preserving, so references don't shatter on the way. Right out of the same content tree you're already authoring against.
There are three ways in, depending on where you are when the urge strikes:
- Right-click an item in the tree and choose Deploy to SitecoreAI... - the surgical, "just this subtree" path.
- The package cart drawer - if you've been collecting items into a package, there's a Deploy to SitecoreAI button right there.
- The package builder checkout - build your selection, deploy it, same flow.
All three converge on the same deploy dialog.
Pick your target environment, and Mockingbird previews the plan before it writes a single thing. It evaluates your selection against the target and tells you exactly what's about to happen - something like "3 create, 0 update, 166 skip" - with a live "Evaluating X of N items" progress bar while it works through the list. No surprises. You see the shape of the deploy, then you pull the trigger.
Hit deploy, and it streams the write back to you with its own progress bar. That's the whole loop. Author locally, preview, deploy up.
The interesting part: two APIs doing the work
Under the hood, this leans on the pieces of the platform Sitecore did leave us - just not the ones you'd reach for env-to-env.
Preview uses the Authoring API. For each item in your selection, Mockingbird asks the target a simple question via an item(where: { itemId, database }) probe: "do you already have this?" That's how it sorts every item into create (net-new), update (already there), or skip (identical). The whole "3 create, 0 update, 166 skip" summary is just that probe, run across your selection.
The write uses the Management API. Specifically the executeSerializationCommands mutation - the same serialization machinery that dotnet sitecore ser push rides. Mockingbird maps your items into serialize commands, batches them, and sends them up. Media rides along too: blobs are inlined as base64 in the payload, GUIDs preserved, so a freshly-deployed image is still the same image everything else references.
Auth is per-environment. Each environment you define carries its own automation-client credentials - a client id and secret. Mockingbird exchanges those for a short-lived (24-hour) JWT against auth.sitecorecloud.io/oauth/token (audience api.sitecorecloud.io), and uses that token for the calls. Standard SitecoreAI automation-client stuff; nothing exotic.
Why this lives in Mockingbird and not Rift
Reasonable question: I already had Rift, a browser tool that talks to SitecoreAI. Why not just add "deploy from local" there?
Because Rift is a browser app, and this feature needs to hold client ids and secrets and call the Authoring and Management APIs with them. Storing automation-client secrets in a browser is a genuinely bad idea - secrets sitting in browser storage, CORS gymnastics to reach the endpoints, the whole thing one screenshot away from an incident. I could have forced it. It would have required some hacky af decisions I didn't want my name on.
Mockingbird, on the other hand, is a local server. The secrets live on your own filesystem, the API calls happen server-side, and the browser never touches a credential. The feature has a natural home, and it turns out the natural home is the tool that's already sitting between your repo and your rendering host. Rift keeps doing what it's good at (environment-to-environment over the Content Transfer API); Mockingbird owns the local-to-cloud direction. Right tool, right job.
Where the credentials actually live
If you've read my other Mockingbird posts, you know I'm a stickler about what's committed and what isn't. Deploy follows the same two-file discipline:
- Environment definitions live in
config.mockingbird.environmentsat your workspace root. Name, CM host, that sort of thing. This is team-shared - commit it, and the next dev who clones the repo gets your whole environment list for free. - Secrets - the client id and secret for each environment - live in
.environments.local, which is gitignored, per developer. Your credentials are yours. They never ride in git, and they're kept in a separate file specifically so that when the shared config gets rewritten, it can't clobber them.
So the team shares which environments exist; each developer supplies their own keys to them. Exactly the split you want.
A word on pointing this at production
This writes to live SitecoreAI. That's the whole point, and it's also the part that deserves a little respect. You define the environments, so define them thoughtfully - the same way I keep an AllowWrite = $false on prod in my content-sync script. The server also enforces a blocking-template check on the way in, so the most obvious mistakes are caught. But the durable safety rail is the one between your chair and your keyboard: know which environment you picked before you hit deploy.
TL;DR
- Package install - the default "move items between environments" tool for ~20 years - was quietly removed a few weeks ago (not in some years-old cloud migration; it survived that just fine), replaced with "here's an API, go build it yourself."
- Environment-to-environment transfer inside SitecoreAI is fine (Content Transfer API, and my Rift tool on top of it). The gap was local to SitecoreAI.
- Mockingbird 0.16 fills it: select items + media, preview a create/update/skip plan, deploy straight up to a live environment, GUID-preserving.
- Preview runs on the Authoring API; the write runs on the Management API (
executeSerializationCommands). Per-environment automation credentials, short-lived JWTs. - It lives in Mockingbird (a local server) instead of Rift (a browser app) because secrets belong on your filesystem, not in browser storage.
- Environment definitions are team-shared (
config.mockingbird.environments, commit it); secrets are per-dev and gitignored (.environments.local).
The road ahead
Mockingbird is an experiment I keep poking at, not a Sitecore-supported product - bug reports, "wait you did WHAT" reactions, and feature ideas are all welcome over at github.com/project-mockingbird/mockingbird/issues.
Grab the latest image, define an environment, and send some items up. Package install may be gone, but getting your local work back into the cloud doesn't have to be.
Happy Sitecore trails, my friend!