inkling-mcp
Enables coding agents to capture, claim, and summarize ideas from an idea inbox, with queue/retain modes and budget tracking.
README
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:
- Mode —
queue: 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_nextrefuses 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.
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_ORIGINfrom*to the origin(s) of the pages that embed your drop.
License
MIT — take it, bend it, ship it.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。