关于 URLs-LE
URLs-LE 是面向开发者的 URL 提取工具,可从文档、代码和配置中收集链接,并显示协议与位置。它支持单文件和工作区扫描,对已知格式排除特定注释或代码区域。
主要功能
- 01提取 URL、协议及行列位置
- 02支持 Markdown、HTML、代码与配置格式
- 03按格式排除注释或代码区域
- 04扫描文件夹或工作区并汇总重复项
- 05提供去重与排序命令
适用场景
- 01盘点文档中的链接
- 02审查源代码中的 URL
- 03汇总配置文件里的服务地址
- 04提取链接后交由其他工具检查
MCP 相关
MCP 服务通过 `extract_urls` 工具接收文本并返回 URL、协议和位置;结果默认最多 500 条并标明是否截断。服务不读取文件或发起网络请求。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
1收录的工具列表 · 更新于 3 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| dedupe | boolean | 否 | 重复的 URL 仅保留首次出现的记录。 |
| format | enum | 否 | 文档格式。请指定此参数或 `filename`。支持常见扩展名和别名;其他格式会作为纯文本扫描,而不会拒绝。markdown | html | css | javascript | typescript | json | yaml | properties | toml | ini | xml | csv | plaintext |
| content | string | 是 | 要扫描的文档文本。 |
| filename | string | 否 | 用于在未指定 `format` 时推断格式的文件名,例如 "README.md"。 |
| maxResults | integer | 否 | 返回 URL 数量的上限(默认 500)。meta.truncated 用于报告是否有内容被丢弃。 |
详细介绍
URLs-LE:轻松提取 URL
一键提取当前文件中的所有 URL
适用于任何文本文件——Markdown、HTML、CSS、JavaScript、TypeScript、JSON、YAML、Properties、TOML、INI 和 XML,并能识别需要排除的内容
觉得有用? 点星标或评分能帮助其他开发者发现它—— ★ GitHub · ★ Open VSX · ★ Marketplace
功能
打开文件,运行 URLs-LE: Extract URLs,文档中的所有 URL 都会出现在新的编辑器中,然后可在其中去重和排序。适用于 VS Code 以及基于 VS Code 的编辑器,例如 Cursor 和 VSCodium(可从 Open VSX 安装)。
- 链接审查 — 提取 Markdown 和 HTML 中的所有链接、自动链接和纯文本 URL(排除 Markdown 代码块和 HTML 注释)
- 源代码审查 — 提取 JS/TS 中字符串字面量、模板字面量和注释里的 URL
- 配置文件扫描 — 提取 JSON 字符串、YAML 值、Java 属性、TOML/INI 值以及 XML(Maven POM、信息源)中的 URL
安装
| 适用场景 | 可获得的功能 | 安装方式 |
|---|---|---|
| VS Code | 在编辑器中按一次快捷键即可提取 | Marketplace |
| Cursor、VSCodium、Windsurf | 同一扩展 | Open VSX |
| 终端或 CI 步骤 | 对整个目录树执行相同操作,并返回退出码 | npx url-le · npm 或 cargo install urls-le · crates.io |
| 任何通过 Node 接入的 MCP Agent | 通过 stdio 调用 extract_urls | npx urls-le-mcp · npm |
在 AI Agent 中使用
同一提取引擎也作为 MCP 服务运行,因此 Agent 可以直接调用它,无需你运行命令。
| 编辑器 | 方法 |
|---|---|
| VS Code 1.101+ | 无需安装 — 此扩展会在 Agent 模式下注册 extract_urls |
| Claude Code | claude mcp add urls-le -- npx -y urls-le-mcp |
| Cursor、Windsurf 及其他工具 | 将其指向 npx urls-le-mcp |
extract_urls(content, format?, filename?, dedupe?, maxResults?)
返回每个 URL 及其协议和从 1 开始计数的行号与列号;默认最多返回 500 个,并通过 meta.truncated 标记,避免大型文件内容淹没 Agent 的上下文窗口。
该服务接收内容并返回数据 — 不读取文件,也不会自行发起网络请求。它以 urls-le-mcp 的名称发布在 npm 上,并以 io.github.nolindnaidoo/urls-le 的名称列入 MCP 注册表。
手动配置 — 任何带有 MCP 配置文件的宿主
大多数宿主会读取 JSON 配置。添加一项:
{
"mcpServers": {
"urls-le": {
"command": "npx",
"args": ["-y", "urls-le-mcp"]
}
}
}
-y 会跳过首次运行时的安装提示。如果你不想追踪版本更新,可以固定版本 — [email protected]。
不想每次启动都通过 npx 运行?安装一次,然后指向该二进制文件:
npm install -g urls-le-mcp
{
"mcpServers": {
"urls-le": { "command": "urls-le-mcp" }
}
}
它通过 stdio 使用 MCP,无需环境变量、API 密钥,也不需要自行配置。要在接入其他内容前检查它:
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | npx -y urls-le-mcp
这会打印工具列表并退出 — 如果你看到 extract_urls,说明服务运行正常。
Extract 会读取当前打开的文档。扫描会从磁盘读取多个文件,并生成一份报告。
- 整个工作区:在命令面板中运行
URLs-LE: Extract URLs from Workspace。 - 一个文件夹:在 Explorer 中右键单击该文件夹,然后选择
Extract URLs from Folder;或者运行URLs-LE: Extract URLs from Folder并选择一个文件夹。
项目中同一个 URL 往往会出现在许多地方,因此报告会列出不同的 URL,按使用频率从高到低排列,并显示每个 URL 出现的次数和位置:
# URLs-LE workspace report
`my-project` · 3 file(s) read · 2 distinct URL(s), 5 occurrence(s) in 3 file(s)
| URL | Occurrences | Files |
|---|---|---|
| `https://example.com/docs` | 3 | 2 |
| `https://api.example.com/v1` | 2 | 2 |
## `https://example.com/docs` (3)
- `config.json` · **2:12**
- `docs/a.md` · **1:5**, **1:34**
## `https://api.example.com/v1` (2)
- `docs/a.md` · **2:6**
- `src/b.ts` · **1:14**
以上示例启用了 urls-le.showPositions。该设置默认关闭,此时每行会显示文件和 URL 在其中出现的次数:docs/a.md (2)。剪贴板中的内容遵循 urls-le.clipboardIncludesPositions 设置,与 Extract 的行为相同。
扫描会读取什么。 文件来自磁盘,因此不会读取尚未保存的编辑内容。超过安全大小限制的文件,或不是 UTF-8 文本的文件,都会被跳过。扫描最多处理 5,000 个文件或 10,000 个列出的出现位置。报告末尾会针对每项跳过内容添加一行,避免让人误以为简短的报告代表项目没有问题。
扫描会跳过什么,以及如何更改。 有三个开关默认处于启用状态,可在 Settings 中分别关闭:
| 开关 | 跳过的内容 |
|---|---|
scanUseDefaultExcludes | 依赖文件夹、构建输出、工具缓存和锁文件。完整列表见下文 |
scanRespectGitignore | 项目的 .gitignore 文件指定跳过的内容 |
scanSkipBinaryFiles | 图片、字体、归档文件及其他非文本文件 |
还可以通过两个列表调整结果,而无需关闭开关。如需跳过更多内容,请将模式添加到 scanExcludes。如需读取开关原本会跳过的内容,请将其添加到 scanAlwaysInclude:
{
// Also skip the test fixtures.
"urls-le.workspace.scanExcludes": ["**/fixtures/**"],
// Read the vendored code, though the built-in list skips it.
"urls-le.workspace.scanAlwaysInclude": ["**/vendor/**"]
}
URLs-LE: Open Settings 会在 Settings 编辑器中打开所有这些设置。
内置列表
所有位置的文件夹:
.git、.hg、.svn、node_modules、bower_components、jspm_packages、.pnpm-store、.yarn、vendor、site-packages、Pods、Carthage、dist、build、out、target、_build、_site、dist-newstyle、zig-out、storybook-static、cdk.out、DerivedData、CMakeFiles、.next、.nuxt、.output、.svelte-kit、.angular、.astro、.docusaurus、.vuepress、.expo、.turbo、.parcel-cache、.cache、.sass-cache、.jekyll-cache、.dart_tool、.pub-cache、.gradle、.kotlin、.cxx、.externalNativeBuild、captures、ephemeral、.symlinks、.swiftpm、.build、.bundle、.stack-work、.zig-cache、.godot、elm-stuff、.vercel、.netlify、.serverless、.aws-sam、.terraform、.venv、venv、__pycache__、.tox、.nox、.mypy_cache、.pytest_cache、.ruff_cache、.ipynb_checkpoints、.eggs、coverage、htmlcov、.nyc_output、.vscode-test、.idea、.vs、xcuserdata、*.egg-info
所有位置的文件:
*.min.js、*.min.css、*.map、*.snap、*.lock、package-lock.json、pnpm-lock.yaml、npm-shrinkwrap.json、go.sum、*.pbxproj、*.iml、local.properties、output-metadata.json、.flutter-plugins、.flutter-plugins-dependencies、.packages、Generated.xcconfig、flutter_export_environment.sh、GeneratedPluginRegistrant.*、fastlane/report.xml、fastlane/test_output/**、doc/api/**
以下内容不在列表中,因为它们在许多项目中都是普通文件夹:bin、obj、tmp、logs、public、generated。会生成这些内容的项目通常会在 git 中忽略它们,扫描也会读取 .gitignore。
影响扫描的设置位于 Settings 下。
CLI
相同的提取操作也可以在终端或 Shell 管道中运行:Rust CLI 位于 crate/,并与扩展共享同一语料库 — crate/fixtures/ — 因此两者读取文档的方式始终一致。可以通过 npm 安装(npm install -g url-le),或使用 npx url-le 运行;也可以通过 crates.io 安装(cargo install urls-le)。两种方式安装的都是同一个 urls-le 命令,输出必须逐字节保持一致。npm 包命名为 url-le,因为 urls-le 在 npm 上已被占用。
urls-le . # every URL in the tree; JSON on stdout when piped
urls-le --dedupe docs/ # one line per distinct URL
urls-le mcp # the same extraction over MCP on stdio
# the point of the whole thing:
urls-le . | jq -r '.urls[].value' | sort -u | lychee -
可从 npm (url-le) 或 crates.io (urls-le) 安装。 两种方式安装的都是同一个 urls-le 命令。
npm install -g url-le # or run it once: npx url-le
cargo install urls-le
退出码遵循 grep 的惯例 — 找到 URL 返回 0,未找到返回 1,问题格式错误返回 2 — 因此 if urls-le src/; then … 可以正常工作,而什么都没找到也算是一种结果,不是错误。
它刻意不作任何判断。 不检查链接,不提供不安全协议标记,也不做过滤。在生产配置中,http:// URL 是错误的;在测试夹具中,它却是正确的。替你做决定的工具只会让你去配置它、跟它争论,最后将它静音 — 而静音时,提取功能也一并消失了。把结果传给 lychee,让它来做判断。
支持的格式
| 格式 | 语言 ID | 说明 |
|---|---|---|
| Markdown | markdown | 排除围栏代码块和行内代码 |
| HTML | html | 排除 `` 注释(支持多行) |
| CSS | css | 带引号或不带引号的 url(...)、@import |
| JavaScript / TypeScript | javascript、typescript | 字符串、模板字面量、注释 |
| JSON | json | 仅字符串字面量,通过 jsonc-parser 的 token 偏移量识别;注释视为无关内容 |
| YAML | yaml | 扫描全部内容,包括注释 |
| Properties | properties | 排除以 #/! 开头的注释行 |
| TOML | toml | 仅解析值;排除注释 |
| INI | ini | 扫描全部内容;排除以 ;/# 开头的注释行 |
| XML | xml | 属性和文本内容 |
| 其他 | 任意 | 扫描整个文档;fileType 返回 unknown |
不会拒绝任何文档。 上述 11 种格式知道要排除哪些内容;其他所有语言 ID — python、go、shellscript、csv、plaintext、log,以及编辑器中的其他名称 — 都会扫描全文,因为 URL 在任何文本中都含义明确,而且这些格式中没有值得排除的内容。
提取的协议:http、https、ftp、file、mailto(需要包含 @)、tel。每个匹配项都会报告其实际行号和列号 — TOML 的位置会在源文本中向前定位,重复的相同值可能导致位置近似。URL 在空白字符或引号/括号分隔符处结束,因此不会提取相对链接(/docs)和裸域名(example.com);包含原始空格的 URL 则会被提取为在空格处截断的部分。末尾的 ./, 会保留 — 它们是合法的 URL 字符。
命令
| 命令 | 说明 |
|---|---|
URLs-LE: Extract URLs | 从当前文档中提取所有 URL |
URLs-LE: Extract URLs from Workspace | 列出工作区中每个文件里的不同 URL,以及每个 URL 的位置 |
URLs-LE: Extract URLs from Folder | 对一个文件夹执行相同操作。也可在资源管理器中的文件夹上使用 |
URLs-LE: Deduplicate URLs | 删除结果中的重复行 |
URLs-LE: Sort URLs | 按字母顺序、域名或长度对结果排序 |
URLs-LE: Open Settings | 打开 URLs-LE 设置 |
URLs-LE: Help | 内置文档 |
默认情况下,没有命令绑定快捷键。可在编辑器的 Keyboard Shortcuts 中为任意命令设置快捷键。
设置
| 设置 | 默认值 | 说明 |
|---|---|---|
urls-le.openResultsSideBySide | true | 在当前编辑器旁打开结果 |
urls-le.postProcess.openInNewFile | true | 在新文件中打开结果(未并排显示时) |
urls-le.showPositions | false | 显示每个 URL 所在的行和列 |
urls-le.copyToClipboardEnabled | false | 同时将结果复制到剪贴板 |
urls-le.clipboardIncludesPositions | false | 在复制内容中包含行和列 |
urls-le.dedupeEnabled | false | 自动删除提取结果中的重复项 |
urls-le.notificationsLevel | silent | all = 所有通知,important = 警告和错误,silent = 仅错误 |
urls-le.workspace.scanPatterns | ["**/*"] | 文件夹或工作区扫描会读取的文件 |
urls-le.workspace.scanUseDefaultExcludes | true | 跳过依赖项文件夹、构建输出、缓存和锁文件 |
urls-le.workspace.scanRespectGitignore | true | 跳过项目的 .gitignore 文件所指定的内容 |
urls-le.workspace.scanSkipBinaryFiles | true | 跳过图像、字体、存档及其他非文本文件 |
urls-le.workspace.scanExcludes | [] | 以 glob 模式指定要跳过的其他文件 |
urls-le.workspace.scanAlwaysInclude | [] | 即使以上三项设置会跳过,也要读取的文件 |
urls-le.workspace.scanMaxFiles | 5000 | 单次扫描读取的文件数量上限 |
urls-le.workspace.scanMaxResults | 10000 | 停止读取前,单次扫描列出的 URL 出现次数上限 |
urls-le.safety.enabled | true | 为超大文件提供防护 |
urls-le.safety.fileSizeWarnBytes | 1000000 | 文件大小超过此值时拒绝提取 |
urls-le.safety.largeOutputLinesThreshold | 50000 | 行数超过此值时发出警告 |
urls-le.statusBar.enabled | true | 显示状态栏项 |
urls-le.telemetryEnabled | false | 仅本地事件日志(参见隐私) |
语言
除英语外,还支持 12 种语言:
德语 · 西班牙语 · 法语 · 印度尼西亚语 · 意大利语 · 日语 · 韩语 · 葡萄牙语(巴西)· 俄语 · 乌克兰语 · 越南语 · 简体中文
两部分内容均已本地化:清单(命令标题、设置名称和说明),以及扩展运行时显示的所有内容(通知、状态栏、排序快速选择器)。扩展会遵循 VS Code 的显示语言,因此会与编辑器当前设置的语言保持一致;扩展本身没有单独的语言设置。
隐私与安全
- 无法访问网络。 扩展不会获取、验证或 ping 它提取的 URL——它只读取当前活动文档的文本。
telemetryEnabled设置会将事件写入本地输出通道,供你检查(URLs-LE Telemetry);不会有任何数据离开你的设备。 - MCP 服务同样遵循这一原则。 它接收内容作为参数并返回数据:不访问文件系统、不进行网络调用、不收集遥测数据。你的 Agent 已经有读取文件的工具,因此在服务中重复实现这些功能只会增加路径遍历攻击面,却不带来任何新能力。如果服务导入了任何可能触及这两者的内容,
check:mcp-bundle就会导致构建失败。 - 错误通知会对主目录路径和类似凭证的字符串片段进行脱敏。
- 评分提示最多出现两次。 第 3 次成功使用时,扩展会询问你是否愿意评分;如果你选择 稍后 或关闭提示,则会在第 20 次使用时再询问一次。选择 不再询问 后就不会再提示。你自行将
notificationsLevel设为important或silent,也会关闭提示。计数保存在 VS Code 的扩展存储中,不会发送到任何地方;点击 评分 会在浏览器中打开你安装扩展时使用的市场页面——VS Code Marketplace 或 Open VSX。
文档
| 内容 | 位置 |
|---|---|
| 工具可以做什么——范围、输出约定、拒绝事项和非目标 | crate/SPEC.md |
| 扩展的构建与内部机制——架构、不变量、工具链和发布 | AGENTS.md |
| CLI 的构建与内部机制 | crate/AGENTS.md |
| 变更内容 | CHANGELOG.md · crate/CHANGELOG.md |
| 工具页面及其他 15 个工具 | letools.dev/tools/urls-le |
性能
| 输入 | 大小 | 找到数量 | 耗时 | 速率 | 扫描速度 |
|---|---|---|---|---|---|
| Markdown 文档 | 2.63 MB | 50,000 | 61.14 ms | 817,802/sec | 43 MB/s |
| HTML 页面 | 1.25 MB | 30,000 | 21.88 ms | 1,370,972/sec | 57 MB/s |
| JSON 配置 | 1.52 MB | 40,000 | 39.01 ms | 1,025,358/sec | 38.8 MB/s |
在 Apple M5 Pro、24 GB RAM、Node 24.3.0 上预热后运行 7 次所得的中位数。输入由
scripts/benchmark.ts 生成,并未纳入代码库,因此上方列出的大小就是
实际测得的大小。运行 bun run benchmark 即可复现。
这些数据因机器而异,不会在 CI 中作为断言——用基准测试来阻止构建, 只能说明运行器当时有多忙。
测试
| 指标 | 覆盖率 |
|---|---|
| 语句 | 77.59% |
| 分支 | 67.64% |
| 函数 | 84.73% |
| 行 | 79.13% |
35 个文件中共包含 475 个测试用例,此外还有一套在真实 VS Code 扩展宿主中运行的集成测试,以及一项将构建好的 .vsix 安装到干净配置文件中的端到端测试。
覆盖率数据由真实运行生成,来源为 coverage/coverage-summary.json 和
coverage/test-results.json,并由 scripts/coverage-readme.js 生成;如果
本节内容发生偏差,CI 会失败。运行 bun run test:coverage 即可复现;用例
数量以 vitest 打印的数字为准。
LE 系列的更多工具
为每个模型眼前的工作打造的 16 款单一用途工具。每款都附带一个 Rust CLI 和一个 MCP 服务。一页尽览:letools.dev
提取
- String-LE — 提取代码库中的所有字符串,方便人工阅读
- Numbers-LE — 提取代码库中所有硬编码数字,方便人工检查
- Units-LE — 提取所有带单位的数量并统一格式,遇到含义不明确的数量时会按名称拒绝处理
- Dates-LE — 提取所有日期和时间戳,并给出每个日期和时间戳解析出的确切时刻
- IDs-LE — 提取所有 UUID、ULID、NanoID、ObjectId 和 Snowflake,并解码其中的时间
- IPs-LE — 提取所有 IP 地址、CIDR 网段和 MAC 地址,统一格式并按范围分类
- URLs-LE — 提取代码库中的所有 URL,并给出协议和确切位置
- Paths-LE — 提取代码库中的所有文件路径,并说明它们是否仍指向实际内容
- Colors-LE — 提取代码库中的所有颜色,并指出哪些颜色不在你的调色板中
检查
- Regex-LE — 查找代码库中的所有正则表达式,并报告哪些可能导致灾难性回溯
- Versions-LE — 查找某个依赖项在仓库的各个清单文件中受到不同约束的位置
- i18n-LE — 识别项目使用的 i18n 库,然后依据该库的规则审查其目录
- Scrape-LE — 在编写抓取器之前检查网页能否抓取,并说明何时无法判断
防护
- Secrets-LE — 查找代码库中的硬编码凭据,绝不在报告中打印凭据
- EnvSync-LE — 比较目录树中的 dotenv 文件,并指出哪些文件缺少哪些键
- Unicode-LE — 查找那些隐藏含义的 Unicode 字符——双向控制字符、不可见字符、同形异义字符、混合文字系统
每款工具都独立运行:没有共享的 crate,也没有发布的核心库。若有两款工具得出相同结论,那是因为这个答案经得起两次验证。
联系 — nolindnaidoo.com · GitHub · LinkedIn
nolindnaidoo 的其他项目
Rust — pixelcoords 和 pixelactions 构成一个工作循环:pixelcoords 回答 位置,pixelactions 在那里执行操作。它们有各自的工具、各自的风格——不属于 LE 系列。
- pixelcoords — 冻结屏幕,标记区域,获取像素级精确的坐标和裁剪图像 pixelcoords.dev · crates.io · docs.rs
- pixelactions — 使用经过人工验证的坐标执行交互,并确认操作已生效 pixelactions.dev · crates.io · docs.rs
许可证
MIT © nolindnaidoo
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。