Jinni 是一个工具,可以高效地为大型语言模型提供项目的上下文。它提供了相关项目文件的综合视图,克服了逐个阅读文件的局限性和低效性。每个文件的内容前都有一个简单的标题,指示其路径:
```path=src/app.py
print("hello")
该工具背后的哲学是,LLM 的上下文窗口很大,模型很聪明,直接看到您的项目最能帮助模型应对任何挑战。
有一个 MCP(模型上下文协议)服务器用于与 AI 工具集成,还有一个命令行工具(CLI),用于手动使用,将项目上下文复制到剪贴板,以便在需要的地方粘贴。
这些工具对什么是相关的项目上下文有明确的看法,以最好地在大多数用例中开箱即用,自动排除:
* 二进制文件
* 点文件和隐藏目录
* 日志、构建目录、临时文件等的常见命名约定
如果需要,可以通过 .contextfiles 进行完全粒度的自定义包含/排除。这类似于 .gitignore,但定义的是包含规则。.gitignore 文件本身也会被自动尊重,但在 .contextfiles 中的规则优先。
MCP 服务器可以根据需要提供项目的任意部分。默认情况下,范围是整个项目,但模型可以请求特定模块/匹配模式等。
适用于 Cursor / Roo / Claude Desktop / 您选择的客户端的 MCP 服务器配置文件:
{
"mcpServers": {
"jinni": {
"command": "uvx",
"args": ["jinni-server"]
}
}
}
您可以选择限制服务器仅读取树的一部分以确保安全,以防您的 LLM 失控:在 args 列表中添加 "--root", "/绝对路径/"。
安装 uv(如果未安装):https://docs.astral.sh/uv/getting-started/installation/
重新加载您的 IDE,现在可以要求代理读取上下文。
如果您希望限制到特定模块/路径,只需询问即可——例如,“读取测试上下文”。
使用 Cursor 的示例:
<img src="assets/use_example.png" alt="使用示例">Cursor 可能会无声地丢弃超过允许最大值的上下文,因此,如果您有一个较大的项目并且代理表现得好像工具调用从未发生过,请尝试减少您引入的内容(“读取 xyz 上下文”)。
jinni MCP 服务器:
read_context 工具,返回从指定项目目录中提取的相关文件内容的串联字符串。jinni CLI:
.gitignore 语法的系统(pathspec 库的 gitwildmatch)。.gitignore 文件。这些排除项可以通过 .contextfiles 中的规则覆盖。.contextfiles 进行分层配置。规则根据正在处理的文件/目录动态应用。--overrides(CLI)或 rules(MCP)以独占使用一组特定规则。当覆盖生效时,内置默认规则和任何 .contextfiles 被忽略。覆盖的路径匹配仍然相对于目标目录。.contextfiles / 覆盖):
.gitignore 样式的模式定义要包含或排除的文件/目录,应用于相对路径。! 开头的模式否定匹配(一个排除模式)。(参见下面的配置部分)。DetailedContextSizeError 错误而终止。错误消息包括导致大小的 10 个最大文件列表,帮助您识别可能的排除候选者。参见故障排除部分,了解如何管理上下文大小。list_only 禁用。read_context 工具)claude_desktop_config.json)以通过 uvx 运行 jinni 服务器。read_context 工具。
project_root(字符串,必需): 项目根目录的绝对路径。规则发现和输出路径相对于此根目录。targets(字符串数组,必需): 指定必须处理的 project_root 内的文件/目录列表。必须是一个字符串路径的 JSON 数组(例如,["path/to/file1", "path/to/dir2"])。路径可以是绝对的,也可以相对于当前工作目录。所有目标路径必须解析为 project_root 内的位置。如果提供空列表 [],则处理整个 project_root。rules(字符串数组,必需): 必须的内联过滤规则列表(使用 .gitignore 样式语法,例如,["src/**/*.py", "!*.tmp"])。如果不需要特定规则,则提供空列表 [](这将使用内置默认值)。如果非空,则这些规则独占使用,忽略内置默认值和 .contextfiles。list_only(布尔值,可选): 如果为真,则仅返回相对文件路径列表,而不是内容。size_limit_mb(整数,可选): 超越上下文大小限制(以 MB 为单位)。debug_explain(布尔值,可选): 在服务器上启用调试日志记录。exclusions(对象,可选): 排除配置,具有三个可选字段:
global(字符串数组):全局排除的关键字(例如,["tests", "deprecated"])scoped(对象):映射路径到关键字数组,用于范围排除(例如,{"src/legacy": ["old", "deprecated"]})patterns(字符串数组):要排除的文件模式(例如,["*.test.js", "*_old.*"])project_root。如果出现上下文大小错误,它返回一个带有最大文件详细信息的 DetailedContextSizeError。usage 工具)usage 工具(无需参数)。README.md 文件的内容作为字符串。(详细的服务器设置说明将根据您的 MCP 客户端而有所不同。通常,您需要配置客户端以执行 Jinni 服务器。)
运行服务器:
uvx 直接运行服务器入口点(需要 jinni 包已发布到 PyPI 或可由 uvx 找到):
uvx jinni-server [OPTIONS]
示例 MCP 客户端配置(例如,claude_desktop_config.json):
{
"mcpServers": {
"jinni": {
"command": "uvx",
"args": ["jinni-server"]
}
}
}
您可以选择限制服务器仅读取树的一部分以确保安全,以防您的 LLM 失控:在 args 列表中添加 "--root", "/绝对路径/"。
请参阅您的特定 MCP 客户端的文档以获取精确的设置步骤。确保已安装 uv
jinni CLI)jinni [OPTIONS] [<PATH...>]
<PATH...>(可选): 要分析的一个或多个项目目录或文件路径。如果没有提供,默认为当前目录(.)。-r <DIR> / --root <DIR>(可选): 指定项目根目录。如果提供,规则发现从这里开始,输出路径相对于此目录。如果省略,根目录将从 <PATH...> 参数的共同祖先推断出来(如果只处理 '.',则为当前工作目录)。--output <FILE> / -o <FILE>(可选): 将输出写入 <FILE> 而不是打印到标准输出。--list-only / -l(可选): 仅列出将被包含的文件的相对路径。--overrides <FILE>(可选): 从 <FILE> 添加高优先级规则,除了 .contextfiles 和 .gitignore。--size-limit-mb <MB> / -s <MB>(可选): 超越最大上下文大小(以 MB 为单位)。--debug-explain(可选): 将详细的包含/排除原因打印到标准错误和 jinni_debug.log。--root <DIR> / -r <DIR>(可选): 见上文。--no-copy(可选): 防止在打印到标准输出时自动将输出内容复制到系统剪贴板(默认是复制)。--not <keyword>(可选,可重复): 排除匹配关键字的模块/目录(例如,--not tests --not vendor)。可以多次使用。--not-in <path:keywords>(可选,可重复): 在特定路径中排除特定关键字(例如,--not-in src/legacy:old,deprecated)。可以多次使用。--not-files <pattern>(可选,可重复): 排除匹配模式的文件(例如,--not-files '*.test.js' --not-files '*_old.*')。可以多次使用。--keep-only <modules>(可选): 仅保留指定的模块/目录,排除其他所有内容(逗号分隔,例如,--keep-only src,lib,docs)。CLI 示例:
# 排除所有测试目录
jinni --not tests
# 排除多个关键字
jinni --not tests --not vendor --not deprecated
# 在特定路径中排除旧代码
jinni --not-in src/legacy:old,deprecated --not-in lib/v1:legacy
# 排除特定文件模式
jinni --not-files "*.test.js" --not-files "*_old.*"
# 仅保留 src 和 docs,排除其他所有内容
jinni --keep-only src,docs
# 结合不同类型的排除
jinni --not tests --not-in src/experimental:wip --not-files "*.bak"
注意: 排除命令(--not* 标志)在现有 .gitignore 和 .contextfiles 规则的基础上工作。它们进一步过滤掉原本会被包含的内容。
MCP 示例:
{
"project_root": "/path/to/project",
"targets": [],
"rules": [],
"exclusions": {
"global": ["tests", "vendor"],
"scoped": {
"src/legacy": ["old", "deprecated"],
"lib/experimental": ["wip", "unstable"]
},
"patterns": ["*.test.js", "*_backup.*"]
}
}
您可以使用 pip 或 uv 安装 Jinni:
使用 pip:
pip install jinni
使用 uv:
uv pip install jinni
这将在您的环境中使 jinni CLI 命令可用。请参阅上面的“运行服务器”部分,了解如何根据您的安装方法启动 MCP 服务器。
Jinni v0.1.7+ 自动转换 WSL 路径。
提供以下任一作为 project_root(CLI --root 或 MCP 参数):
/home/user/project
vscode-remote://wsl+Ubuntu-22.04/home/user/project
无需包装器、挂载或额外标志——Jinni 在 Windows 上自动解析 UNC 路径(\\wsl$\...)。
UNC 路径格式: Jinni 总是使用 \\wsl$\<distro>\... 以最大限度地兼容支持 WSL 的所有 Windows 版本。
发行版名称处理: 发行版名称允许空格和大多数特殊字符。只有真正非法的 UNC 字符被替换为 _。
缓存: 为了性能,WSL 路径查找和转换被缓存。如果您在 Jinni 运行时安装 WSL,请重启 Jinni 以拾取新的 wslpath。
退出: 设置环境变量 JINNI_NO_WSL_TRANSLATE=1 以禁用所有 WSL 路径翻译逻辑。
只有 wsl+<distro> URI 和绝对 POSIX 路径(以 / 开头)被翻译;对于 SSH 或容器远程,需在该环境中运行 Jinni。
| 运行时操作系统 | 您传递的内容 | _translate_wsl_path() 返回的内容 |
|---|---|---|
| Windows | vscode-remote://wsl%2BUbuntu/home/a/b | \\wsl$\\Ubuntu\home\a\b |
| Windows | /home/a/b | \\wsl$\\Ubuntu\home\a\b (通过 wslpath) |
| Linux/WSL | vscode-remote://wsl+Ubuntu/home/a/b | /home/a/b |
| Linux/WSL | /home/a/b | /home/a/b (不变) |
将 my_project/ 的上下文转储到控制台:
jinni ./my_project/ # 处理单个目录
jinni ./src ./docs/README.md # 处理多个目标
jinni # 处理当前目录(.)
列出 my_project/ 中将被包含的文件,但不包含内容:
jinni -l ./my_project/
jinni --list-only ./src ./docs/README.md
将 my_project/ 的上下文转储到名为 context_dump.txt 的文件中:
jinni -o context_dump.txt ./my_project/
使用来自 custom.rules 的覆盖规则,而不是 .contextfiles:
jinni --overrides custom.rules ./my_project/
显示调试信息:
jinni --debug-explain ./src
转储上下文(输出默认情况下自动复制到剪贴板):
jinni ./my_project/
转储上下文但不要复制到剪贴板:
jinni --no-copy ./my_project/
.contextfiles & 覆盖)Jinni 使用