ReferenceEverything logg exposes

Documentation

React components, the REST API, iframe embeds, webhooks, the CLI, and the MCP server.

Quickstart#

logg generates beautiful changelogs from your GitHub releases using AI. Connect a repo, sync your releases, and publish changelogs that can be embedded anywhere.

1

Sign in with GitHub

Go to logg.sh/login and authenticate. We request read access to your repositories.

2

Create a project

Pick a GitHub repository or create a manual project. Set a slug — it becomes your public URL: logg.sh/your-slug

3

Sync releases

Hit Sync in the dashboard. AI analyzes commits between each release and generates structured changelogs with categories.

4

Publish and embed

Publish entries from the editor. Embed with React components, an iframe, or fetch from the REST API.

Concepts#

Project

A link between logg and a GitHub repository, or a standalone manual project. Each project has a unique slug used in public URLs, API endpoints, and embed configs.

Changelog entry

One version's release notes. Contains a version, title, AI-generated markdown with categories (features, fixes, improvements, breaking), and a publish state. Only published entries appear on public pages and the API.

Slug

A URL-safe identifier for your project (lowercase letters, numbers, hyphens). Auto-generated from the repo name, editable in project settings. Used in: logg.sh/slug, /api/v1/changelogs/slug, <Changelog slug="..." />.

React Components@logg/react#

Terminal
npm install @logg/react

Import the stylesheet once in your app's entry point. If you use shadcn/ui, the components automatically pick up your theme via CSS variables.

app/layout.tsx
import '@logg/react/styles.css'

<Changelog />#

Renders a full changelog timeline for a project. Fetches data from the public API on mount.

Example
import { Changelog } from '@logg/react'
import '@logg/react/styles.css'

export default function WhatsNew() {
  return <Changelog slug="my-project" maxEntries={5} />
}
NameTypeDefaultDescription
slugstringProject slug from your logg dashboard
baseUrlstring"https://www.logg.sh"API base URL
maxEntriesnumberallMaximum number of entries to display
classNamestringAdditional CSS class on the root element
renderEntry(entry) => ReactNodeCustom render function per entry (overrides default UI)
theme"adaptive" | "logg""adaptive"adaptive inherits your shadcn variables; logg applies logg's own monochrome palette

By default the widget is theme-agnostic — it reads your shadcn variables and blends into whatever surrounds it. Pass theme="logg" when you would rather it look like logg than like your site.

logg theme
<Changelog slug="my-project" theme="logg" />

Custom rendering example:

Custom entry renderer
<Changelog
  slug="my-project"
  renderEntry={(entry) => (
    <div key={entry.version}>
      <h3>v{entry.version} — {entry.title}</h3>
      <p>{entry.summary}</p>
    </div>
  )}
/>

<ChangelogNotification />#

A fixed-position "What's new" button with a dot badge that appears when there's a new version. Tracks seen state in localStorage.

Example
import { ChangelogNotification } from '@logg/react'

<ChangelogNotification
  slug="my-project"
  position="bottom-right"
/>
NameTypeDefaultDescription
slugstringProject slug from your logg dashboard
baseUrlstring"https://www.logg.sh"API base URL
position"bottom-right" | "bottom-left" | "top-right" | "top-left""bottom-right"Fixed position on screen
classNamestringAdditional CSS class on the root element
childrenReactNode"What's new"Custom trigger button content
theme"adaptive" | "logg""adaptive"adaptive inherits your shadcn variables; logg applies logg's own monochrome palette

Hooks#

Use hooks directly if you need full control over rendering.

useChangelog
import { useChangelog } from '@logg/react'

function MyChangelog() {
  const { data, error, loading } = useChangelog('my-project')

  if (loading) return <p>Loading...</p>
  if (error) return <p>Error: {error}</p>

  return (
    <div>
      <h1>{data.project.name}</h1>
      {data.changelogs.map(entry => (
        <div key={entry.version}>
          <h2>v{entry.version}</h2>
          <p>{entry.title}</p>
          {entry.categories?.features?.map((f, i) => (
            <li key={i}>{f}</li>
          ))}
        </div>
      ))}
    </div>
  )
}
useLatestChangelog
import { useLatestChangelog } from '@logg/react'

function NewVersionBanner() {
  const { data, isNew, markSeen } = useLatestChangelog('my-project')

  if (!isNew || !data) return null

  return (
    <div>
      New: v{data.version} — {data.summary}
      <button onClick={markSeen}>Dismiss</button>
    </div>
  )
}

Styling#

Components use CSS variables from shadcn/ui. If your project uses shadcn, everything matches automatically. Otherwise, dark-theme fallback values are applied.

shadcn variables used

--foreground--muted-foreground--border--card--card-foreground--accent--accent-foreground

Override specific styles with --logg-* custom properties:

Custom overrides
.logg-root {
  --logg-accent: #f3f3f3;
  --logg-accent-text: #f3f3f3;
  --logg-border: rgba(255, 255, 255, 0.08);
  --logg-text: rgba(255, 255, 255, 0.9);
  --logg-text-muted: rgba(255, 255, 255, 0.4);
}

REST API#

Public read-only API. No authentication required. Rate limited to 60 requests per minute per IP.

GET /api/v1/changelogs/:slug#

Returns all published changelogs for a project.

Request
curl https://www.logg.sh/api/v1/changelogs/my-project
Response
{
  "project": {
    "name": "My Project",
    "slug": "my-project",
    "description": "An awesome project",
    "repo": "owner/my-project"
  },
  "changelogs": [
    {
      "version": "1.2.0",
      "title": "Dark mode and performance improvements",
      "summary": "Added dark mode support and improved load times by 40%",
      "content": "## New Features\n- Dark mode support...",
      "contentHtml": "<h2>New Features</h2><ul><li>Dark mode support...</li></ul>",
      "categories": {
        "features": [
          "Dark mode with system preference detection",
          "Keyboard shortcuts for common actions"
        ],
        "improvements": [
          "Reduced bundle size by 40%",
          "Faster page transitions"
        ],
        "fixes": [
          "Fixed auth redirect loop on Safari"
        ]
      },
      "publishedAt": "2026-02-10T12:00:00.000Z",
      "releaseDate": "2026-02-10T12:00:00.000Z"
    }
  ]
}

GET /api/v1/changelogs/:slug/latest#

Returns only the latest published changelog entry.

Request
curl https://www.logg.sh/api/v1/changelogs/my-project/latest
Response
{
  "version": "1.2.0",
  "title": "Dark mode and performance improvements",
  "summary": "Added dark mode support and improved load times by 40%",
  "publishedAt": "2026-02-10T12:00:00.000Z",
  "releaseDate": "2026-02-10T12:00:00.000Z"
}

Response headers include X-RateLimit-Remaining and Cache-Control: public, s-maxage=60, stale-while-revalidate=300.

iframe Embed#

Embed your changelog on any page with a simple iframe. The embed sends a postMessage with its height so you can auto-resize.

HTML
<iframe
  src="https://www.logg.sh/my-project/embed"
  width="100%"
  height="600"
  frameborder="0"
  style="border: none;"
></iframe>

Auto-resize with JavaScript:

Auto-resize script
<script>
  window.addEventListener('message', (e) => {
    if (e.data?.type === 'logg-sh-resize') {
      document.querySelector('iframe').style.height = e.data.height + 'px'
    }
  })
</script>

Detection & versioning#

logg watches your repo and decides when a changelog entry should exist. Pick the mode that matches how you ship — the project wizard analyzes your last 90 days and recommends one:

Release publishedGitHub or GitLab releases drive entries.

Tag pushedany tag (optionally filtered by a glob like v*) cuts an entry — no releases needed.

PR mergedevery merge into the watched branch becomes an entry.

Just commitspushes accumulate into a window that cuts after 8 quiet hours (7-day max). Flush anytime with the Cut now button or `logg cut`.

Manualentries come only from the dashboard, CLI, or MCP.

When a trigger carries no tag, the project's versioning scheme names the entry: mirror existing tags, CalVer (2026.08.15), inferred SemVer from conventional commits, or a plain counter. A version bump in package.json, pyproject.toml, or Cargo.toml always cuts an entry with that exact version. Entries are drafts by default — flip the publish policy to auto-publish when you trust the pipeline. Drafts flag AI guesses ("needs review") so you know what to check before publishing.

Webhooks#

logg can automatically generate and publish changelogs when you create a GitHub release. Set up a webhook in your repo settings:

1

Go to repo Settings > Webhooks > Add webhook

2

Payload URL

https://www.logg.sh/api/github/webhook
3

Content type

application/json

4

Secret

Set your GITHUB_WEBHOOK_SECRET value. Used for HMAC-SHA256 signature verification.

5

Events

Select "Releases", "Pushes", and "Pull requests" — which events matter depends on your project's detection mode. logg gathers the evidence, writes the entry, and publishes it (or drafts it for review) per your publish policy. New projects register this webhook automatically; set it up manually only if that failed.

Outbound webhooks#

logg can also call your endpoint on every publish: add a webhook channel in project settings and you'll get a signed POST with the entry. Verify it by recomputing HMAC-SHA256 with your signing secret over {timestamp}.{body} and comparing to the x-logg-signature header (sha256=<hex>). Deliveries carry an x-logg-idempotency-key that stays stable per entry and channel, so replays are safe to deduplicate.

Agent-readable feeds#

Every public changelog is also served in formats agents and scripts can consume directly: /your-project/llms.txt (compact index), /your-project/changelog.md (full markdown), and /your-project/changelog.json (JSON Feed 1.1). All CORS-open and cached.

CLI@logg/cli#

Manage changelogs from the terminal. Authenticate once, then create, publish, and sync changelogs without leaving your shell. Zero token overhead compared to MCP.

Terminal
npm install -g @logg/cli

Or use without installing:

Terminal
npx @logg/cli <command>

Authentication#

The CLI uses GitHub OAuth via a browser redirect. Run logg login to authenticate — it opens your browser, you sign in with GitHub, and the CLI receives a 365-day token stored in ~/.config/logg/credentials.json.

Terminal
logg login      # opens browser for GitHub OAuth
logg whoami     # show current user and token expiry
logg logout     # clear stored credentials

Commands#

All commands use --project to reference a project by its slug.

Projects
# List all projects
logg project list

# Create a manual project
logg project create --name="My App" --slug=my-app

# Create a project linked to GitHub
logg project create --name="My App" --slug=my-app --github=owner/repo
Changelogs
# List changelogs
logg changelog list --project=my-app

# Add a changelog with inline content
logg add --project=my-app --version=1.2.3 --content="## Changes\n- Fixed bug"

# Add from a file
logg add --project=my-app --version=1.2.3 --file=CHANGELOG.md

# Publish / unpublish
logg publish --project=my-app --version=1.2.3
logg unpublish --project=my-app --version=1.2.3
GitHub Sync
# Sync releases and generate changelogs with AI
logg sync --project=my-app

# Regenerate AI content for a specific version
logg generate --project=my-app --version=1.2.3

# Cut the open commit window into an entry (commit detection mode)
logg cut --project=my-app

CLI vs MCP#

CLIMCP
Token costZero per-message overhead~1,500 tokens/message
AuthOne-time login, 365-day tokenRe-auth on token expiry
UsageDirect terminal commandsNatural language via AI tools
Best forCI/CD, scripts, quick actionsConversational workflows

Both use the same API endpoints and can be used interchangeably.

MCP Server#

Manage changelogs from AI coding tools via the Model Context Protocol. Supports OAuth 2.1 with PKCE — your tool handles the flow automatically.

Server URL

https://www.logg.sh/api/mcp

Claude Code#

~/.claude/settings.json
{
  "mcpServers": {
    "logg": {
      "url": "https://www.logg.sh/api/mcp"
    }
  }
}

Claude Code will detect OAuth, open a browser for GitHub sign-in, and store the token. After that, tools like list_projects and sync_project are available in conversations.

Cursor#

.cursor/mcp.json
{
  "mcpServers": {
    "logg": {
      "url": "https://www.logg.sh/api/mcp"
    }
  }
}

Codex#

.codex/mcp.json
{
  "mcpServers": {
    "logg": {
      "url": "https://www.logg.sh/api/mcp"
    }
  }
}

Available Tools#

ToolParamsDescription
create_projectname, slug, description?, githubOwner?, githubRepo?Create a new project (omit GitHub fields for manual)
list_projectsList all your projects
get_projectprojectIdGet project details
list_changelogsprojectIdList changelogs for a project
get_changelogprojectId, changelogIdGet full changelog content
create_changelogprojectId, version, content, title?Create a new changelog entry
update_changelogprojectId, changelogId, title?, content?, summary?, categories?Update an existing entry
publish_changelogprojectId, changelogIdMake entry visible on public page
unpublish_changelogprojectId, changelogIdHide entry from public page
sync_projectprojectIdSync GitHub releases and generate with AI
generate_changelogprojectId, changelogIdRegenerate AI content for an entry

Example — publish all draft changelogs from Claude Code:

Prompt
Use logg to list my projects, then list changelogs for "my-project"
and publish any that are still in draft.

OAuth Details#

The MCP server implements OAuth 2.1 with PKCE (S256). Most MCP clients handle this automatically. If you're building a custom integration:

DiscoveryGET /.well-known/oauth-authorization-server
Resource metadataGET /.well-known/oauth-protected-resource
Register clientPOST /api/oauth/register
AuthorizeGET /api/oauth/authorize
Token exchangePOST /api/oauth/token

Tokens expire after 1 hour. Clients re-authenticate automatically when tokens expire.

logg — AI-native changelogs