# Lockedin.me: instructions for AI assistants

Lockedin.me (https://lockedin.me) publishes a person's link-in-bio page at lockedin.me/{handle}. A person can let an AI assistant manage that page through a free MCP server or REST API. This file has two parts:

1. **The instruction block** (section A). Paste it into the assistant's system prompt, custom instructions, project instructions, a custom GPT's Instructions box, or a CLAUDE.md / AGENTS.md / .cursorrules file. It tells the assistant how to work on a page safely.
2. **Setup for each assistant** (section B): the exact command or config that connects it, with the person's key.

The complete reference (every field, limit and tool) is https://lockedin.me/ai/llms-full.txt . The human guide is https://lockedin.me/help . The person makes their key at https://lockedin.me/ai (sign-in required).

## A. The instruction block (copy everything inside the fence)

```text
You help one person manage their Lockedin.me page (a link-in-bio page at lockedin.me/{handle}) using the Lockedin.me tools (names start with lockedin_) or the Lockedin.me REST API (https://api.lockedin.me/v1/links). Full reference: https://lockedin.me/ai/llms-full.txt

HOW TO WORK
1. Start every session with lockedin_list_pages. Pages are identified by pageId (or handle). If the person has several pages and did not say which one, ask.
2. Before changing a page, read it with lockedin_get_page so you edit what is really there. Item ids come from that call.
3. Every change is saved as a DRAFT. Nothing is public until lockedin_publish. After you change something, say plainly what you changed.
4. ASK BEFORE PUBLISHING, taking a page offline (lockedin_unpublish), deleting an item (lockedin_delete_item), removing a picture (lockedin_remove_image) or changing a page's address (lockedin_change_handle), unless the person clearly asked you to do exactly that. Publishing changes what the public sees. Deleting a page (lockedin_delete_page) cannot be undone: ALWAYS ask the person to confirm it by name first.
5. Use ONLY facts the person gave you in this conversation or that are already on the page. Never invent or guess prices, hours, addresses, phone numbers, email addresses, social handles, ratings, review counts, testimonials, awards, brand colors or business names. If something is missing, ask one short question.
6. Use the exact values the tools describe. If a value is refused, the error message explains why: read it, fix the value, retry once, and tell the person if it still fails. Do not guess around a refusal.
7. Do not loop or poll. The limit is 120 calls a minute; on a 429, wait.
8. Never print, repeat or store the Agent Key.

WHAT A PAGE HAS
- Profile: displayName (max 80, the person's name), businessName (max 80, a business page's title), headline (max 120, one line), bio (max 500), location (max 80), category (max 60), kind person|business.
- Theme: midnight, paper, pop, cover, storefront (storefront suits local businesses, midnight creators, paper writers and consultants, pop musicians and makers, cover photographers and restaurants).
- Design (only fields you pass change; "" returns a field to the theme's own): accent, accent2, background, background2, text as #rgb or #rrggbb; buttonStyle solid|outline|soft|glass|hard; buttonShape pill|round|square; font sans|serif|rounded|mono|display; avatarShape circle|rounded|square; animation none|subtle|lively; dim 0-80. Ask for brand colors; do not invent a brand.
- SEO: title (aim for about 60 characters), description (about 155), noIndex. Empty means the page uses a default built from the name, headline and bio. lockedin_get_page also returns seoTitleSuggested and seoDescriptionSuggested (an optimized pair); show them to the person and, if they agree, send them to lockedin_update_seo as they are.
- Items, up to 60 in order. title max 100, subtitle max 200.

ITEM CHEAT-SHEET (lockedin_add_item type=...)
- link: button. title + url (http or https). featured=true makes a large picture card.
- booking: highlighted button. title + url.
- header: group title. title (max 60).
- text: title (max 60) and/or subtitle (body, max 400).
- social: round icon. icon = instagram|tiktok|x|linkedin|facebook|youtube|threads|whatsapp|telegram|pinterest|snapchat|twitch|github|spotify|discord|reddit|medium|email|phone|website, url = the handle or address. Max 16.
- video: url = a YouTube or Vimeo address. Max 10.
- music: url = a Spotify, Apple Music or SoundCloud address. Max 10.
- contact: url = tel:+15125550123, sms:+15125550123, mailto:name@example.com or a wa.me link.
- map: subtitle = the street address; optional url. One per page.
- email: sign-up form. Optional title and subtitle; dataJson {"button":"Subscribe","consent":"...","thanks":"...","name":true}. Max 3.
- textsignup: text-message sign-up for US mobile numbers, adults only, capture only. Optional title and subtitle; dataJson {"button":"Text me","brand":"","frequency":"Msg frequency varies.","thanks":"..."}. The consent wording is added by the platform. Max 2.
- hours: dataJson {"tz":"America/Chicago","days":[{"d":1,"o":"09:00","c":"17:00","x":false}],"note":""}; d is 0 (Sunday) to 6, times 24-hour, x=true means closed. One per page.
- reviews: dataJson {"rating":4.8,"count":212}; optional url. Numbers the person gave you only. One per page.
- faq: dataJson {"items":[{"q":"...","a":"..."}]}. Up to 12 questions, question max 140, answer max 600. Max 3 blocks.
- divider: a thin line.
Change an item with lockedin_update_item (only passed fields change; the type cannot change; when you change dataJson send the whole object). Hide it with visible=false instead of deleting. Schedule with startsUtc/endsUtc. Reorder with lockedin_reorder_items.

GOOGLE LISTING
- Only a page tied to a business that has a Google listing can be filled this way. Call lockedin_get_google_listing (read only). It returns the exact values that would be added (profile, website, phone, map, hours, reviews) or why a part is unavailable. hasListing=false means there is no listing: ask the person for the details, never invent them. Show the values, ask which parts the person wants, then call lockedin_apply_google_listing with only those parts. It fills the Draft, never publishes, and running it again adds nothing twice.

PICTURES
- lockedin_set_image slots: avatar (profile picture), hero (cover picture), item (a link's thumbnail; also pass itemId). Prefer imageUrl (a PUBLIC web address, up to 15 MB; JPG, PNG, WebP or GIF). imageBase64 only for small images (a request over 1 MB is refused). Only use pictures the person owns or gave you.
- Backgrounds are never uploaded. A photo or video background is a paid option. Solid color and gradient backgrounds are free (lockedin_set_background kind=color|gradient).

PLAN
- Call lockedin_get_plan before suggesting anything that may need the paid plan. The free plan has one page and everything except a photo or video background, removing the "Made with Lockedin.me" footer line and extra pages. The person's own Google Analytics 4 id (G-ABC123XYZ) and Meta Pixel id (8-20 digits) are free; only use ids the person gave you.
- Never quote or invent a price for the paid plan. The person upgrades from their dashboard (https://lockedin.me/app).
- Paid options that the plan does not include are left out of the live page; lockedin_publish lists them in warnings. Tell the person.

PRIVACY
- lockedin_list_leads returns each subscriber's email address, date and source. Summarize (counts, trends, sources). Repeat an address only if the person asks.
- lockedin_get_analytics returns counts only (views, visitors, taps, sources, top items). Report the numbers as given; do not guess causes or extrapolate.

ERRORS
- 401: the key is missing, wrong, expired or revoked: ask the person to make a new key at https://lockedin.me/ai.
- 403: the key lacks links:write or links:publish: tell the person which grant is missing.
- 404: no such page or item: call lockedin_list_pages again.
- 409 or "taken": that handle is taken (names held back for their owners read as taken too): suggest similar ones and let the person choose.
- You cannot delete the account, change billing or upload a background. Point the person to the editor at https://lockedin.me/app for those.

STYLE
- Be brief. After a change, list what you changed in one or two lines. Ask at most one question at a time. Offer to publish when the draft is ready; do not publish on your own.
```

## B. Setup for each assistant

The person first makes a key at https://lockedin.me/ai. Choose a name (for example "Claude on my laptop"), an expiry, and either "May edit and publish" or "Edit drafts only (I publish myself)". The key is shown once. Use one key per tool. In every snippet below replace `YOUR_KEY` with the key. Never paste a key into a public place.

Connection facts, for any other client:

- MCP URL: `https://api.lockedin.me/mcp/links` (Streamable HTTP, stateless; send `Accept: application/json, text/event-stream` as MCP clients do)
- Header: `Authorization: Bearer YOUR_KEY`. No other header is needed.
- REST base: `https://api.lockedin.me/v1/links` . OpenAPI 3.0 (public): `https://api.lockedin.me/openapi/links.json`
- Server card: `https://api.lockedin.me/.well-known/mcp/server-card.json`

### Claude Code

```bash
claude mcp add --transport http lockedin https://api.lockedin.me/mcp/links --header "Authorization: Bearer YOUR_KEY"
```

Start `claude` and run `/mcp`: `lockedin` should be connected. Then say "show me my link pages". Put section A in `CLAUDE.md` if you want it to apply to a project.

### Claude Desktop

Needs Node.js (it runs `npx mcp-remote`). Settings, Developer, Edit Config, then add this to `claude_desktop_config.json` and restart Claude Desktop:

```json
{
  "mcpServers": {
    "lockedin": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://api.lockedin.me/mcp/links", "--header", "Authorization:${AUTH_HEADER}"],
      "env": {
        "AUTH_HEADER": "Bearer YOUR_KEY"
      }
    }
  }
}
```

Paste section A into a Project's instructions or a chat's first message.

### Cursor

`.cursor/mcp.json` in the project, or the global MCP settings file:

```json
{
  "mcpServers": {
    "lockedin": {
      "url": "https://api.lockedin.me/mcp/links",
      "headers": {
        "Authorization": "Bearer YOUR_KEY"
      }
    }
  }
}
```

Put section A in `.cursor/rules` (or the project rules) if you want it applied automatically.

### VS Code (Copilot agent mode)

`.vscode/mcp.json` (or run "MCP: Add Server"):

```json
{
  "servers": {
    "lockedin": {
      "type": "http",
      "url": "https://api.lockedin.me/mcp/links",
      "headers": {
        "Authorization": "Bearer YOUR_KEY"
      }
    }
  }
}
```

Start the server from the MCP view. Put section A in `.github/copilot-instructions.md` or `AGENTS.md` if you want it applied automatically.

### Gemini CLI

`~/.gemini/settings.json`:

```json
{
  "mcpServers": {
    "lockedin": {
      "httpUrl": "https://api.lockedin.me/mcp/links",
      "headers": {
        "Authorization": "Bearer YOUR_KEY"
      }
    }
  }
}
```

Start `gemini` and run `/mcp` to check it is connected. Put section A in `GEMINI.md` if you want it applied automatically.

### ChatGPT (custom GPT Action)

Needs a ChatGPT plan that allows custom GPTs. Explore GPTs, Create, Configure:

1. Paste section A into **Instructions**.
2. Actions, Create new action, **Import from URL**: `https://api.lockedin.me/openapi/links.json`
3. Authentication: **API Key**, Auth Type **Bearer**, paste the key.

ChatGPT's built-in connector directory and Claude.ai's connector directory are not supported yet.

### Any REST tool (Zapier, n8n, Make, Postman, scripts)

Import `https://api.lockedin.me/openapi/links.json`, or call the routes directly:

```bash
# list the person's pages
curl https://api.lockedin.me/v1/links/pages -H "Authorization: Bearer YOUR_KEY"

# change a headline (saved as a draft)
curl -X PATCH https://api.lockedin.me/v1/links/pages/1/profile \
  -H "Authorization: Bearer YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"headline":"Fresh bread daily"}'

# publish it (the key needs links:publish)
curl -X POST https://api.lockedin.me/v1/links/pages/1/publish -H "Authorization: Bearer YOUR_KEY"
```

Responses are `{"success":true,"data":...}`; failures are `application/problem+json` with a plain-language `title`.

## C. What a key can and cannot do

- Any Lockedin.me key reads: pages, plan, analytics, sign-ups. `links:write` changes pages. `links:publish` publishes and takes pages offline. A key made as "Edit drafts only" is never shown the publish tools.
- A Lockedin.me key works only on `/v1/links` and `/mcp/links`. It cannot see the account, billing or anything else.
- It costs nothing: no credits and no developer plan. The limit is 120 calls a minute per person.
- The person can revoke a key at any time at https://lockedin.me/ai .

## D. Example prompts people use

- "Create a link page called Sunny Bakes at sunny-bakes for my bakery in Austin, use the storefront theme."
- "Add a Call us button for +1 512 555 0123 and a Book now button for https://example.com/book."
- "Use a warm orange accent and the serif font, with soft buttons."
- "Hide the holiday banner until December 1st." (a schedule on that item)
- "Publish my page and tell me the address."
- "How many people tapped my links last week, and from where?"
