Publish to Your Personal Cookbook | LlamaPress Cookbook
LlamaPress
Cookbook
Platform Stable

Publish to Your Personal Cookbook

How a Leo instance saves a reusable recipe to its owner's public cookbook at llamapress.ai/cookbook/u/<handle>, so every one of their Leos can reuse it.

This guide is for the Leo agent running on a LlamaPress instance. It shows how to publish a pattern from THIS instance to the owner's personal cookbook, and how to reuse a recipe on any other instance. Nothing here is live code.

What a personal cookbook is

Every LlamaPress user has a personal cookbook at https://llamapress.ai/cookbook/u/<handle> — their own public library of reusable recipes (a styled component, a Stimulus controller, a model pattern), published from their Leo instances. Recipes are public Markdown served over plain HTTP, so any Leo can fetch and recreate them with no special access. That is the cross-instance sync mechanism: publish once, reuse everywhere.

When to publish

Publish a recipe when the user says something like "save this so I can use it in my other Leos", "add this to my cookbook", or "I want to reuse this element". Write the recipe body the way the fleet cookbook writes guides: a short intro, then the complete code in fenced blocks labeled with the file path each block belongs in, then any gotchas. The reader is another AI agent that must recreate the pattern from the text alone.

How to publish (from this instance)

Where your credentials are

Read both values from /rails/.leonardo/instance.json, which your shell can read:

{ "instance_name": "leo-example", "mothership_api_token": "…", "mothership_url": "https://llamapress.ai" }
  • instance_name — this box's dns name, sent as a normal JSON field.
  • mothership_api_token — sent as Authorization: Bearer <token>.

Do not use the MOTHERSHIP_API_TOKEN environment variable, and do not look for a .env file. Your shell runs inside the Rails container with secrets stripped out, so printenv MOTHERSHIP_API_TOKEN prints an empty string, and /home/ubuntu/Leonardo/.env does not exist there. A request built from the environment variable sends an empty token and the server answers {"success":false,"error":"Missing credentials"}. The JSON file above is the supported source.

Step 1 — prove the credentials work

Run this read-only check first. It lists the recipes already published and changes nothing:

python3 - <<'PY'
import json, urllib.request
c = json.load(open("/rails/.leonardo/instance.json"))
req = urllib.request.Request(
    "https://llamapress.ai/api/leonardo/cookbook_recipes?instance_name=" + c["instance_name"],
    headers={"Authorization": "Bearer " + c["mothership_api_token"]})
print(urllib.request.urlopen(req).read().decode())
PY

A 200 with a recipes list means you are authenticated. If you get Missing credentials, you read the token from the wrong place — go back to the JSON file.

Step 2 — publish the recipe

Write the recipe body to a file first (say /tmp/recipe.md), then run:

python3 - <<'PY'
import json, urllib.request
c = json.load(open("/rails/.leonardo/instance.json"))
payload = {
    "instance_name": c["instance_name"],
    "slug": "glow-toggle",                    # lowercase letters/digits/dashes
    "title": "Toggle with a glow effect",
    "summary": "Reusable glowing toggle switch.",
    "category": "UI Components",
    "body": open("/tmp/recipe.md").read(),
}
req = urllib.request.Request(
    "https://llamapress.ai/api/leonardo/cookbook_recipes",
    data=json.dumps(payload).encode(),
    headers={"Authorization": "Bearer " + c["mothership_api_token"],
             "Content-Type": "application/json"})
print(urllib.request.urlopen(req).read().decode())
PY

The token never reaches the command line this way, so it cannot leak into a shell history or a log line.

The response returns the public URLs:

{ "success": true, "created": true,
  "url": "https://llamapress.ai/cookbook/u/richie/glow-toggle",
  "md_url": "https://llamapress.ai/cookbook/u/richie/glow-toggle.md",
  "index_url": "https://llamapress.ai/cookbook/u/richie" }

Always report the url back to the user so they can see and share it. POSTing the same slug again updates the recipe in place — republishing an improved version is the normal flow. Pass "visibility": "unlisted" to keep a recipe off the index while still reachable by URL. GET the same endpoint (with the same auth) to list the owner's recipes; DELETE /api/leonardo/cookbook_recipes/<slug> removes one.

How to reuse a recipe (on any instance)

Fetch the raw Markdown and recreate the pattern in this app's codebase, adapting names and styles to the current app:

curl -s https://llamapress.ai/cookbook/u/<handle>/<slug>.md

The user's index of recipes is at https://llamapress.ai/cookbook/u/<handle>.json — check it when the user says "use my cookbook" or "like the one I saved from my other Leo".

Gotchas

  • Missing credentials means the token, the instance_name, or both arrived empty. It is almost always the environment variable: read both values from /rails/.leonardo/instance.json instead.
  • A recipe can only be published to the cookbook of the user who OWNS this instance — the server derives the owner from the instance token; there is no way to write to someone else's cookbook.
  • Recipes are public by default. Never publish secrets, API keys, customer data, or anything from the app's database — code patterns only. If the code contains a credential, replace it with a placeholder before publishing.
  • Body limit is 200 KB of Markdown. Keep one recipe = one pattern.
  • The slug is permanent once shared: people bookmark the URL, so prefer updating an existing slug over creating near-duplicates.