Developers

Celestial MCP server

Celestial exposes a Model Context Protocol (MCP) server so AI agents can read and write a person's own Celestial data on their behalf. Every call is authenticated as a real Celestial user and scoped to that user's rows — there is no anonymous access and no cross-account access.

Endpoint

Streamable HTTP

https://www.celestial-app.life/mcp

Transport: MCP Streamable HTTP. POST requests must send Accept: application/json, text/event-stream.

Authentication

OAuth 2.1 with dynamic client registration and PKCE. Clients discover the authorization server from /.well-known/oauth-protected-resource, register themselves, and send the user through Celestial's consent screen. The issued access token is forwarded on every tool call, and database access runs as that user under row-level security.

Rate limits and logging

Tools

get_profile

Get my Celestial profile

Display name, zodiac sign, birth details, timezone and onboarding state for the signed-in user.

Input

{} — no arguments

Example request (tools/call params)

{ "name": "get_profile", "arguments": {} }

Example structured response

{
  "profile": {
    "display_name": "Paul",
    "zodiac_sign": "Scorpio",
    "birth_date": "1990-11-07",
    "birth_time": "07:20",
    "birth_place": "Dublin, Ireland",
    "timezone": "Europe/Paris",
    "onboarding_complete": true
  }
}

list_diary_entries

List my diary entries

Most recent entries, newest first. Notes are decrypted server-side for the owner only.

Input

limit: integer 1–30 (default 7)

Example request (tools/call params)

{ "name": "list_diary_entries", "arguments": { "limit": 3 } }

Example structured response

{
  "entries": [
    { "id": "8f2…", "entry_date": "2026-08-18", "mood": "steady", "energy": 4,
      "moment": "gratitude", "note": "Grateful for a quiet morning." },
    { "id": "1a7…", "entry_date": "2026-08-17", "mood": "tender", "energy": 2,
      "moment": "hard_day", "note": "Long day, felt stretched thin." }
  ]
}

search_diary_entries

Search and summarise my diary

Filter by date range, mood and emotion keywords, then return matches plus a computed summary. Keyword matching happens after decryption, so encrypted notes are searchable without ever being stored in plaintext.

Input

from: YYYY-MM-DD · to: YYYY-MM-DD · keywords: string[] (max 10) · moods: string[] (max 10) · limit: 1–60 (default 30)

Example request (tools/call params)

{
  "name": "search_diary_entries",
  "arguments": {
    "from": "2026-08-01",
    "to": "2026-08-18",
    "keywords": ["anxious", "tired", "grateful"],
    "limit": 30
  }
}

Example structured response

{
  "summary": {
    "matches": 6,
    "scanned": 18,
    "date_range": { "from": "2026-08-03", "to": "2026-08-18" },
    "mood_distribution": { "tender": 3, "steady": 2, "bright": 1 },
    "average_energy": 3.2,
    "recurring_themes": [ { "word": "sleep", "count": 4 }, { "word": "work", "count": 3 } ],
    "highlights": [
      { "entry_date": "2026-08-14", "mood": "tender",
        "excerpt": "Anxious before the review, calmer once I wrote it down…" }
    ]
  },
  "entries": [ /* full matching entries, newest first */ ]
}

add_diary_entry

Add a diary entry

Creates or updates the entry for a date. The note is encrypted with AES-256-GCM before it is stored. Limited to 10 calls per minute.

Input

mood: string (required) · energy: 1–5 (default 3) · note: string ≤2000 chars · entry_date: YYYY-MM-DD

Example request (tools/call params)

{
  "name": "add_diary_entry",
  "arguments": { "mood": "hopeful", "energy": 4, "note": "Started the morning walk again." }
}

Example structured response

{ "entry": { "id": "c31…", "entry_date": "2026-08-18", "mood": "hopeful", "energy": 4 } }

get_daily_affirmation

Get today's affirmation

Today's reading, affirmation and focus for the user's local date. Generated from the live sky and recent diary if not cached yet. Limited to 10 calls per minute.

Input

refresh: boolean (default false) — regenerate instead of using the cached reading

Example request (tools/call params)

{ "name": "get_daily_affirmation", "arguments": { "refresh": false } }

Example structured response

{
  "reading": {
    "reading_date": "2026-08-18",
    "reading": "The Moon in Capricorn steadies the week…",
    "affirmation": "I build slowly, and what I build holds.",
    "focus": "One unfinished thing, finished today."
  }
}

get_weekly_reflection

Get my latest weekly reflection

The most recent synthesised week: narrative, growth themes, attention points, next steps, affirmation.

Input

{} — no arguments

Example request (tools/call params)

{ "name": "get_weekly_reflection", "arguments": {} }

Example structured response

{
  "reflection": {
    "week_start": "2026-08-10",
    "narrative": "This week moved from scattered to settled…",
    "growing": ["Consistency with mornings"],
    "attention": ["Rest before the week's midpoint"],
    "next_steps": ["Write one gratitude line before bed"],
    "affirmation": "Steadiness is a skill I am practising.",
    "stats": { "entries": 5, "streak": 12, "avg_energy": 3.4 }
  }
}

get_horoscope_advice

Get this week's horoscope advice

Current sky read for the user's sign, plus growth themes and next steps from their latest weekly reflection when one exists.

Input

{} — no arguments

Example request (tools/call params)

{ "name": "get_horoscope_advice", "arguments": {} }

Example structured response

{
  "advice": {
    "sign": "Scorpio",
    "sky": { "date": "2026-08-18", "moon_phase": "Waxing Gibbous", "summary": "Sun in Leo, Moon in Capricorn…" },
    "sky_advice": "The Moon moves through Capricorn — momentum you start now carries further than usual.",
    "weekly_reflection": { "week_start": "2026-08-10", "next_steps": ["Write one gratitude line before bed"] }
  }
}

Privacy

Diary notes and questionnaire answers are stored encrypted with AES-256-GCM and are decrypted only inside a request carrying that user's own verified token. Granting an agent access means that agent can read those decrypted entries — revoke it at any time by disconnecting the connector.

PrivacyTermsSupport