
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 分