>_

MCP integration

This app exposes a Model Context Protocol server so agents like Claude, ChatGPT, Cursor and Codex can read and write your prompt library on your behalf.

Endpoint

Streamable HTTP endpoint:

https://your-app.lovable.app/mcp

Discovery document: https://your-app.lovable.app/.well-known/oauth-protected-resource

Authentication (OAuth 2.1 + PKCE)

  1. MCP client fetches /.well-known/oauth-protected-resource from this app.
  2. It discovers the Supabase authorization server and (optionally) registers itself with dynamic client registration.
  3. It sends the user to the authorize URL. The user signs in with the same account they use in this app, then approves consent at /.lovable/oauth/consent.
  4. The client exchanges the authorization code for an access token and calls /mcp with Authorization: Bearer <access_token>.

Every tool call runs under Postgres RLS as the signed-in user, so a client can only ever read and write that user's own data.

Data boundaries

  • Your library only. Every tool filters on the signed-in user, including get_prompt and get_prompts. Another member's prompt is reported as not found even when it is published in the public feed, and even if the id is known.
  • Your instance only. Agent access is a main-instance feature. A call that arrives on another instance's domain is refused with instance_not_enabled instead of being answered with main-instance data.
  • Tokens from this app only. An access token minted by any other backend is refused with issuer_not_recognized.
  • Approved clients only. A newly seen OAuth client stays pending until you approve it in connected clients; revoking it stops all further calls immediately.
  • Refused calls are recorded as denied in your activity log, with the machine-readable code in the tool result.

Rate limits

Per authenticated user:

  • 30 tool calls per minute
  • 300 tool calls per hour
  • 2000 tool calls per day
  • create_prompt is additionally capped at 60 writes per day

Over-limit calls return isError: true with a rate-limit message and are recorded in your activity log.

Connecting a client

In Claude Desktop, ChatGPT (Custom GPTs / Connectors), Cursor, or any MCP client, add a new HTTP MCP server:

URL:  https://your-app.lovable.app/mcp
Auth: OAuth (the client discovers everything from the URL)

When the client redirects you to sign in, use the same account you use in this app.

Connecting from Claude

  1. In Claude, open Settings → Connectors → Add custom connector.
  2. Paste the endpoint URL https://your-app.lovable.app/mcp and confirm. Claude discovers OAuth automatically.
  3. Sign in with your account and approve the consent screen. Claude then lists the prompt tools.
  4. Ask Claude things like “find my prompt about cold emails” — it calls search_prompts and then get_prompt.

Claude cannot reach the preview sandbox — the app must be published for the connector to work.

Tools

List categories

list_categoriesread

List the category tree: shared top-level categories plus your own sub-categories.

curl -X POST 'https://your-app.lovable.app/mcp' \
  -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_categories","arguments":{}}}'

Search prompts

search_promptsread

Keyword search across your prompts; returns ranked hits with a snippet and prompt id.

Input: query*: string, category_id: uuid, subcategory_id: uuid, visibility: string (private|published), content_type: string (single|chain|skill), limit: integer 1-50
curl -X POST 'https://your-app.lovable.app/mcp' \
  -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_prompts","arguments":{"query":"cold email","limit":5}}}'

List my prompts

list_my_promptsread

List your prompts with optional text search, category/sub-category scope, labels, paging and full text.

Input: query: string, category_id: uuid, subcategory_id: uuid, labels: string[], visibility: string (private|published), content_type: string (single|chain|skill), include_text: boolean, limit: integer 1-100, offset: integer
curl -X POST 'https://your-app.lovable.app/mcp' \
  -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_my_prompts","arguments":{"query":"marketing","limit":10,"include_text":true}}}'

Get prompt

get_promptread

Fetch a single prompt (including its text) by id. RLS decides what the caller can read.

Input: id*: uuid
curl -X POST 'https://your-app.lovable.app/mcp' \
  -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_prompt","arguments":{"id":"00000000-0000-0000-0000-000000000000"}}}'

Get prompts (batch)

get_promptsread

Fetch up to 20 prompts with their full text in one call, instead of many single fetches.

Input: ids*: uuid[] (max 20)
curl -X POST 'https://your-app.lovable.app/mcp' \
  -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_prompts","arguments":{"ids":["00000000-0000-0000-0000-000000000000","11111111-1111-1111-1111-111111111111"]}}}'

Get prompt chain

get_prompt_chainread

Fetch one of your prompt chains by id with its content_type metadata and every step in order.

Input: id*: uuid
curl -X POST 'https://your-app.lovable.app/mcp' \
  -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_prompt_chain","arguments":{}}}'

List my skills

list_my_skillsread

List your skills with their metadata (labels, category, sub-category, model, visibility, skill description, when to use).

Input: query: string, category_id: uuid, subcategory_id: uuid, labels: string[], visibility: string (private|published), include_text: boolean, limit: integer 1-100, offset: integer
curl -X POST 'https://your-app.lovable.app/mcp' \
  -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_my_skills","arguments":{}}}'

Get skill

get_skillread

Fetch one of your skills by id with its full Markdown instructions, skill description and when-to-use.

Input: id*: uuid
curl -X POST 'https://your-app.lovable.app/mcp' \
  -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_skill","arguments":{}}}'

Create prompt, chain or skill

create_promptwrite

Create a new library entry. content_type selects the kind: single (needs text), chain (needs at least two steps) or skill (needs a skill description plus instructions). Defaults to private visibility.

Input: title*: string 1-300, content_type: string (single|chain|skill), text: string, steps: step[] (max 25), skill_description: string, when_to_use: string, category_id*: uuid, subcategory_id: uuid, model*: string, visibility: string (private|published), labels: string[] (max 8)
curl -X POST 'https://your-app.lovable.app/mcp' \
  -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"create_prompt","arguments":{"title":"My prompt","text":"Write a haiku about pgvector.","category_id":"00000000-0000-0000-0000-000000000000","model":"gpt-5","visibility":"private"}}}'

Update prompt, chain or skill

update_promptwrite

Update an existing entry; only the supplied fields change. Pass steps to replace a chain's ordered steps atomically.

Input: id*: uuid, title: string 1-300, text: string, steps: step[] (2-25), skill_description: string, when_to_use: string, category_id: uuid, subcategory_id: uuid | null, model: string, visibility: string (private|published), labels: string[] (max 8)
curl -X POST 'https://your-app.lovable.app/mcp' \
  -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"update_prompt","arguments":{}}}'

Replace prompt chain steps

set_prompt_chainwrite

Replace the ordered steps of an existing prompt with the supplied list (at least two), converting it to a chain. Written atomically; previous steps are removed.

Input: prompt_id*: uuid, steps*: step[] (2-25)
curl -X POST 'https://your-app.lovable.app/mcp' \
  -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"set_prompt_chain","arguments":{}}}'

Delete prompt, chain or skill

delete_promptwrite

Permanently delete one library entry. Chain steps are removed with it.

Input: id*: uuid
curl -X POST 'https://your-app.lovable.app/mcp' \
  -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"delete_prompt","arguments":{}}}'