Skip to main content
Glama

jscpd

NPM

Crates.io Version

NPM License jscpd CI Socket Badge OpenSSF Scorecard OpenSSF Best Practices

Детектор копипасты для исходного кода программ. Поддерживает более 224 форматов. Готов для AI: MCP-сервер и экономный по токенам репортер. Теперь на движке Rust — в 24-37 раз быстрее.

jscpd реализует алгоритм Рабина—Карпа для поиска дублирующихся блоков кода в файлах.

Быстрый старт

# Install (all platforms — installs the jscpd command)
curl -fsSL https://jscpd.dev/install.sh | bash

# TypeScript engine (Node.js, v4.x)
npm install -g jscpd@4
jscpd /path/to/code
# or use without installing
npx jscpd@4 /path/to/code

# Rust engine (v5.x, 24-37x faster) — installs the jscpd command
npm install -g jscpd@5
jscpd /path/to/code

# Rust engine — cpd command only
npm install -g cpd
cpd /path/to/code

# Rust-native install (exposes both jscpd and cpd)
cargo install jscpd

# Nix (installs both jscpd and cpd)
nix run github:kucherenko/jscpd -- /path/to/code
# or install permanently
nix profile install github:kucherenko/jscpd

# Homebrew (macOS/Linux)
brew install jscpd

Related MCP server: tree-sitter-analyzer

Документация

Документ

Описание

TypeScript (v4.x)

Движок Node.js — CLI, репортеры, конфигурация, режимы детекции

Rust (v5.x)

Движок Rust — установка, CLI, репортеры, blame, Rust API

AI-Ready

AI-репортер, навыки агентов, MCP-сервер

Programming API

Программные API на TypeScript и Rust

CI & Pre-Commit Hooks

GitHub Action, pre-commit хуки

Packages

Обзор пакетов и крейтов монорепозитория

Два движка

TypeScript (v4)

Rust (v5)

npm-пакет

jscpd@4

jscpd@5 или cpd

Команда CLI

jscpd

jscpd (из jscpd@5) или cpd (из cpd)

Скорость

Базовый уровень

в 24-37 раз быстрее

Форматы

224

223

Требуется Node.js

Да

Нет (автономный бинарный файл)

Программный API

TypeScript (jscpd(), detectClones())

Rust (крейт cpd-finder)

Хранилище LevelDB

Да

Нет

Репортеры

13

13

jscpd@5 устанавливает команду jscpd. npm-пакет cpd устанавливает команду cpd. Оба содержат один и тот же Rust-бинарный файл. Чтобы получить оба имени команды из одной установки, используйте crates.io: cargo install jscpd.

Что нового

v5.0.x — движок Rust

jscpd v5 — это полная переписка на Rust с нуля, которая поставляется как jscpd@5 (устанавливает команду jscpd) или cpd (устанавливает команду cpd). Автономный бинарь — Node.js рантайм не требуется.

Тот же интерфейс, в 24-37 раз быстрее:

  • Все CLI-опции из v4 сохранеы — полная замена: jscpd → jscpd@5

  • Тот же конфигурационный файл .jscpd.json, тот же алгоритм детекции, те же репортеры

  • 223 языковых формата с межформатной детекцией (Vue SFC, Svelte, Astro, Markdown)

Новое в v5:

  • В 24-37 раз быстрее детекция на реальных проектах (см. бенчмарк)

    • Небольшие кодовые базы (548 файлов): в 34 раза быстрее

    • Средние кодовые базы (9K файлов): в 37 раз быстрее

    • Крупные кодовые базы (17K файлов, 900 MB): в 24 раза быстрее

  • Git blame с параллельным сравнением авторов (--blame --reporter console-full)

  • --workers — управляет параллелизмом токенизации файлов и детекции (по умолчанию: авто, использует все ядра CPU; недоступно в v4)

  • 13 репортеров: console, console-full, json, xml, csv, html, markdown, badge, sarif, ai, xcode, threshold, silent

  • AI-репортер — экономный по токенам вывод для LLM-пайплайнов (~79% меньше токенов, чем у console)

  • --mcp — встроенный MCP-сервер через stdio: укажите вашему AI-ассистенту на бинарный файл, и он сможет проверять фрагменты на дубликаты относительно вашей кодовой базы (см. документацию)

  • --summary — сводка по кодовой базе: топ файлов и папок по токенам, строкам, размеру и оценке сложности — горячие точки для рефакторинга прямо из результатов сканирования (см. документацию)

  • Автономный бинарь — готовые сборки для 7 платформ (macOS arm64/x64, Linux arm64/x64, Windows arm64/x64)

Пока нет в v5 (для этого используйте v4):

  • Хранилища LevelDB/Redis (--store leveldb))

  • Программный API Node.js (jscpd(), detectClones()))

Полный справочник по CLI и отличия от v4 см. в документации по Rust.

v4.2.x — TypeScript-движок

  • Собственный бекенд токенизатора — заменен prismjs на собственный бекенд на основе reprism. Токенизация реальных проектов выполняется ~11,5% быстрее

  • Межформатная детекция — Vue SFC, Svelte, Astro и Markdown токенизируются поблочно, что позвояет обнаруживать дубликаты между типами файлов

  • Новые форматы: Apex, CFML/ColdFusion, GDScrip и еще более 70 форматов (всего 224, раньше было 152)

  • Определение shebang — авоматическое определе语言 для скриптов без расширения

  • --store-path — задает каталог кэша LevelDB для параллельных запусков

  • --skipComments — сокращение для --mode weak

  • --formats-names — сопоставляет имена файлов (например, Makefile, Dockerfile) с форматами

  • --noTips — подавляет вывод подсказок в CI

  • Исправления багов: дубликаты целых файлов молча отбрасывались (#728), ReDoS на файлах Lisp/Elisp (#737), падение процесса из-за поврежденного package.json (#739), межфайловая детекция Vue SFC (#737), номера колонок Vue SFC (#737), 50 уязвимостей безопасности в зависимостях

Полный справочник по CLI см. в документации по TypeScript.

Пакеты

Пакет

Описание

jscpd

CLI и Node.js API (v4.x)

jscpd-server

REST API + MCP-сервер

@jscpd/core

Базовый алгоритм обнаружения

@jscpd/finder

Обнаружение в файлах, репортеры

@jscpd/tokenizer

Токенизация исходного кода

@jscpd/html-reporter

HTML-отчет

@jscpd/badge-reporter

SVG-бейдж

jscpd-sarif-reporter

SARIF (GitHub Code Scanning)

@jscpd/leveldb-store

Постоянное хранилище LevelDB

@jscpd/redis-store

Распределенное хранилище Redis

cpd (движок Rust)

Движок на Rust (v5.x) — также доступен как jscpd@5

Кто использует jscpd

npm-пакет jscpd скачивают более 10 млн раз в месяц, и ~5000 репозиториев указыают его на графе зависимостей GitHub.

Входит в состав аналитических платформ:

  • GitHub Super Linter — официальный агрегатор линтеров GitHub, включает jscpd в качестве детектора копипасты

  • MegaLinter — опенсорсный агрегатор линтеров для CI, поставляет jscpd во всех вариантах, включая ci_light

  • Codacy — платформа авоматического анализа кода, jscpd обеспечивает работу движка обнаружения дубликатов

Используется в известных проектах:

  • OpenClaw — персональный AI-ассистент, запускает jscpd как проверку на дубликаты в своих скриптах проверки

  • DeepSeek Harness — плагинный харнесс DeepSeek, конфигурация jscpd в CI

  • degit — генератор каркаса проектов Рича Харриса

  • MEGA webclient — веб-клиент MEGA.nz

  • Microsoff TypeAgent

  • Saleforce DX VS Code

  • Alibaba AppWorks — встраивает jscpd в качестве библотеки

  • OVHcloud manager — клиентская панель управления OVHcloud

  • KiroCrew — самосовершенствующееся постоянное рабочее пространство разработки

Производительность

Замеры проводились на macOS (Apple Silicon), по 10 прогонов на цель (3 для CopilotKit). v4 запускалась с --no-gitignore -i "node_modules", чтобы обес печить сопоставимое сканирование файлов.

Цель

Файлы

Размер

jscpd v4

jscpd v5

Ускорение

fixtures

548

1.5 MB

1.03s

0.03s

34.3x

svelte

9K

38 MB

15.80s

0.43s

36.9x

CopilotKit

17K

159 MB

82.89s

3.44s

24.1x

Полную методологию и исодные данные см. в performance-comparison.md).

Возможности AI-Ready

jscpd интегрируется в рабочие процессы на основе AI с помощью трех механизмов:

AI-репортер

Экономный по токенам вывод для LLM-пайплайнов (~79% меньше токенов, чем у стандартного репортера console):

jscpd --reporters ai /path/to/source              # v4
cpd --reporters ai /path/to/source                # v5
cpd --reporters ai --summary /path/to/source      # v5: + compact codebase summary

Навыки агентов

Два устанавлваемых навыка, которые учат AI-ассистентов программированию использовать jscpd и рефакторить обнаруженные дубликаты:

Навык

Назначение

Установка

jscpd

Справочник по инструменту — опции CLI, формат AI-репортера, синтаксис конфигурации

npx skills add kucherenko/jscpd --skill jscpd

dry-refactoring

Направляемый процесс рефакторинга — прочитать клоны, выбрать стратегию, применить, проверить

npx skills add kucherenko/jscpd --skill dry-refactoring

После установки попросите вашего агента «найти и исправить дублирование кода» — он вызовет jscpd с нужными опциями и обработает результаты.

Подробности см. в документации AI-Ready.

Участие в разработке

См. CONTRIBUTING.md: здесь описаны настройка среды разработки (Rust и TypeScript), политика тестирования и требования к приемлемым pull request. Проблемы безопасности передавайте через политику безопасности, а не в публичные issues.

  1. Сделайте форк репозитория kucherenko/jscpd

  2. Клонируйте форк (git clone https://github.com/{your-id}/jscpd)

  3. Установите зависимости (pnpm install)

  4. Запустите в режиме разработки: pnpm dev

  5. Внесите свои изменения

  6. Добавьте тесты и проверьте: pnpm test

  7. Соберите проект: pnpm build

  8. Создайте PR

Бэкеры

Спасибо всем нашим бэкерам! 🙏 [Стать бэкером]

Спонсоры

Поддержите этот проект, став спонсором. Ваш логотип появится здесь со ссылкой на ваш сайт. [Стать спонсором]

Лицензия

MIT © Andrey Kucherenko

Available Tools

5 tools
check_current_directoryScan the project againA
Read-onlyIdempotent

Scan the paths the server was started with again and return the fresh clone list and counts. Use it after creating, editing or deleting files, so that the other tools answer from current content. Returns {files, kinds, clones, returned, duplicatedLines, percentage, byKind, duplications[]} with the duplications of get_file_clones, biggest first. Reads the files only, and replaces the previous scan; it can take a few seconds on a large project.

NameRequiredDescriptionDefault
kindsNoThe kinds of clone to look for: exact (type1), renamed (type2), similar (type3; 'gap' or 'ast' for one of its two mechanisms) and semantic (type4). Without it: exact, what jscpd reports with this server's options. Renamed and similar clones may need one scan more, and semantic ones run an embedding model, which takes a while the first time.
limitNoMaximum number of clones in the response. 'clones' always carries the full count, so a small limit still tells you how much was found.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only, idempotent, non-destructive, closed-world behavior. The description adds meaningful context beyond that: it reads files only, replaces the previous scan, and can take a few seconds on a large project.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the action and purpose, then covers usage, return shape, and side effects without filler. Every sentence adds useful information for invoking or interpreting the tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, but the description explicitly lists the return shape and notes that duplications are biggest first. For a two-parameter scan tool with annotations covering safety, the description is complete enough to call and interpret correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both parameters in detail, including the kinds enum and limit behavior. The description does not add parameter-specific semantics beyond what the schema provides, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: scanning the paths the server was started with and returning a fresh clone list and counts. It also distinguishes itself by tying its duplication output to get_file_clones and by explaining that other tools should answer from current content after a scan.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says to use it after creating, editing, or deleting files so other tools answer from current content. It does not state when not to use it, which keeps it below a full 5, but the usage context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_duplicationCheck a snippet for duplicationA
Read-onlyIdempotent

Check whether a code snippet duplicates code that already exists in the scanned project. Use it before writing or committing a function, class or block, to find the existing code you should reuse instead; pass kinds ["exact", "renamed", "similar"] to find copies with other names or edited lines as well. Returns {format, kinds, count, returned, duplications[]}, each duplication with 'kind', 'format' (the language of the code that matched), 'file', 'fileStartLine', 'fileEndLine', 'lines' (how many of those lines count as duplicated, as in jscpd's reports: fewer when the match runs over other blocks of the file), 'snippetStartLine', 'snippetEndLine' and 'tokens'; similar and semantic ones add 'similarity' (and 'method': gap or ast), and ast and semantic ones add 'name' (the name of the project's function) and 'snippetName'. Exact matches come first, then renamed, similar and semantic ones. A request without 'kinds' gets its ast matches under 'similar' with 'similarCount', as earlier versions answered. A Markdown, Vue, Svelte or Astro snippet is split into blocks the way a scan splits such a file, so the code of a fence or a script matches code in its language; by meaning, only the functions in a component's scripts are compared. A snippet or a block of code in it shorter than the server's --min-tokens (50 by default) cannot match, and a 'note' says so. Kinds that could not be searched are listed under 'unavailable' with the reason. The snippet is compared with the last scan: call check_current_directory first if files changed.

NameRequiredDescriptionDefault
codeYesThe source code to check, verbatim. Whole functions or blocks work best.
kindsNoThe kinds of clone to look for: exact (type1), renamed (type2), similar (type3; 'gap' or 'ast' for one of its two mechanisms) and semantic (type4). Without it: exact, what jscpd reports with this server's options. Renamed and similar clones may need one scan more, and semantic ones run an embedding model, which takes a while the first time.
limitNoMaximum number of duplications in the response. 'count' always carries the full count, so a small limit still tells you how much was found.
formatYesLanguage of the snippet: a jscpd format name such as 'javascript', 'typescript', 'python', 'java', or a file extension such as 'js', 'py' (`jscpd --list` lists all 224).
similarityNoThe share of subtrees two functions' normalized syntax trees must have in common to be an ast match: 1 finds copies with other names, each standing for one name, and other literals only, 0.8 also one-line edits, 0.7 a couple of added or removed statements. Giving it asks for ast matches. Defaults to the server's --similarity, or 0.8. Functions of JavaScript, TypeScript, Python, Java, Kotlin, Scala, C#, Go, Rust, C, C++, PHP, Ruby, Swift and Clojure. In ast matches each function's syntax tree is normalized: the names of the functions and methods it calls and its operators count, local names, field names and literals do not, as long as each name stands for one name on the other side, and two functions score the share of subtrees their trees have in common. Test files are left out.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover the safe-read profile; the description adds substantial behavior: results are ordered exact → renamed → similar → semantic, a --min-tokens threshold (50 default) prevents short snippets from matching, unfindable kinds appear under 'unavailable', semantic search runs an embedding model that is slow the first time, and renamed/similar may need an extra scan. It also documents the legacy no-'kinds' response shape, which is real behavioral variance.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and usage are front-loaded in the first sentence, and the dense return-format detail is justified because no output schema exists. It does read as one long wall of text bundling edge cases (Markdown/Vue/Svelte/Astro splitting, threshold notes) that could be sectioned, but little is truly wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description takes on the full burden and delivers: it enumerates every returned field, explains the 'lines' vs match-span distinction, and covers degraded responses ('note', 'unavailable'). An agent has everything needed to call this and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already carries most parameter meaning. The description still adds cross-parameter semantics the schema does not: supplying 'similarity' implicitly requests ast matches, and omitting 'kinds' changes how ast results are reported ('similar' with 'similarCount'), plus the note that ast matching only covers a listed set of languages.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Check whether a code snippet duplicates code that already exists in the scanned project') and scopes it to the last scan. It is clearly distinguishable from siblings like get_file_clones (project-wide listing) and compare_folders (folder-to-folder).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit trigger ('Use it before writing or committing a function, class or block, to find the existing code you should reuse instead') and an explicit prerequisite/alternative: 'call check_current_directory first if files changed'. Both when-to-use and when-to-refresh are covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compare_foldersCompare two folders function by functionA
Read-onlyIdempotent

Compare two folders function by function, in one language or across languages: a port and its original (the source first, the target second), or two implementations of one app (iOS and Android). Every function of one folder is paired with the function of the other that does the same job, by the embedding model, and what has no counterpart is listed. Returns the JSON report of jscpd --compare: 'code' and 'tests' sections, each with 'sides' (per folder: 'functions', 'matched', 'percentage', 'files', 'unmatched', 'readyToPort': unported functions whose callees are all ported) and 'pairs' (each with both functions, 'similarity', 'level' high/medium/low, 'renamed' and 'matchedBy' code or name). Read a few low pairs and the pairs matched by name before relying on them. Needs the embedding model; the first comparison of two folders embeds every function and can take minutes, later ones reuse the cached vectors.

NameRequiredDescriptionDefault
leftYesThe first folder (or file): the source of a port, or one of two implementations. It must lie inside the scanned folders: give it relative to one of them, or absolute.
limitNoMaximum number of entries of each list ('pairs', 'unmatched', 'readyToPort', 'files') in the response. 'functions' always carries the full count, so a small limit still tells you how much was found.
rightYesThe second folder (or file): the target of a port, or the other implementation. It must lie inside the scanned folders too, and must not contain the first or lie inside it.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/idempotent annotations, the description discloses the operational cost ('needs the embedding model', 'the first comparison ... can take minutes, later ones reuse the cached vectors') and describes the full returned report. It also flags correctness risk by warning that name-matched and low-level pairs should be spot-checked, which the annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is front-loaded with purpose and argument ordering and every sentence carries information. The long parenthetical enumeration of returned sections is dense but justified because no output schema exists, though it could be tightened.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description fully carries the return-value burden: it names the 'code'/'tests' sections, the per-side fields including 'readyToPort', and the 'pairs' fields including 'similarity', 'level', 'renamed' and 'matchedBy'. Combined with model requirements and caching behavior, an agent has what it needs to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so the baseline is 3, but the description adds the semantic ordering rule (left is the source, right the target) and implies the left/right containment constraint the schema also states. The 'limit' parameter's truncation behavior is left entirely to the schema, so it isn't a full 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource — compare two folders function by function — and immediately names the two scenarios it serves (a port and its original, or two implementations of one app such as iOS and Android). That is enough to distinguish it from the sibling tools get_statistics, check_duplication and get_file_clones, which operate on duplication statistics or clone lists rather than cross-folder function pairing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It spells out both intended scenarios and the argument ordering (source first, target second), and it adds a concrete interpretation rule: read a few low-similarity pairs and the pairs matched by name before relying on them. It never explicitly states when not to use it or names a sibling as the alternative for plain clone or duplication queries, so a 4 rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_file_clonesList the clones of one fileA
Read-onlyIdempotent

List every clone of the last scan that involves one file, to see which other files share code with it. Use it before refactoring, splitting or deleting a file. Returns {file, kinds, clones, returned, duplications[]}, each duplication with 'kind', 'format', 'fileA', 'startA', 'endA', 'fileB', 'startB', 'endB', 'lines' and 'tokens' ('similarity' and 'method' for similar and semantic ones), biggest first; the file may be fileA or fileB. A path that was not part of the scan gets clones 0 and a 'note'.

NameRequiredDescriptionDefault
pathYesThe file, relative to the scan root as other results show paths (e.g. 'src/cart.js'), or absolute.
kindsNoThe kinds of clone to look for: exact (type1), renamed (type2), similar (type3; 'gap' or 'ast' for one of its two mechanisms) and semantic (type4). Without it: exact, what jscpd reports with this server's options. Renamed and similar clones may need one scan more, and semantic ones run an embedding model, which takes a while the first time.
limitNoMaximum number of clones in the response. 'clones' always carries the full count, so a small limit still tells you how much was found.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, non-destructive behavior, and the description goes beyond them: it discloses the ordering (biggest first), the edge case where an unscanned path returns 0 clones plus a 'note', and the cost/latency caveats for semantic clones and extra scans.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose, usage, and return shape are front-loaded in that order with no filler sentences. The long enumeration of return fields is dense but earns its place given there is no output schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description fully compensates by specifying the response envelope, per-clone fields, ordering, and the not-found shape. An agent has everything needed to call and interpret it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3; the description adds meaning by explaining that results may place the requested file as either fileA or fileB, and by describing the unscanned-path outcome that affects the 'path' parameter. It does not elaborate on kinds/limit beyond the schema, so not a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb and resource — 'List every clone of the last scan that involves one file' — plus a scoping phrase ('which other files share code with it') that separates it from siblings like check_duplication and get_statistics.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete usage context ('before refactoring, splitting or deleting a file'), which is clear guidance on when to reach for it. It does not name an alternative tool or state when not to use it, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_statisticsProject duplication statisticsA
Read-onlyIdempotent

Report the duplication statistics of the last scan, for the clones of the kinds asked: for the whole project and per format, the files, lines and tokens analyzed, the clones, and the duplicated lines and tokens with their percentages, plus the number of clones of each kind ('byKind'). Use it to judge overall duplication, or to compare before and after a refactoring (call check_current_directory in between). It reflects the last scan, not the files on disk now.

NameRequiredDescriptionDefault
kindsNoThe kinds of clone to look for: exact (type1), renamed (type2), similar (type3; 'gap' or 'ast' for one of its two mechanisms) and semantic (type4). Without it: exact, what jscpd reports with this server's options. Renamed and similar clones may need one scan more, and semantic ones run an embedding model, which takes a while the first time.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses important snapshot semantics: it reflects the last scan, not the files currently on disk. It also enumerates the reported statistics, including the 'byKind' breakdown. It does not cover cost or timing details, though those appear in the parameter schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and the key caveat about the last scan. The first sentence is dense and long, but each part carries useful information and the later sentences add workflow guidance efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does a good job listing the returned statistics and explaining the stale-scan behavior. It omits precise output shape details, but gives enough for an agent to understand what the call yields and when to use it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the sole 'kinds' parameter is fully documented in the schema, including defaults, enum meanings, and performance notes. The description only alludes to 'the clones of the kinds asked' and does not add meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Report the duplication statistics of the last scan') and clarifies the aggregate scope ('whole project and per format'), which helps distinguish it from per-file tools like get_file_clones. It does not explicitly contrast with check_duplication, so sibling differentiation is good but not complete.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear usage contexts: judging overall duplication and comparing before/after a refactoring, with the concrete instruction to call check_current_directory in between. It does not state when not to use it or name get_file_clones as the alternative for per-file clone data.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv5.4.2
    • Changedcheck_current_directory2 fields changed
      • addedInput schema / properties / kinds
        Added value: +{
        +  "description": "The kinds of clone to look for: exact (type1), renamed (type2), similar (type3; 'gap' or 'ast' for one of its two mechanisms) and semantic (type4). Without it: exact, what jscpd reports with this server's options. Renamed and similar clones may need one scan more, and semantic ones run an embedding model, which takes a while the first time.",
        +  "examples": [
        +    [
        +      "exact",
        +      "renamed",
        +      "similar"
        +    ],
        +    [
        +      "semantic"
        +    ]
        +  ],
        +  "items": {
        +    "enum": [
        +      "exact",
        +      "renamed",
        +      "similar",
        +      "gap",
        +      "ast",
        +      "semantic",
        +      "type1",
        +      "type2",
        +      "type3",
        +      "type4"
        +    ],
        +    "type": "string"
        +  },
        +  "type": "array",
        +  "uniqueItems": true
        +}
      • changedInput schema / properties / limit / description
        Previous value: -"Maximum number of clones to include in the response. 'clones' always carries the untruncated total, so a small limit still tells you how much was found."New value: +"Maximum number of clones in the response. 'clones' always carries the full count, so a small limit still tells you how much was found."
    • Changedcheck_duplication7 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / code / description
        Previous value: -"The source code to check, verbatim (whole functions or blocks work best; it must reach the server's --min-tokens threshold, 50 tokens by default)"New value: +"The source code to check, verbatim. Whole functions or blocks work best."
      • changedInput schema / properties / format / description
        Previous value: -"Language of the snippet: a jscpd format name such as 'javascript', 'typescript', 'python', 'java', or a file extension such as 'js', 'py' (run `jscpd --list` for all 224). Unknown values return an error naming the problem."New value: +"Language of the snippet: a jscpd format name such as 'javascript', 'typescript', 'python', 'java', or a file extension such as 'js', 'py' (`jscpd --list` lists all 224)."
      • addedInput schema / properties / kinds
        Added value: +{
        +  "description": "The kinds of clone to look for: exact (type1), renamed (type2), similar (type3; 'gap' or 'ast' for one of its two mechanisms) and semantic (type4). Without it: exact, what jscpd reports with this server's options. Renamed and similar clones may need one scan more, and semantic ones run an embedding model, which takes a while the first time.",
        +  "examples": [
        +    [
        +      "exact",
        +      "renamed",
        +      "similar"
        +    ],
        +    [
        +      "semantic"
        +    ]
        +  ],
        +  "items": {
        +    "enum": [
        +      "exact",
        +      "renamed",
        +      "similar",
        +      "gap",
        +      "ast",
        +      "semantic",
        +      "type1",
        +      "type2",
        +      "type3",
        +      "type4"
        +    ],
        +    "type": "string"
        +  },
        +  "type": "array",
        +  "uniqueItems": true
        +}
      • changedInput schema / properties / limit / description
        Previous value: -"Maximum number of duplications to include in the response. 'count' always carries the untruncated total, so a small limit still tells you how much was found."New value: +"Maximum number of duplications in the response. 'count' always carries the full count, so a small limit still tells you how much was found."
      • changedInput schema / properties / similarity / description
        Previous value: -"Also return project functions whose syntax-tree structure is similar to the snippet's functions, when the similarity ratio reaches this value. 1 means exact matches only (no 'similar' section); 0.85 catches renames, literal changes and one-line edits; 0.7 tolerates a couple of added or removed statements. Defaults to the server's --similarity setting (1 unless configured). JavaScript/TypeScript only; other formats ignore it."New value: +"The share of subtrees two functions' normalized syntax trees must have in common to be an ast match: 1 finds copies with other names, each standing for one name, and other literals only, 0.8 also one-line edits, 0.7 a couple of added or removed statements. Giving it asks for ast matches. Defaults to the server's --similarity, or 0.8. Functions of JavaScript, TypeScript, Python, Java, Kotlin, Scala, C#, Go, Rust, C, C++, PHP, Ruby, Swift and Clojure. In ast matches each function's syntax tree is normalized: the names of the functions and methods it calls and its operators count, local names, field names and literals do not, as long as each name stands for one name on the other side, and two functions score the share of subtrees their trees have in common. Test files are left out."
      • changedInput schema / properties / similarity / examples
        Previous value: -[
        -  0.85
        -]New value: +[
        +  0.8
        +]
    • Addedcompare_folders
    • Changedget_file_clones4 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / kinds
        Added value: +{
        +  "description": "The kinds of clone to look for: exact (type1), renamed (type2), similar (type3; 'gap' or 'ast' for one of its two mechanisms) and semantic (type4). Without it: exact, what jscpd reports with this server's options. Renamed and similar clones may need one scan more, and semantic ones run an embedding model, which takes a while the first time.",
        +  "examples": [
        +    [
        +      "exact",
        +      "renamed",
        +      "similar"
        +    ],
        +    [
        +      "semantic"
        +    ]
        +  ],
        +  "items": {
        +    "enum": [
        +      "exact",
        +      "renamed",
        +      "similar",
        +      "gap",
        +      "ast",
        +      "semantic",
        +      "type1",
        +      "type2",
        +      "type3",
        +      "type4"
        +    ],
        +    "type": "string"
        +  },
        +  "type": "array",
        +  "uniqueItems": true
        +}
      • changedInput schema / properties / limit / description
        Previous value: -"Maximum number of clones to include in the response. 'clones' always carries the untruncated total, so a small limit still tells you how much was found."New value: +"Maximum number of clones in the response. 'clones' always carries the full count, so a small limit still tells you how much was found."
      • changedInput schema / properties / path / description
        Previous value: -"The file to inspect, either relative to the scan root exactly as paths appear in other tool results (e.g. 'src/cart.js') or absolute"New value: +"The file, relative to the scan root as other results show paths (e.g. 'src/cart.js'), or absolute."
    • Changedget_statistics1 field changed
      • addedInput schema / properties / kinds
        Added value: +{
        +  "description": "The kinds of clone to look for: exact (type1), renamed (type2), similar (type3; 'gap' or 'ast' for one of its two mechanisms) and semantic (type4). Without it: exact, what jscpd reports with this server's options. Renamed and similar clones may need one scan more, and semantic ones run an embedding model, which takes a while the first time.",
        +  "examples": [
        +    [
        +      "exact",
        +      "renamed",
        +      "similar"
        +    ],
        +    [
        +      "semantic"
        +    ]
        +  ],
        +  "items": {
        +    "enum": [
        +      "exact",
        +      "renamed",
        +      "similar",
        +      "gap",
        +      "ast",
        +      "semantic",
        +      "type1",
        +      "type2",
        +      "type3",
        +      "type4"
        +    ],
        +    "type": "string"
        +  },
        +  "type": "array",
        +  "uniqueItems": true
        +}
  2. 4 tool updatesv5.2.0
    • Changedcheck_current_directory3 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / limit / default
        Added value: +100
      • changedInput schema / properties / limit / description
        Previous value: -"Maximum number of clones to include in the response (default 100); 'clones' always carries the untruncated total"New value: +"Maximum number of clones to include in the response. 'clones' always carries the untruncated total, so a small limit still tells you how much was found."
    • Changedcheck_duplication6 fields changed
      • changedInput schema / properties / code / description
        Previous value: -"Source code snippet to check"New value: +"The source code to check, verbatim (whole functions or blocks work best; it must reach the server's --min-tokens threshold, 50 tokens by default)"
      • changedInput schema / properties / format / description
        Previous value: -"Language format (javascript, python, ...) or file extension (js, py, ...); see `cpd --list`"New value: +"Language of the snippet: a jscpd format name such as 'javascript', 'typescript', 'python', 'java', or a file extension such as 'js', 'py' (run `jscpd --list` for all 224). Unknown values return an error naming the problem."
      • addedInput schema / properties / format / examples
        Added value: +[
        +  "javascript",
        +  "python",
        +  "ts"
        +]
      • addedInput schema / properties / limit / default
        Added value: +100
      • changedInput schema / properties / limit / description
        Previous value: -"Maximum matches to include in the response (default 100); 'count' always carries the untruncated total"New value: +"Maximum number of duplications to include in the response. 'count' always carries the untruncated total, so a small limit still tells you how much was found."
      • addedInput schema / properties / similarity
        Added value: +{
        +  "description": "Also return project functions whose syntax-tree structure is similar to the snippet's functions, when the similarity ratio reaches this value. 1 means exact matches only (no 'similar' section); 0.85 catches renames, literal changes and one-line edits; 0.7 tolerates a couple of added or removed statements. Defaults to the server's --similarity setting (1 unless configured). JavaScript/TypeScript only; other formats ignore it.",
        +  "examples": [
        +    0.85
        +  ],
        +  "exclusiveMinimum": 0,
        +  "maximum": 1,
        +  "type": "number"
        +}
    • Changedget_file_clones4 fields changed
      • addedInput schema / properties / limit / default
        Added value: +100
      • changedInput schema / properties / limit / description
        Previous value: -"Maximum clones to include in the response (default 100); 'clones' always carries the untruncated total"New value: +"Maximum number of clones to include in the response. 'clones' always carries the untruncated total, so a small limit still tells you how much was found."
      • changedInput schema / properties / path / description
        Previous value: -"File path, relative to the scan root (as shown in other tool results) or absolute"New value: +"The file to inspect, either relative to the scan root exactly as paths appear in other tool results (e.g. 'src/cart.js') or absolute"
      • addedInput schema / properties / path / examples
        Added value: +[
        +  "src/cart.js"
        +]
    • Changedget_statistics1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
  3. 4 tool updatesv0.1.0
    • First observedcheck_current_directory
    • First observedcheck_duplication
    • First observedget_file_clones
    • First observedget_statistics

TDQS

A4.4/5.0

Scored across 5 tools

Disambiguation5/5

The five tools target clearly distinct inputs and outputs: snippet check, file clone listing, folder comparison, statistics reporting, and rescanning. The descriptions explicitly clarify boundaries, such as 'last scan' vs 'fresh scan', leaving little room for misselection.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern (get_statistics, check_duplication, get_file_clones, check_current_directory, compare_folders). No mixed conventions or vague verbs.

Tool Count5/5

Five tools neatly cover the duplication analysis domain: scan, stats, snippet check, file clones, and folder comparison. Each tool has a clear role, and the set is neither thin nor bloated.

Completeness4/5

Core workflows are covered, but there is no tool to retrieve the full clone list from the last scan without rescanning (check_current_directory always rescans), and no way to adjust parameters like min-tokens. These are minor gaps that agents can work around.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Framework-aware code intelligence MCP server that builds a cross-language dependency graph from source code. 53 integrations (Laravel, Django, Rails, Spring, NestJS, Next.js, and more) across 68 languages. 100+ tools for navigation, impact analysis, refactoring, security scanning, session memory, and CI/PR reports — up to 97% token reduction.
    29
    7,155 npm
    198
    MIT
  • A
    license
    B
    quality
    A
    maintenance
    An MCP code-intelligence server for AI agents with pre-indexed AST cache, 62 MCP tools, and TOON-compressed output, enabling token-efficient code analysis and project health grading entirely locally.
    9
    1,170 PyPI
    61
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A local MCP server that indexes TypeScript/JavaScript projects and returns budget-aware, dependency-optimized context packs for AI coding assistants.
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Token-efficient MCP server for multi-language project analysis (Java, TypeScript, JavaScript, Markdown, Python) with plugins, semantic search, and static analysis.
    MIT