Skip to main content
Glama

inkling

inkling (n) — a slight idea; a vague notion.

A small floating drop that catches yours. Drop it into any web page with one script tag: tap the drop, type the thought, press Enter — it flies off to an endpoint you own, and the page you were on never even notices.

That's the whole trick. Ideas die because capturing them means switching apps, finding the right note, losing your place. Inkling sits quietly in the corner of whatever you're already looking at, so a thought goes from your head to your pipeline in about four seconds.

No dependencies. No build step. No framework. One file of vanilla JS for the widget, one optional file of vanilla Node for the backend — and one file of MCP so the model you already work with can see your ideas.

inkling speaks MCP

This is the part that makes it more than a feedback widget: your coding agent gets a direct feed of your idea inbox.

claude mcp add inkling -- node /path/to/inkling/mcp.js

First use, the agent walks you through a one-time setup — asked with your harness's own clickable UI, answers saved to plain JSON (~/.inkling.json) you can edit anytime:

  • Modequeue: the agent claims the next pending idea whenever it finishes a task and actually implements it (real changes in your repo, under your harness's normal permissions — not just architecture notes). retain: the agent leaves the inbox alone and summarizes it only when you ask. Blurb freely all day; nothing interrupts you.

  • Daily budget — $1/$2/$5 a day, or no cap. Honest fine print: this is advisory bookkeeping — the agent reports its own costs to a work ledger and ideas_claim_next refuses once the day's budget is spent. No portable server can meter a host model's real spend; this is a seatbelt the agent participates in, not a billing wall.

  • Model capture — whether the agent may drop its own ideas into your inbox (capture_idea). Switched off, the tool isn't just refused — it disappears from the tool list entirely, so a human-only inbox stays human-only.

The loop this closes: you tap the drop on any page → the idea lands in the file → next time your terminal agent has a free moment (queue mode) it claims the idea, builds it, and logs the outcome and cost. Capture anywhere, ship from wherever you already work.

Every claimed idea is handed over fenced as untrusted goal material — the same rule as everywhere else in inkling: a captured note describes what to build, never instructions about the agent's own operation.

Related MCP server: claude-orchestrator

Quick start

git clone https://github.com/kevinpalencia46/inkling
cd inkling
npm start          # → http://localhost:3000

Open it, tap the ink drop, type something, hit Enter. It lands in ideas.jsonl and shows up on the page. That's the whole loop.

To put the drop on your own page:

<script src="https://your-host/orb.js"
        data-project="my-app"
        data-endpoint="https://your-host/api/ideas"></script>

Bring your own pipeline

The reference backend (server.js) is an example, not a dependency. The drop works against anything that accepts this request:

POST /api/ideas
content-type: application/json
x-inkling: 1                       ← always sent
authorization: Bearer <token>      ← only when data-token is set

{"text": "the idea", "project": "my-app", "source": "orb"}

Respond with any 2xx and the drop flashes "saved ✓". That's the entire contract — a Flask route, an Express handler, a Cloudflare Worker, a Google Form proxy, whatever you already run. Five minutes, tops:

// Express version, complete:
app.post('/api/ideas', (req, res) => {
  if (req.get('x-inkling') !== '1') return res.sendStatus(403);
  fs.appendFileSync('ideas.jsonl', JSON.stringify({ ...req.body, ts: Date.now() }) + '\n');
  res.status(201).json({ ok: true });
});

Point data-endpoint at it and you're done. Where the ideas go after capture — triage, an LLM that turns them into build plans, a kanban column, an email digest — is your pipeline's business. Inkling just makes sure the thought survives the moment.

Examples

  • examples/ai-triage — the AI-pipeline version: same wire contract, but an LLM structures each idea into a card (title / summary / effort / first_step) on the way in. Works with any OpenAI-compatible endpoint — Ollama locally for free, or DeepSeek/OpenAI in the cloud. Built around two rules: capture never fails (model down → the raw idea still lands), and the idea is untrusted input (fenced in the prompt, model output whitelist-validated — a prompt-injected note can't do anything but describe itself).

Config

Everything is a data- attribute on the script tag:

Attribute

Default

What it does

data-endpoint

/api/ideas

Where captures POST to

data-project

(none)

Tag sent with every idea — lets one inbox serve many apps

data-token

(none)

Sent as Authorization: Bearer … — see security notes

data-accent

inherit

Drop color: any hex/named color, or inherit to read the host page's --inkling-accent CSS variable (falls back to #5aa8ff)

data-icon

(ink drop)

Replace the built-in accent-tinted ink-drop SVG with any character/emoji

Reference backend env vars: PORT (3000), IDEAS_FILE (./ideas.jsonl), IDEAS_TOKEN (empty = no auth), CORS_ORIGIN (* — tighten this to your host page's origin in production), and NOTIFY_URL — when set, every capture POSTs a one-line "💡 idea captured: …" text to that webhook, fire-and-forget (a dead webhook never costs you the idea). Nicest zero-account pairing: an ntfy.sh topic — NOTIFY_URL=https://ntfy.sh/your-secret-topic puts a push notification on your phone for every thought you catch.

How it works (the casual architecture)

Shadow DOM, both directions. The drop renders inside an attached shadow root with :host { all: initial }. Your page's CSS can't restyle the widget, and the widget's styles can't leak into your page. This is what makes "paste one script tag anywhere" actually safe — it behaves the same on a brutalist blog and a Tailwind app.

Drag vs. click is 4 pixels. The drop is draggable so it can get out of your way. Pointer-down starts a candidate drag; if total movement stays under 4px it was a click (open the capture card), otherwise it was a drag (save the new position to localStorage). touch-action: none keeps mobile browsers from hijacking the gesture for scrolling.

The visual viewport, not the layout viewport. Position math uses window.visualViewport instead of innerHeight. War story: on iPad Safari, innerHeight includes the area behind the collapsing toolbar, so the capture card kept opening half off-screen — looked broken, was actually a lie in the coordinate system. visualViewport reports what the user can really see, including when the keyboard is up. If you build floating UI for iOS Safari, this one's for you.

Embedder input is untrusted input. data-accent goes into a <style> block, so it's validated against a hex-or-named-color pattern first (safeColor) — a malicious or typo'd value becomes the default blue instead of markup. data-project and data-icon are set via textContent, never interpolated into HTML (the default ink-drop SVG is a static string no config touches).

The x-inkling header is a CSRF guard, not a secret. Browsers won't send custom headers cross-origin without a CORS preflight. Requiring the header means any cross-site POST has to survive your CORS policy first — a plain <form> or drive-by request can't fake it. The protection is the preflight, not the header's obscurity.

Security notes

  • The token is capture-scoped by design. If it leaks, someone can add ideas to your inbox — and that's all they can do. Don't reuse a token that unlocks anything else, and don't put any other secrets in data- attributes.

  • Self-hosting orb.js from your own infra (like the demo does) keeps update friction at zero.

  • Serving orb.js from a CDN? Add Subresource Integrity so a compromised CDN can't swap the script under you:

    openssl dgst -sha384 -binary orb.js | openssl base64 -A
    <script src="https://cdn.example.com/orb.js"
            integrity="sha384-<hash-from-above>"
            crossorigin="anonymous" ...></script>

    (The hash pins one exact version — recompute it when you update the file.)

  • Tighten CORS_ORIGIN from * to the origin(s) of the pages that embed your drop.

License

MIT — take it, bend it, ship it.

A
license - permissive license
-
quality - not tested
C
maintenance

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

  • Coding agents from Claude Code, Cursor and Codex claim jobs and lock files on one shared board.

  • The project brain for AI coding agents — memory, decisions, sprints, knowledge base via MCP.

  • Agentic workflow budget approvals with usage receipts.

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/kevinpalencia46/inkling'

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