Skip to main content
Glama
skmalikllc

contact-dedupe

by skmalikllc

contact-dedupe — MCP server

An MCP (Model Context Protocol) server that lets Claude, or any MCP client, work on a contact export: profile it, find the rows that are the same person, and write a merged file — with every conflicting value reported instead of quietly dropped.

Built for the job I get asked for most often: a CRM or Google Contacts export where the same person appears three times as Ali Raza, Raza, Ali and Ali R., with the phone number on one row and the email on another.

Tools

Tool

What it does

profile_csv

rows, columns, fill rate per column, and the detected name/email/phone/company mapping

find_duplicates

duplicate groups with the evidence behind each match — read-only

dedupe_csv

merges each group into one row, writes a cleaned CSV (dry_run supported)

compare_records

scores a single pair 0–1 and lists the signals, for tuning the threshold

Related MCP server: MCP Data Integration Server

Matching rules

Exact-match dedupe misses most real duplicates, and fuzzy name matching alone merges people who merely share a surname. So the score comes from several signals:

  • EmailAli.Raza+crm@gmail.com and aliraza@gmail.com are the same mailbox, but a.b@outlook.com and ab@outlook.com are not; the dot rule is a Gmail behaviour, not a general one.

  • Phone — compared on the last 9 digits, so +92 300 1234567, 0300-1234567 and 00923001234567 line up without guessing a country.

  • Name — accent- and punctuation-insensitive, order-insensitive (Raza, Ali = Ali Raza), Levenshtein for the rest.

  • Company — only ever a tie-breaker on top of a name match.

A shared email or phone is strong evidence; a similar name on its own is not enough to merge. Groups form transitively (A–B by phone, B–C by email puts all three together), and the threshold is a parameter, not a hard-coded constant.

Merging keeps the most complete row as the base, fills blanks from the others, prefers the longer value when one contains the other (Beta FoodsBeta Foods Pvt Ltd), and reports everything else as a conflict.

Install

npm install

Register it with an MCP client (Claude Desktop / Claude Code):

{
  "mcpServers": {
    "contact-dedupe": {
      "command": "node",
      "args": ["/absolute/path/to/csv-dedupe-mcp/src/server.mjs"]
    }
  }
}

Try it

node test/server.e2e.mjs

Runs the real stdio protocol against sample/contacts.csv (10 rows, messy on purpose) and prints:

duplicate groups: 3 | rows involved: 7
  group 1: rows 2, 3, 4 — same email + same name + same company ; same phone
  group 2: rows 5, 6 — same email + same name
  group 3: rows 8, 9 — same email
dedupe_csv (dry run) → { input: 10, output: 6, removed: 4 }
conflicts flagged: Company: kept "Beta Foods Pvt Ltd" / dropped "Beta Foods" | …

Tests

node --test test/dedupe.test.js   # 9 tests: normalisation, scoring, grouping, merge, CSV
node test/server.e2e.mjs          # protocol-level run over stdio

Layout

src/server.mjs   MCP server (stdio) — tool definitions and zod schemas
src/dedupe.js    matching, grouping and merge logic (no protocol code)
src/csv.js       RFC 4180 CSV reader/writer, no dependencies
sample/          messy sample export
test/            unit tests + end-to-end MCP client test

The matching logic holds no MCP code on purpose — the rules that decide whether two people are the same are the part worth testing on their own.

Available Tools

4 tools
compare_recordsCompare two recordsB

Score a single pair 0-1 and list the signals behind the score — useful for tuning the threshold.

ParametersJSON Schema
NameRequiredDescriptionDefault
aYesFirst record as field/value pairs
bYes
fieldsNo

TDQS

B3.2/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden. It states the tool 'scores' a pair, which implies a read-only computation, but it does not explicitly disclose that it has no side effects, nor does it explain what kind of signals are returned or how the score is computed. The phrase 'list the signals' is vague about the content and format. This is a significant gap for a tool with no annotation support.

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 concise, one sentence with a purposeful start ('Score a single pair'). It efficiently communicates the core action and output. It could be slightly more informative without becoming verbose, but as is, it is appropriately sized and front-loaded.

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

Completeness2/5

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

The tool has no output schema, no annotations, and limited schema coverage. The description only provides the high-level purpose and a vague reference to signals. It does not explain the return format beyond a 0-1 score, nor does it clarify parameter semantics or any edge cases (e.g., missing fields, mismatched field names). An agent trying to call this tool correctly would likely need additional documentation.

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

Parameters1/5

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

The input schema has low description coverage (33%) – only parameter 'a' is described, while 'b' and 'fields' lack descriptions. The tool description does not mention any parameters or explain their roles. It only says 'Score a single pair', which implicitly refers to a and b, but does not clarify what 'fields' does or how it affects scoring. Given the low schema coverage, the description should compensate, but it does not.

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 states a specific verb (score) and a resource (a single pair) and clarifies the output (0-1 score plus signals). This clearly distinguishes it from sibling tools like find_duplicates (which scans many records) and dedupe_csv (which performs deduplication). An agent can immediately understand what the tool does and how it differs from alternatives.

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?

The description mentions a concrete use case: 'useful for tuning the threshold'. This gives context for when to use the tool. However, it does not explicitly mention alternatives or state when not to use it. The sibling names imply other tools for bulk operations, but the description itself does not draw that contrast. Still, the stated purpose is clear enough for an agent to infer its role.

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

dedupe_csvDeduplicate a CSVB

Merge duplicate groups into one row each and write a cleaned CSV. Conflicting values are reported, never dropped silently.

ParametersJSON Schema
NameRequiredDescriptionDefault
outNoOutput path; defaults to <name>.deduped.csv
fileYes
fieldsNo
dry_runNo
thresholdNo

TDQS

B3/5.0
Behavior3/5

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

With no annotations, the description carries the behavioral disclosure burden and does add one useful trait: conflicting values are reported, never silently dropped. However, it does not clarify dry_run behavior, threshold semantics, overwrite behavior, or what 'reported' means, so significant behavior remains undisclosed.

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?

Two sentences with no filler: the primary action is front-loaded and the conflict-handling guarantee is stated separately. Every phrase earns its place.

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

Completeness2/5

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

The tool has five parameters, a nested fields object, no output schema, and no annotations, so the description must carry more context. It explains the core output and conflict safety but omits threshold meaning, dry_run effects, field mapping, and required input details, making it insufficient for correct invocation without additional inference.

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

Parameters2/5

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

Schema description coverage is only 20% (only 'out' has a description), so the description must compensate for file, fields, dry_run, and threshold. It does not explain any of these parameters or how fields/threshold control deduplication, leaving key invocation details undocumented.

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: merge duplicate groups into one row each and write a cleaned CSV. It is clear enough to distinguish from find_duplicates, which likely only locates duplicates, though it never explicitly names that sibling or states the contrast.

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

Usage Guidelines2/5

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

There is no guidance on when to use this tool versus profile_csv, find_duplicates, or compare_records. The description implies a deduplication workflow but provides no conditions, exclusions, or alternative tool routing, leaving the agent to infer applicability.

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

find_duplicatesFind duplicate groupsB

Group rows that look like the same person and explain why, without changing the file.

ParametersJSON Schema
NameRequiredDescriptionDefault
fileYes
limitNo
fieldsNo
thresholdNo0-1; lower finds more, with more false positives

TDQS

B3.2/5.0
Behavior3/5

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

With no annotations, the description carries the burden of behavioral disclosure. It does disclose the key read-only behavior ('without changing the file') and hints at the reasoning output ('explain why'), but it omits other behaviors such as fuzzy matching sensitivity, threshold effect, or how the limit applies. This is a minimal disclosure, though not contradictory.

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 a single efficient sentence that front-loads the core purpose and key constraint. No redundant words or filler.

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

Completeness2/5

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

With no output schema and four parameters, the description is incomplete. It does not describe the output format (beyond 'explain why'), nor does it clarify how to specify fields, the meaning of limit, or how threshold works beyond the schema's minimal note. An agent would need to infer too much.

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

Parameters2/5

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

Schema description coverage is only 25% (only 'threshold' has a description). The description adds no parameter-level detail, failing to explain 'file', 'limit', or the 'fields' object. Since the schema is sparse, the description should compensate but does not.

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 clearly states the tool groups rows that look like the same person and explains why, while explicitly noting it does not change the file. This distinguishes it from a modification tool like dedupe_csv, though it does not name sibling tools directly. The verb 'Group' is specific enough.

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

Usage Guidelines3/5

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

The phrase 'without changing the file' implies this is for analysis rather than modification, but there is no explicit guidance on when to choose this over siblings like dedupe_csv or compare_records. The context is clear but exclusions and alternatives are not spelled out.

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

profile_csvProfile a CSVA

Row count, columns, fill rate per column and the detected name/email/phone/company mapping.

ParametersJSON Schema
NameRequiredDescriptionDefault
fileYesPath to the CSV file

TDQS

A3.6/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It implies a read-only analysis operation by listing computed metrics, but does not explicitly state that the file is not modified, nor does it disclose any limitations (e.g., encoding assumptions, large-file performance, or the heuristic nature of the mapping detection). This is adequate but not comprehensive.

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 a single, compact sentence that front-loads the core outputs and contains no filler. It conveys all essential information about what the tool returns in a highly efficient manner.

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?

Given there is no output schema, the description enumerates the return values (row count, columns, fill rate, mapping), which is sufficient for an agent to understand what to expect. The main omission is any mention of error scenarios or assumptions about the input file format, but these are secondary for a straightforward profiling tool.

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?

The schema covers the single `file` parameter with a description ('Path to the CSV file'), so schema coverage is 100%. The tool description does not add any additional meaning about the parameter beyond what the schema provides, so the baseline of 3 applies.

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 states a specific action ('Profile a CSV') and enumerates the exact outputs: row count, columns, fill rate, and detected name/email/phone/company mapping. This clearly distinguishes it from siblings like dedupe_csv or compare_records, which focus on data cleaning or comparison rather than structural analysis.

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

Usage Guidelines2/5

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

The description gives no guidance on when to use this tool versus find_duplicates, dedupe_csv, or compare_records. It does not mention context, prerequisites, or situations where a sibling would be more appropriate, leaving the agent to infer usage from the tool name and description alone.

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. 4 tool updatesv1.0.0
    • First observedcompare_records
    • First observeddedupe_csv
    • First observedfind_duplicates
    • First observedprofile_csv

TDQS

A3.7/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct role: profiling the CSV, finding duplicate groups, performing the deduplication, and comparing individual pairs. No overlap in purpose or output.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case: profile_csv, find_duplicates, dedupe_csv, compare_records. The style is uniform and predictable.

Tool Count5/5

Four tools is exactly right for a focused deduplication workflow. Each tool serves a distinct step in the process without unnecessary bloat or missing core functionality.

Completeness5/5

The workflow is complete: profile to understand data, identify duplicates, execute deduplication, and fine-tune via pair scoring. No obvious dead ends or required operations that agents cannot perform.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Comprehensive CSV processing MCP server with 40+ operations for data manipulation, analysis, and validation. Features auto-save, undo/redo, and handles GB+ files
    39
    25
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables reading, normalizing, validating, merging, and exporting data from Excel, CSV, JSON, and SQLite sources into a unified schema, with tools exposed via FastMCP.
    1
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP-compatible AI clients to validate healthcare claims data quality by running completeness, integrity, and temporal checks on CSV files via five callable tools, including profiling and full scans.
    -