Skip to main content
Glama

pointless.

Presentations, minus the Power.

Pointless is a self-hosted presentation tool you talk to instead of click at. Deploy it once, connect any LLM that speaks MCP (Claude, or anything else), and ask for a presentation in plain language. What comes back is not a slide template: it's a bespoke, self-contained HTML experience (its own typography, motion, and navigation), published at a share link anyone you share it with can open.

You: "Turn these Q3 numbers into a dark, editorial presentation:
      full-screen sections, keyboard nav, end on the hiring ask."
LLM: …calls create_presentation / set_html / publish…
LLM: "Here you go: https://pointless.yourcompany.com/d/YzRu45qV…"

Try it

No install required. Point your MCP client at the hosted instance and start asking for presentations.

pointless demo: add the MCP server, ask for a presentation, open the share link

  1. Add the MCP server.

    claude mcp add --transport http pointless https://app.pointless.show/mcp

    For Claude Desktop / claude.ai: Settings → Connectors → Add custom connector, paste https://app.pointless.show/mcp.

  2. Sign in. On first connect your client opens a Google sign-in (any Google account works, nothing to paste).

  3. Create. Ask in plain language: "make me a deck on our Q3 results." The LLM authors a self-contained HTML presentation and hands back a share link anyone can open.

  4. Manage in the UI. Open app.pointless.show to browse your presentations with live thumbnails, copy or password-protect share links, and delete what you no longer need.

Want your own instance instead? See Run it.

Related MCP server: Egile MCP Slide Deck Generator

How it works

  • One stateless server. Express + PostgreSQL + a built-in web UI. It keeps no local state; point DATABASE_URL at any Postgres.

  • A presentation is one self-contained HTML document with CSS and JS inline. The get_design_guide tool hands the LLM the authoring contract: self-containment, viewport rules, house palettes, and interaction patterns.

  • Sandboxed by construction. Documents are served under a CSP sandbox and embedded via <iframe sandbox> in an opaque origin: no cookies, no API access, no reach into the app or other presentations.

  • Share links are unguessable 128-bit tokens (/d/<token>); re-publishing after edits keeps the same link. Decks can be password-protected (scrypt-hashed at rest).

  • MCP endpoint at /mcp (Streamable HTTP). Tools: get_design_guide, create_presentation, set_html, get_presentation, list_presentations, publish.

Run it

The app is stateless and needs a PostgreSQL database (DATABASE_URL). The quickest way to run both together is Docker Compose:

docker compose up --build
# app on http://localhost:3000, Postgres alongside it

Run a published image. Releases are on the GitHub Container Registry, multi-arch (amd64 + arm64), signed, and SBOM-attested. Run a pinned version against any Postgres:

docker run -d -p 3000:3000 \
  -e DATABASE_URL=postgres://user:pass@your-db-host:5432/pointless \
  -e DATABASE_SSL=true \
  -e BASE_URL=https://pointless.yourcompany.com \
  ghcr.io/moorjani-ajay/pointless:0.5.3

Pin by immutable digest (@sha256:<digest>) for reproducible deploys, and verify the cosign signature before running:

cosign verify ghcr.io/moorjani-ajay/pointless:0.5.3 \
  --certificate-identity-regexp '^https://github.com/moorjani-ajay/pointless/' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

To build it yourself instead: docker build -t pointless . && docker run -d -p 3000:3000 -e DATABASE_URL=… pointless. A running instance reports { version, commit } at GET /version.

Configuration

Variable

Required

Purpose

DATABASE_URL

yes

Postgres connection string, e.g. postgres://user:pass@host:5432/pointless.

DATABASE_SSL

no

Set to true for hosted databases that require TLS (e.g. RDS).

BASE_URL

no*

Origin that publish links are minted with; omit to derive from the request host. Required under oidc.

ADMIN_TOKEN

no

Gates the operator surface; required once the server is reachable beyond loopback.

PORT

no

Port to listen on (default 3000).

AUTH_MODE

no

oidc enables SSO login + the OAuth server; unset/off keeps the server open (default).

MCP_REQUIRE_AUTH

no

Under oidc, defaults on (/mcp requires a token); set false to leave /mcp open.

OIDC_ISSUER

under oidc

IdP issuer URL, e.g. https://accounts.google.com.

OIDC_CLIENT_ID

under oidc

OAuth client id from the IdP.

OIDC_CLIENT_SECRET

under oidc

OAuth client secret from the IdP.

SESSION_SECRET

under oidc

≥32-char random string that signs the session cookie (openssl rand -hex 32).

OIDC_SCOPES

no

Space-separated; default openid email profile.

OIDC_ALLOWED_DOMAINS

no

Comma list of email domains allowed to sign in; empty ⇒ any authenticated user.

OIDC_ADMIN_EMAILS

no

Comma list of emails granted the admin role (see and manage every deck).

Set ADMIN_TOKEN whenever the server is reachable beyond loopback, then open https://your-host/?admin=<token> once to store it locally. Unset, the operator routes are reachable only from 127.0.0.1, so a purely local instance needs no config. Share links (and their passwords) are unaffected either way.

SSO / OIDC (optional)

By default Pointless is open (or ADMIN_TOKEN-gated). Set AUTH_MODE=oidc to require single sign-on with any OpenID Connect provider (Google Workspace, Microsoft Entra ID, Okta, Keycloak, Auth0). It turns on three things:

  • Dashboard login for the operator UI.

  • MCP auth. /mcp becomes an OAuth 2.1 resource server; clients discover it and complete a browser sign-in, no token to paste. On by default under oidc; set MCP_REQUIRE_AUTH=false to opt out.

  • Per-user ownership. Decks are private to their creator; OIDC_ADMIN_EMAILS see and manage everything.

Pointless is its own OAuth 2.1 authorization server and federates the human login to your IdP, so every provider works through one code path. Restrict who may sign in with OIDC_ALLOWED_DOMAINS.

Google Workspace example (set the redirect URI to https://your-host/auth/callback):

AUTH_MODE=oidc
BASE_URL=https://your-host
OIDC_ISSUER=https://accounts.google.com
OIDC_CLIENT_ID=<client id>
OIDC_CLIENT_SECRET=<client secret>
SESSION_SECRET=$(openssl rand -hex 32)
OIDC_ALLOWED_DOMAINS=yourcompany.com
OIDC_ADMIN_EMAILS=you@yourcompany.com

For other providers, point OIDC_ISSUER at the tenant/realm issuer (Entra: https://login.microsoftonline.com/<tenant-id>/v2.0).

Connect an LLM

Point any MCP client at your server's /mcp endpoint. For Claude Code:

claude mcp add --transport http pointless https://your-host/mcp

For Claude Desktop / claude.ai: Settings → Connectors → Add custom connector, paste the endpoint URL. Then just ask for a presentation. With SSO enabled, the client prompts a browser sign-in on first connect.

Development

pnpm install
pnpm --filter @pointless/shared build
docker compose up -d db    # local Postgres on :5432
export DATABASE_URL=postgres://pointless:pointless@localhost:5432/pointless
pnpm dev           # server on :3000 (tsx watch)
pnpm dev:web       # vite dev server on :5173, proxies /api + /raw + /mcp

Tests spin up a throwaway Postgres via testcontainers (Docker required); run them with pnpm test. Repo layout: server/ (Express, MCP, PostgreSQL), web/ (React landing + viewer host), shared/ (types), examples/ (sample presentations).

Security model

Built for deployment inside a trusted network. Authoring happens over MCP; anyone with a share link can view that presentation unless it carries a password. The operator surface (listing/deleting decks and preview-by-id, which bypasses the share password) is ADMIN_TOKEN-gated when set and loopback-only otherwise, so it is never exposed unguarded. Presentation documents may contain arbitrary JavaScript (that is the point), so they always run isolated behind a CSP sandbox with an opaque origin. For per-creator auth beyond a trusted network, set AUTH_MODE=oidc to require SSO, which gates both the dashboard and /mcp and scopes each deck to its creator.

License

MIT

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
5dRelease cycle
9Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Presentations.AI MCP server — create designed slide decks from a topic, text, or document.

  • Publish & manage shareable HTML/Markdown pages from your LLM, with access control.

  • List, share, upload, and manage Slideless HTML presentations from any MCP host.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/moorjani-ajay/pointless'

If you have feedback or need assistance with the MCP directory API, please join our Discord server