
LockIn
io.github.Sky-walkerX由 GitHub 帳號 Sky-walkerX 發布v1.0.0更新於 Oct 24, 2026
A notebook your coding agents write to: notes that track the code's commit, and handoffs.
概覽
LockIn 是一個筆記本 MCP 伺服器,讓編碼代理儲存、搜尋與讀取與程式碼提交綁定的筆記,並在代理之間交接工作。
- 可以做什麼
- 瀏覽主題、章節與收件匣,依關鍵字或語意搜尋筆記
- 完整讀取單一筆記、任務或子任務,或讀取某主題的完整計畫及任務與子任務
- 在主題或章節下新增筆記、追加內容,並編輯或重新命名同一代理記錄的筆記
- 確認、標記過期、取代或連結替換錨定到儲存庫、提交與檔案的筆記
- 透過一次性連結上傳圖片,並取得在筆記中顯示該圖片的 markdown
- 儲存與接取代理之間的交接、記錄工作階段摘要,並管理章節、任務與子任務
- 適用情境
- 適合在 Claude Code、Codex、Cursor 等 MCP 用戶端跨工作階段工作時使用,把每次工作階段學到的東西留存為可歸檔、可審閱、可查詢的筆記,並把未完成的工作交給下一個代理。
- 執行需求
- 需要一個 LockIn 執行個體:託管端點,或自架部署(需 Docker 與 Compose、Postgres 和 AUTH_SECRET)。代理使用在設定中建立的專屬權杖,透過 Authorization Bearer 標頭驗證;登入型應用改用 OAuth。可從網際網路存取的主機需要 HTTPS。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 LockIn,將其新增到工作區。
- 連接 所需的 憑證。它們會被私密儲存,絕不會在公開頁面上展示。
- 為需要使用其工具的對話啟用該服務。
Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。
交給代理程式安裝
把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。
閱讀 https://sourceweft.com/mcp/io.github.Sky-walkerX%2Flockin/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。其他 MCP 客戶端
把它新增到你客戶端的 mcpServers 設定中。 客戶端會在首次連接時完成 OAuth 登入。
{
"mcpServers": {
"lockin": {
"type": "http",
"url": "https://lockin.namankhandelwal.dev/api/mcp"
}
}
}README
[LockIn. The notebook your AI tools write to.]
[GitHub stars] [CI] [Last commit] [Open issues] [License: AGPL-3.0]
[MCP: 19 tools] [Self-hosted with Docker Compose] [Next.js 16] [Postgres 17] [TypeScript]
Try it · Self-host · Connect your agents · Ask your notes · Develop
You learn things inside Claude, Codex and Cursor every day, and most of it is gone when the session ends. LockIn keeps it. Your agents save notes into it over MCP, you file them by subject, and any model you choose answers questions from them.
The launch film, 45 seconds, with sound:
https://github.com/user-attachments/assets/3ae46572-283e-49fd-a3dc-e178dd269e40
How it fits together
[Claude Code saves a note to the Project-X section over MCP. The note appears in the notebook and is stamped as witnessed. In a later session Codex searches Project-X over MCP and picks up from that note.]
Monday: Claude Code saves a note to Project-X, and you witness it. Thursday: Codex picks up where it left off.
What's in it
Self-hosting
You need Docker with Compose.
Open http://localhost:3000 and create an account. The port answers only on the machine itself; for a server, see HTTPS below. The first start pulls the released images, waits for Postgres and applies the database migrations before the app starts. Images are published for amd64 and arm64; where there's none for your version, Compose builds from the checkout instead.
What runs:
To add text extraction and server-side embeddings, set INGEST_SECRET (any long random string) and INGEST_URL=http://ingest:8080 in .env, then:
The ingest image carries its embedding model, so it's about 1 GB. Without it, keyword search works, and the browser does embeddings itself. It reads two documents at a time and stops one that takes over 140 seconds; a third waits 20 seconds for a slot and is then told the service is busy. PARSE_CONCURRENCY in .env raises the first number, on a machine with a core and a few hundred MB to spare per document.
To update, pull the new release. The compose file names the version it goes with, so the images always match the checkout. Migrations run on start:
To run the code in your checkout instead of a release, build it: docker compose up -d --build.
docker compose ps shows whether the app is healthy; the same check is at /api/health (200 when the app can reach its database) for an uptime monitor.
Backups
Everything lives in two volumes: db (Postgres) and uploads (note images and PDFs). Back up both, and take a backup before updating.
Keep AUTH_SECRET with the backups. A restored copy with a different secret signs everyone out.
Settings in .env:
HTTPS
On a machine the internet can reach, LockIn needs HTTPS: without it sessions and agent tokens cross the network in the clear, and browsers won't run a local model. The https profile adds Caddy, which gets a certificate from Let's Encrypt and renews it. Point your domain at the machine, open ports 80 and 443, and set in .env:
The proxy's settings are in Caddyfile: a year of Strict-Transport-Security, and a 60 MB cap on a request's body.
With a proxy of your own on the machine (nginx, Traefik) leave the profile off, set PUBLIC_URL, point the proxy at 127.0.0.1:3000 and have it send Strict-Transport-Security. That's the one security header LockIn leaves out, since only the proxy knows the site is served over HTTPS; the rest (a content security policy, no framing by other sites, no content sniffing) it sends itself.
Port 3000 isn't open to the network, so the proxy can't be gone around. To use LockIn from other machines without a proxy, on a home network say, set LOCKIN_BIND=0.0.0.0 and TRUSTED_PROXY_HOPS=0. Docker publishes that port past most host firewalls, and everything, passwords and agent tokens included, then travels unencrypted.
Accounts
Anyone who can open the address can sign up, unless you set SIGNUP=closed: make your own account first, then close it.
With SMTP_HOST set, LockIn sends two emails. A new account gets a link to confirm its address and can't sign in until it's opened, and "Forgot password" sends a link that sets a new one. The links are built from PUBLIC_URL, so set it to the address people really use. Without SMTP there's no email: accounts sign in straight away, and you reset a forgotten password yourself:
Changing or resetting a password signs that account out everywhere. Resetting one, by the emailed link or with the script, also disconnects every agent and connected app, in case someone else had been in: a token they made would outlast the new password. Connect them again in Settings. Settings has "Change password" and "Delete account", which removes the notebook, its files and every agent's access.
A notebook you run for yourself has no privacy or terms page. If other people sign up on yours, set OPERATOR_EMAIL, and OPERATOR_NAME if you like: /privacy and /terms appear, linked from the landing and sign-up pages, and name you as the one to write to. OPERATOR_HOSTING is a sentence of your own, shown on the privacy page, on where the data is kept and how long backups are. Both pages describe what LockIn does and make a few promises in your name (that you don't read people's notes, that you'll give notice before closing), so read them before turning them on.
"Continue with Google" makes a new account, or opens the existing one with that address if the address was confirmed. It won't attach to an account made with a password whose address was never confirmed, so nobody can claim an address ahead of its owner.
Limits
LockIn counts a few things so one caller can't wear the instance out, and answers 429 with Retry-After past the limit:
Limits per network go by the visitor's address, which LockIn only knows from the X-Forwarded-For header its proxy sets. That's another reason to run it behind one. With a CDN in front of the proxy as well, set TRUSTED_PROXY_HOPS=2 and have the proxy keep the CDN's header (Caddyfile says how), or everyone behind the CDN is counted as one visitor. With no proxy at all, TRUSTED_PROXY_HOPS=0: a visitor who reaches LockIn directly writes that header themselves, so it isn't believed and those limits count all visitors together.
A request's fields are capped too (a note's body at a million characters, a title at 300). The request body itself is not: let the proxy cap it, at 60 MB or more so PDF uploads still fit (the https profile does; client_max_body_size in nginx).
How big a notebook can get
Search by meaning scores a question against every passage of the account's notebook, inside Postgres. Measured on a laptop with the bundled database: 12 ms for an ordinary notebook (a few hundred passages), 0.1 s for 300 notes and three textbooks (3,900 passages), 0.65 s for 2,000 notes and twenty textbooks (26,000 passages). It grows in a straight line with one account's passages and doesn't depend on how many accounts there are. Past that size the stored vectors want pgvector, which isn't used yet.
A subject's page sends all of its notes at once: fine for hundreds of notes in a subject, slow in the thousands (2,000 notes is about 10 MB). Split a subject that large.
Connect your agents (MCP)
LockIn runs an MCP server at /api/mcp (Streamable HTTP). In LockIn, open Settings → Connect your agents, create a token named after the agent, and copy the setup it shows. For Claude Code:
Settings also shows the Codex (~/.codex/config.toml) and Cursor (~/.cursor/mcp.json) versions.
Tools:
Agents can't delete anything.
When an agent reads a note anchored to code, get_note gives it the git diff to run, so it can tell whether the code has moved on before it relies on the note. Notes carry their commit's date, so when two notes disagree you can see which describes the later code: the note page shows both commits and dates on a replacement.
Claude Code plugin
The plugin in integrations/claude-code files each session into your notebook when Claude Code compacts it and when it ends, and adds /lockin:handoff and /lockin:pickup for passing unfinished work from one agent to another. It uses the lockin server added above:
The capture at the end is a short background run of Claude on Haiku that summarises the session. It counts against your Claude usage; LOCKIN_CAPTURE_ON_EXIT=0 turns it off. The plugin's README has the details.
Each agent gets its own token. Its notes are stamped with the token's name, and you can revoke one without touching the others. Only a hash of each token is stored. A token can make 60 requests a minute; past that it gets 429 with Retry-After.
Claude.ai, ChatGPT and other apps that sign in don't need a token. Add a custom connector with the URL https://your-lockin/api/mcp; the app sends you to LockIn to sign in and allow it. LockIn is its own OAuth 2.1 server for this (PKCE, Client ID Metadata Documents and dynamic registration, rotating refresh tokens), so it works the same self-hosted. Connected apps are listed in Settings, where you can disconnect them.
Ask (⌘J)
Ask runs the model in your browser, on your machine, or at a provider with your own key. LockIn's server builds the prompt from your notes and stores the transcript, but never sees your endpoint or API key: the browser calls the model directly. Keep several connections and pick one at the top of Ask.
-
Your own key: Anthropic, OpenAI, Gemini or OpenRouter. The key stays in this browser. Questions, and the notes used to answer them, go from the browser to that provider. Note autocomplete only runs on local and in-browser models.
-
In browser: WebLLM on WebGPU. Pick a model in Ask's settings and download it once; the browser caches it. Needs recent Chrome or Edge.
-
Local server: any OpenAI-compatible server (Ollama, LM Studio, llama.cpp, vLLM). The browser calls it directly, so it has to allow LockIn's origin:
Running both on localhost needs no configuration.
When your notes outgrow one prompt, Ask stops trimming and starts searching: notes are chunked and embedded (by the ingest service, or in the browser), and a question gets an outline of the subject plus the passages that score as relevant. Embedding in the browser downloads the model once from Hugging Face (about 130 MB, then cached); the code that runs it is served by LockIn itself.
Every note and saved resource has a page number in the notebook. The model sees each one labelled with its page and cites it like [p. 12]; in the reply that's a link to the note. Under each answer, From your notebook lists the passages it used and the pages it cited. A citation of a passage opens the note scrolled to it, with the passage marked.
Development
Environment for development (.env for the Prisma CLI and .env.local for the app):
Optional: GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET, SIGNUP and SMTP_* (Accounts, above), INGEST_URL / INGEST_SECRET, and SUPABASE_URL / SUPABASE_SERVICE_ROLE_KEY to store uploads in Supabase Storage instead of ./storage.
DIRECT_URL must not be a copy of DATABASE_URL on Supabase: pgbouncer in transaction mode can't run DDL, and migrations hang instead of failing.
AUTH_SECRET is not optional. NextAuth's own routes fall back to an internal secret, so sign-in appears to work without it, but every API route reads the JWT with getToken and returns 401.
Schema changes go through migrations: edit prisma/schema.prisma, then pnpm exec prisma migrate dev --name what-changed. A database that was set up with db push before migrations existed is marked at the baseline once (pnpm exec prisma migrate resolve --applied 0001_baseline) and migrates normally after that.
The Prisma client is generated into app/generated/prisma/ (not committed) by pnpm build, or on its own with pnpm exec prisma generate.
Data model
User ──< Subject ──< Milestone ──< Task ──< Subtask, with Subject ──< Resource, User ──< ApiToken, User ──< OAuthGrant ──< OAuthToken (apps that signed in), User ──< EmailToken (confirmation and reset links) and the chat and embedding tables beside them.
A note is stored as a Milestone row (its title and notes markdown), and a subject's Plan tasks can hang off it. The Inbox is a Subject with isInbox. Milestone.source records who wrote a note ("web", or an agent's name), and witnessedAt records when the user signed off on an agent's note.
Design
PRODUCT.md is the product brief and DESIGN.md the design system (the Lab Book look: cloth spine, grid paper, clean reading pages).
Contributing
See CONTRIBUTING.md. Report security issues privately, as SECURITY.md describes.
License
AGPL-3.0-or-later. You can use, change and self-host LockIn freely. If you run a modified version as a service for others, you have to publish your changes.
來源:README.md,提交 236bae0
工具
0版本歷史
1- v1.0.0最新Oct 14, 2026
評分
已滿足適用檢查項的 85%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通必需25 分
- 已宣告認證方式必需10 分
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分