
Opengist
io.github.ni-c由 GitHub 账号 ni-c 发布v0.5.0更新于 Oct 25, 2026
Read, create, update and delete gists on a self-hosted Opengist instance
概览
让助手连接自建 Opengist 实例,列出、搜索、读取、创建、更新、复刻、点赞和删除 gist。
- 可以做什么
- 按范围、所有者、标题、描述或主题列出和搜索 gist
- 读取 gist 的文件内容、指定修订版本、提交历史与复刻情况,或从偏移量获取单个原始文件
- 读取自己的账号或指定用户的资料,并查询点赞状态
- 从文件列表创建 gist,修改标题、描述、可见性,或写入与重命名文件
- 删除单个文件或整个 gist,复刻 gist,以及点赞或取消点赞
- 返回带分页、截断说明和不可信内容标记的结构化结果
- 适用场景
- 适合把代码片段、笔记或配置文件放在自建 Opengist 服务器上,并希望助手直接查找、总结或起草并发布新 gist 的场景;也便于查看某个 gist 的修订与提交历史。
- 运行要求
- 需要 Node.js 24 或更新版本,或使用已发布的容器镜像,以 stdio 方式运行。需要一个可访问且已启用 REST API 的 Opengist 实例,以及必需的环境变量 OPENGIST_URL 和 OPENGIST_TOKEN(在设置中的访问令牌页面创建、以 og_ 开头的个人访问令牌)。令牌作用域为 gist:read、gist:write、user:read,点赞还需 user:write。
安装
在 SourceWeft 中
- 打开 控制台中的 Opengist,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
opengist-mcp
[CI]
[OpenSSF Scorecard]
[Socket Badge]
[Glama score]
[npm version]
[container image]
[HTTP via mcp-hub]
[docs]
[sponsor]
A Model Context Protocol (MCP) server for Opengist, the self-hosted pastebin powered by Git.
Lets MCP clients like Claude Code, Claude Desktop or Codex read, search, create, update and delete gists on your own Opengist instance: file contents and revisions, commit history, forks and likes, plus your user account.
Fourteen tools is the ceiling, not the floor: OPENGIST_ALLOW_TOOLS=essential
registers a curated seven instead, and a model picks the right tool far more
reliably from seven than from fourteen — see
choosing which tools load.
Note: this server talks to the Opengist REST API under
/api, which is available in recent Opengist releases and enabled by default (api.enabled). A running instance serves its own OpenAPI spec atGET /api/openapi.yaml— compare it against your version if a tool behaves unexpectedly.
What makes it different
Fourteen tools over one API surface, derived from the Opengist REST API and verified against a live instance: reading, searching, writing, forking and liking gists, including revisions, commit history and raw file access.
Bounded by construction. File contents are capped per file and against an overall budget, binary files are never dumped as text, and every truncation names the call that fetches the rest.
Requirements
-
Node.js 24 or newer
-
An Opengist instance with the REST API enabled
-
An Opengist Personal Access Token (Settings → Access Tokens). Scopes:
gist:read— read gists, including your private and unlisted onesgist:write— create, update, delete and fork gistsuser:read— read your own accountuser:write— only needed forset_gist_like
A token without
gist:readstill works, but the API then silently returns only public gists instead of failing.
Configuration
The token is read once at startup and then removed from
process.env, so it is not visible to child processes. Usehttps://for anything but a loopback address — over plain http the token and every gist travel in cleartext.If your instance's
external-urlis not configured, the URLs Opengist reports (and this server passes through) point atlocalhost. Setexternal-url/OG_EXTERNAL_URLon the instance so links are usable.
Choosing which tools load
OPENGIST_ALLOW_TOOLS and OPENGIST_DENY_TOOLS take comma-separated tool names;
a trailing * matches a whole family. essential is a curated preset of
seven: list_gists, search_gists, get_gist, get_gist_file, create_gist, update_gist, delete_gist.
An entry that matches no tool aborts startup and names it, so a typo cannot
silently hide a tool — an absent tool is not something anyone traces back to an
environment variable. A filtered tool is never registered, so it is absent from
tools/list and unknown to tools/call alike, exactly like a write tool under
OPENGIST_READ_ONLY.
If you run several of these servers at once, mcp-hub
is the other answer — its /hub endpoint replaces every server's tools with six
meta-tools.
Installation
Claude Code
Claude Desktop
claude_desktop_config.json:
Codex
~/.codex/config.toml:
Docker
-i is required — the transport is stdio. Do not add -t; a TTY corrupts the
protocol stream.
From source
Through mcp-hub
A client that cannot spawn a local process — ChatGPT connectors, Claude on the web,
Cursor, LibreChat — reaches opengist-mcp through mcp-hub: one
container serves many stdio MCP servers over Streamable HTTP, with an OAuth 2.1 login
behind a single password and long-lived tokens for the clients that cannot do OAuth. Its
/hub endpoint puts every server behind six meta-tools, so one connector reaches all of
them without N×tool schemas in the model's context, and it speaks both protocol revisions
— a question this server asks travels through it to the person at the far end.
Its /config/mcp.json uses Claude Code's format, so the entry is the one you already
have:
allowTools and denyTools there are the hub's own per-server filter, which is not
the same thing as *_ALLOW_TOOLS in env — the difference, and the mistake it invites,
are in the client guide.
Tools
Reading
Writing
Structured output
Every tool declares an outputSchema and answers with structuredContent
alongside the text block, so a client can use the result without parsing prose:
Every tool that reports gist content carries untrusted: true and
source: "opengist" as fields. This server has always said so in notes —
prose in a list, which a client can read but not check — and the field is what
makes it checkable. Three tools are without it, because their answer is entirely
this server's own words: check_gist_like, set_gist_like and delete_gist
report an id they were given and a boolean.
An over-budget result still drops file contents first. Where that is not enough
it is now an error: it used to answer with the JSON cut at the ceiling,
which a text block tolerates and structuredContent cannot.
Safety
- Irreversible actions ask a person.
delete_gist,delete_gist_filesand widening a gist's visibility raise a real dialog through MCP elicitation where the client supports it — one the model cannot answer on its behalf. A plainconfirm: trueflag could be set by the model on its own, or be talked into it by text inside a gist. Where the client cannot show a dialog they refuse the first call and return a random, single-use token that expires after five minutes; that proves the call was made twice with the same arguments and nothing more, and the text says so. Either way the approval fordelete_gist_filesis bound to the exact set of filenames, so one for a single file cannot be replayed to delete another.ELICITATION=falsetakes the fallback deliberately; it never removes the guard. See Asking a person. - Publishing content is asked about the same way. Creating a
publicorunlistedgist, and writing files into a gist that already is one, are disclosure events: whatever the model has in its context becomes readable by others and cannot be withdrawn from anyone who already saw it. Both ask before they act. The approval is bound to the exact content, so one for a single file cannot be replayed with a second one attached. A call that makes the gist private in the same breath is not a disclosure and is not asked about. - Confirmations are checked after validation. A call that could not succeed anyway is reported as the input error it is, rather than first costing a confirmation round-trip.
- Confirmation prompts never quote gist text. Titles, descriptions, topics and filenames are user-supplied and could carry instructions aimed at manufacturing a confirmation, so refusals show only server-side metadata (visibility, file count, dates).
update_gistcannot delete a file. The Opengist API deletes a file when its entry isnullor carries neithercontentnorfilename— exactly the shape a sloppily built object has. This server therefore never exposes the raw file map; it accepts explicitwrite/renameoperations and asserts before sending that no entry could be read as a deletion. Files you do not mention are left untouched.- Typos cannot silently duplicate a file. A write to a filename that does not exist is refused unless
allowCreate: trueis passed, and the refusal names a case-insensitive near match (readme.mdvsREADME.md). - Gist content is untrusted input. Every response that carries file content is tagged with a note saying so. Treat gist text as data, never as instructions.
- Results are bounded. File contents are capped per file and against an overall budget, commits and forks are omitted by default, binary files are not dumped as text, and every truncation is reported together with the call that fetches the rest.
search_gistsstates how much it scanned and marks incomplete results explicitly. - The instance is read, not trusted. Every response goes through one boundary: a field of the wrong type is absent rather than fatal, counts are finite, a commit id has the shape of one before it is used, and display strings are cut. Every string that leaves is stripped of control characters and repaired of lone surrogates; where that touches a file body the result says how many characters it removed, per file.
- Requests are hardened. Redirects are refused so the bearer token cannot be replayed to another host, every request carries a timeout, path parameters reject
./..and are URL-encoded, and upstream error bodies are truncated with HTML error pages dropped entirely. - Residual risk:
OPENGIST_READ_ONLYand the approval flow are client-side guards. The real boundary is the scope of your access token and the permission prompts of your MCP host. A token limited togist:read/user:readcannot write, whatever the model attempts.
Not exposed, on purpose
Not a git client. It talks to the REST API. Cloning, pushing and branching are
git's job — clone_url and ssh_url come back so you can hand them to git.
Not an admin tool. There is nothing here for users, settings or instance
administration, and get_user returns an allowlisted set of fields rather than
whatever the API happens to include.
Not a search index. Opengist has no search endpoint, so search_gists works
with what the API offers rather than pretending to more.
Safety
- Everything Opengist returns was written by a person, and quite possibly not by you — file contents, titles, descriptions, topics and git author names are marked as untrusted data, to be reported rather than followed.
- Results are bounded: file contents are capped per file and against an overall budget, binary files are never dumped as text, and every truncation names the call that fetches the rest.
- Deleting a gist or its files, and widening a gist's visibility, ask a person first through MCP elicitation. Where the client cannot show a dialog, the call is refused and carries a random single-use token that expires after five minutes and only ever appeared in a previous tool result.
- Two ways to stop it writing, and they are not equivalent:
OPENGIST_READ_ONLY=truedoes not register the write tools, which this server enforces; a token scoped togist:readanduser:readcannot write whatever this server or the model does. Use the second one when it matters. - A public gist is a publishing channel — world-readable on most instances, and indexed. Making one is a decision, which is why it asks.
Documentation
The full guide, tool reference and security notes live at
opengist-mcp.ni-c.de (source in docs/).
Development
Releasing
Bump the version in package.json and server.json, move the ## [Unreleased] section of CHANGELOG.md to the new version, commit, then push a tag:
The release workflow verifies that the tag matches the package version, publishes to npm via OIDC trusted publishing (no long-lived token), waits for the container image to appear on GHCR, registers the release in the MCP registry and creates a GitHub release from the changelog section.
If the registry step fails, fix it on main and dispatch mcp-registry.yml — never re-run the tagged job, which checks out the immutable tag.
Releasing
Releases are tag-driven. Bump package.json, move the [Unreleased] notes in
CHANGELOG.md under the new version, commit, then:
The release workflow publishes to npm via Trusted Publishing (OIDC, with provenance), pushes the multi-arch container image to GHCR, creates the GitHub release from the CHANGELOG section, and updates the entry in the official MCP registry.
Contributing
Issues, discussions and pull requests are welcome — see CONTRIBUTING.md. For vulnerabilities please use private reporting rather than a public issue; the policy is in SECURITY.md.
License
MIT © Willi Thiel
来源:README.md,提交 695b3f9
工具
0版本历史
1- v0.5.0最新Sep 16, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分