Skip to main content
Glama
GeiserX

duplicacy-mcp

by GeiserX

Features

  • Reads the metrics of duplicacy-exporter and serves them over MCP.

  • One call answers "are my backups OK?": get_backup_overview gives every backup a verdict (ok, running, stale, never, failed) with a reason.

  • Speaks MCP 2026-07-28 (server/discover, stateless requests) and every earlier revision down to 2024-11-05 (the initialize handshake) from the same binary, over stdio and Streamable HTTP. Clients that still use the old handshake keep working.

  • Read-only by design: every tool and resource only reads the exporter, so there is no read-only flag to set. Every tool carries readOnlyHint, a title, an output schema and structured results.

  • HTTP listens on 127.0.0.1:8080 by default. On any other address it refuses to start without a bearer token, rejects cross-origin browser requests and caps request bodies.

  • Ships as Go binaries for several platforms (GoReleaser), a Docker image and an npm wrapper.

Related MCP server: duplicati-mcp

Tools and resources

Tool

What it answers

get_backup_overview

Health of every backup in one call: verdict, reason, age of the last success. max_age_hours (default 26) sets when a backup is stale.

list_snapshots

Every snapshot ID, storage target and machine, for use as filter values.

get_backup_status

State and last-run details of one snapshot, per storage target and machine.

get_backup_history

The last completed run of one snapshot. The exporter keeps only the last run.

get_prune_status

Whether a prune is running and when the last one succeeded, per storage target.

get_storage_usage

Storage size and chunks, and revisions per snapshot, from the exporter's storage poller.

Resources: duplicacy://status, duplicacy://progress and duplicacy://health. Parameters and output fields are on Usage.

Install

The npm package runs the server over stdio; set DUPLICACY_EXPORTER_URL to your exporter.

Claude Code

claude mcp add --transport stdio --env DUPLICACY_EXPORTER_URL=http://localhost:9750 duplicacy -- npx -y duplicacy-mcp

Claude Desktop (claude_desktop_config.json) and Cursor (~/.cursor/mcp.json)

{
  "mcpServers": {
    "duplicacy": {
      "command": "npx",
      "args": ["-y", "duplicacy-mcp"],
      "env": { "DUPLICACY_EXPORTER_URL": "http://localhost:9750" }
    }
  }
}

VS Code (.vscode/mcp.json)

{
  "servers": {
    "duplicacy": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "duplicacy-mcp"],
      "env": { "DUPLICACY_EXPORTER_URL": "http://localhost:9750" }
    }
  }
}

Codex (~/.codex/config.toml)

[mcp_servers.duplicacy]
command = "npx"
args = ["-y", "duplicacy-mcp"]
env = { DUPLICACY_EXPORTER_URL = "http://localhost:9750" }

npm 12, pnpm and Bun skip install scripts, so the wrapper downloads and verifies the binary on first start. Versions up to 0.1.2 relied on the install script alone; with npm 12 run them as npx -y --allow-scripts=duplicacy-mcp duplicacy-mcp.

Docker (Streamable HTTP)

export MCP_AUTH_TOKEN=$(openssl rand -hex 32)
docker run -d -p 127.0.0.1:8080:8080 -e MCP_AUTH_TOKEN \
  -e DUPLICACY_EXPORTER_URL=http://duplicacy-exporter:9750 drumsergio/duplicacy-mcp:v0.2.0
claude mcp add --transport http duplicacy http://127.0.0.1:8080/mcp --header "Authorization: Bearer $MCP_AUTH_TOKEN"

The image listens on 0.0.0.0:8080 inside the container, so it will not start without MCP_AUTH_TOKEN (or MCP_ALLOW_UNAUTHENTICATED=true behind a reverse proxy that authenticates). Compose, a global npm install and a local build are in Getting started; every variable is in Configuration.

Documentation

  • Getting started: Docker Compose, npm, local build, first run

  • Configuration: environment variables, HTTP security, client config for stdio and HTTP

  • Usage: tools, parameters, output fields and resources

  • Development: testing with Inspector, credits, contributing

  • Related projects: the Duplicacy family, other MCP servers, registry listings

Part of the Duplicacy family: duplicacy-exporter, duplicacy-cli-cron, duplicacy-ha, duplicacy-container.

License

GPL-3.0-or-later

Available Tools

6 tools
get_backup_historyLast backup runA
Read-onlyIdempotent

Details of the last completed run of one Duplicacy snapshot: duration in seconds, files total and new, bytes uploaded and new, new chunks, revision, exit_code (0 = success, null = unknown). The exporter keeps only the last run, so this is not a list of past runs. Get valid IDs from list_snapshots.

NameRequiredDescriptionDefault
machineNoOnly this machine, exactly as list_snapshots returns it in machines, for example "nas". Omit for all.
snapshot_idYesDuplicacy snapshot ID, exactly as list_snapshots returns it, for example "photos".
storage_targetNoOnly this storage target, exactly as list_snapshots returns it in storage_targets, for example "b2". Omit for all.

Output Schema

NameRequiredDescription
countYes
backupsYes

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, non-destructive, and closed-world, so the safety profile is covered. The description adds genuine value beyond them: the exporter retains only the last run (a data-retention constraint the annotation cannot express) and exit_code semantics including null = unknown.

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 tight sentences; the return-value inventory and the last-run caveat are front-loaded, and the ID-source tip closes it with no filler.

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?

An output schema exists, so the return value need not be enumerated, yet the description still summarizes the key fields helpfully. The last-run limitation and ID sourcing are covered; only an explicit contrast with get_backup_status/get_backup_overview is missing.

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 all three parameters including machine and storage_target are documented in the schema itself. The description only reinforces that IDs come from list_snapshots, which the schema already states. Baseline 3 is appropriate.

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?

States a specific verb and resource ('Details of the last completed run of one Duplicacy snapshot') and enumerates exactly what is returned (duration, files, bytes, chunks, revision, exit_code). It explicitly rules out the misreading that this is a history list, though it does not distinguish itself from get_backup_status or get_backup_overview.

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 prerequisite and routing hint: 'Get valid IDs from list_snapshots.' It also scopes usage by warning the exporter keeps only the last run, so agents won't expect historical data. It stops short of saying when to prefer this over get_backup_status, but the context is clear.

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

get_backup_overviewBackup health overviewA
Read-onlyIdempotent

Health of every backup in one call. Each snapshot, storage target and machine gets a verdict: ok, running, stale (last success older than max_age_hours), never (no successful run) or failed (last exit code not 0), with a reason and the age of the last success. status is ok, attention or no_data. Use this to answer "are my backups OK?"; use get_backup_status for the details of one snapshot.

NameRequiredDescriptionDefault
machineNoOnly this machine, exactly as list_snapshots returns it in machines, for example "nas". Omit for all.
snapshot_idNoDuplicacy snapshot ID, exactly as list_snapshots returns it, for example "photos".
max_age_hoursNoA backup whose last success is older than this many hours is stale. Default 26, which suits daily backups.
storage_targetNoOnly this storage target, exactly as list_snapshots returns it in storage_targets, for example "b2". Omit for all.

Output Schema

NameRequiredDescription
countsYes
statusYesok when every backup is ok or running, attention when any is stale, never ran or failed, no_data when the exporter reports no backups
backupsYes
summaryYes
exporterYes
checked_atYesWhen the overview was computed, RFC 3339 in UTC
max_age_hoursYesA backup whose last success is older than this is stale

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare the tool as read-only, idempotent and non-destructive. The description adds meaningful behavioral context: the verdict categories (ok, running, stale, never, failed), what stale means in relation to max_age_hours, and the overall status values (ok, attention, no_data). It does not discuss cost or latency, but the added output semantics are substantive.

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 dense and front-loaded: the main purpose is stated first, followed by verdict semantics, status values, and the sibling routing. Every sentence carries information useful to an agent.

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 an output schema, fully documented parameters and annotation coverage, the description only needs to supply purpose, usage and verdict meaning. It does so completely, including a clear alternative for a different use case.

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 all four parameters are already documented in the schema, including max_age_hours and its default. The description states the stale rule but does not add syntax or format details 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 resource and scope: it returns the health of every backup in one call, covering each snapshot, storage target and machine. It also distinguishes itself from get_backup_status, so an agent can identify it without opening the schema.

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?

It explicitly names the question this tool answers ("are my backups OK?") and directs the agent to get_backup_status for details about a single snapshot. That is explicit when-to-use and alternative routing.

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

get_backup_statusBackup statusA
Read-onlyIdempotent

Current state and last-run details of one Duplicacy snapshot: running, exit_code (0 = success, null = unknown), last_success (RFC 3339, UTC), duration in seconds, files and bytes. A snapshot backed up to several storage targets or from several machines returns one row each. Get valid IDs from list_snapshots. For a health check across all backups use get_backup_overview instead.

NameRequiredDescriptionDefault
machineNoOnly this machine, exactly as list_snapshots returns it in machines, for example "nas". Omit for all.
snapshot_idYesDuplicacy snapshot ID, exactly as list_snapshots returns it, for example "photos".
storage_targetNoOnly this storage target, exactly as list_snapshots returns it in storage_targets, for example "b2". Omit for all.

Output Schema

NameRequiredDescription
countYes
backupsYes

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, non-destructive, closed-world, so the safety profile is covered. The description adds genuine context beyond that: exit_code semantics (0 = success, null = unknown), RFC 3339 UTC timestamp format, and the row-multiplication behavior when a snapshot spans multiple storage targets or machines. It stops short of stating pagination or volume expectations, which keeps it from a 5.

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?

Four tight sentences, front-loaded with what is returned before the ID-sourcing and alternative-tool guidance. No restatement of the title and no filler; each sentence carries either field semantics or routing information.

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?

Output schema exists, so return shape needn't be re-explained, yet the description still clarifies the ambiguous value encodings (exit_code null, RFC 3339 UTC) that an agent needs to interpret results. With read-only annotations and full schema coverage, nothing material is missing for correct invocation.

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 baseline is 3. The description earns above baseline by explaining that a snapshot backed up to several storage targets or from several machines returns one row each — which is precisely the semantics of the optional machine and storage_target filters, telling the agent why it would narrow them rather than just what they are.

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+resource (current state and last-run details of one Duplicacy snapshot) and enumerates the returned fields: running, exit_code, last_success, duration, files, bytes. It also distinguishes itself from list_snapshots (ID source) and get_backup_overview (aggregate health check), so an agent can separate it from siblings without opening schemas.

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 explicit routing: 'Get valid IDs from list_snapshots' as a prerequisite and 'For a health check across all backups use get_backup_overview instead' as the when-not case with a named alternative. This is exactly the when/when-not/alternative pattern, leaving nothing to inference.

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

get_prune_statusPrune statusA
Read-onlyIdempotent

Whether a prune is running and when the last one succeeded (RFC 3339, UTC), per storage target and machine. An unknown storage_target is an error that lists the known ones.

NameRequiredDescriptionDefault
storage_targetNoOnly this storage target, exactly as list_snapshots returns it in storage_targets, for example "b2". Omit for all.

Output Schema

NameRequiredDescription
countYes
prunesYes

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already cover safety (read-only, idempotent, non-destructive), so the bar is lower. The description usefully adds error behavior—an unknown storage_target is an error listing known targets—and specifies UTC/RFC 3339 timestamps, which are behavioral details not present in the annotations.

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 tightly written sentences with no waste. The core purpose is front-loaded, followed by the most important edge-case behavior.

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?

For a simple read-only status tool with an output schema and rich annotations, the description covers what the tool reports, timestamp format, grouping dimensions, and error behavior. Nothing needed to call it correctly is missing.

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 documents the storage_target parameter well. The description adds meaning beyond the schema by stating that an unknown storage_target produces an error listing known targets, which helps the agent understand invalid-input behavior.

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 resource (prune status) and exactly what it reports: whether a prune is running and when the last one succeeded, per storage target and machine. This clearly distinguishes it from backup-history siblings, but it does not explicitly name or contrast with any sibling tool.

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 explains what the tool returns but gives no guidance on when to use it versus alternatives, nor any exclusions or preconditions. Use is only implied by the monitoring nature of the data.

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

get_storage_usageStorage usageA
Read-onlyIdempotent

Size in bytes and chunk count of each storage, and how many revisions each snapshot keeps, as the exporter's storage poller last saw them. Empty, with a note, when the poller is off.

NameRequiredDescriptionDefault
machineNoOnly this machine, exactly as list_snapshots returns it in machines, for example "nas". Omit for all.
snapshot_idNoDuplicacy snapshot ID, exactly as list_snapshots returns it, for example "photos".
storage_targetNoOnly this storage target, exactly as list_snapshots returns it in storage_targets, for example "b2". Omit for all.

Output Schema

NameRequiredDescription
noteNo
storagesYes
snapshotsYes
poller_errors_totalYesPoller errors since the exporter started
poller_last_successNoTime of the poller's last fully successful cycle, RFC 3339 in UTC

TDQS

A3.6/5.0
Behavior4/5

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

Annotations already declare this a safe, idempotent read, so the bar is lower, and the description still adds real value: the numbers are a stale poller snapshot rather than live data, and an empty result with an explanatory note is returned when the poller is disabled. That is exactly the kind of caveat an agent needs before reporting metrics to a user.

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?

Two tight sentences with no filler; the most decision-relevant fact (staleness) and the failure mode (poller off) are both front-loaded. The opening sentence is a grammatical fragment that takes a second read, which keeps it from a 5.

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 a full output schema and complete in-schema parameter docs, the description only needs to supply behavioral caveats — and it does: data freshness and the empty-result condition. Nothing an agent needs to call and interpret this correctly is missing.

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 coverage is 100% and each of the three filters is documented in-schema with examples and an 'omit for all' default. The description adds no additional parameter meaning, so the baseline 3 applies.

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 names the resource precisely — per-storage size in bytes and chunk count, plus per-snapshot revision retention — which is distinct from the status/history siblings. It omits an explicit verb (it's a noun-phrase fragment), but the returned data is unambiguous.

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 statement of when to reach for this tool versus get_backup_overview, get_backup_status, or list_snapshots, and no mention that the three filters can scope the result. The only contextual note is a data-availability caveat, not usage guidance.

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

list_snapshotsList snapshotsA
Read-onlyIdempotent

Every snapshot ID, storage target and machine the exporter reports, sorted. backups lists each snapshot_id, storage_target and machine combination. Call this first to get valid values for the snapshot_id, storage_target and machine arguments of the other tools.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
countYesNumber of snapshot IDs
backupsYesEvery snapshot_id, storage_target and machine combination with backup metrics
machinesYesEvery machine seen, sorted
snapshot_idsYesEvery snapshot ID the exporter has seen, sorted
storage_targetsYesEvery storage target seen, sorted

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, non-destructive and closed-world, so the safety profile is covered. The description adds that results are sorted and that the payload is exposed under a 'backups' key, which annotations cannot convey. It stops short of noting cost or volume, hence a 4.

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?

Front-loaded with the resource and return fields in the first sentence, and the call-ordering advice comes last where it belongs. The middle sentence ('backups lists each snapshot_id, storage_target and machine combination') largely restates the first, costing a little density.

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 an output schema present, return values need not be detailed, and the description still names the key fields and the 'backups' container. A zero-arg read tool with annotations fully covered needs no more than this.

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?

Zero parameters, so there is nothing to disambiguate; baseline 4 applies. The description correctly frames the tool as an unfiltered enumeration, which reinforces that no arguments are accepted.

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 resource (snapshots) and the exact fields returned (snapshot ID, storage target, machine), plus ordering. It is clearly distinguishable from the get_* siblings, which return status/overview rather than the raw enumerated set.

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?

Explicitly says 'Call this first to get valid values for the snapshot_id, storage_target and machine arguments of the other tools' — a concrete ordering rule plus the reason. No alternatives are left to inference.

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. 6 tool updatesv0.2.1
    • Changedget_backup_history7 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / machine
        Added value: +{
        +  "description": "Only this machine, exactly as list_snapshots returns it in machines, for example \"nas\". Omit for all.",
        +  "maxLength": 256,
        +  "type": "string"
        +}
      • changedInput schema / properties / snapshot_id / description
        Previous value: -"The snapshot ID to query history for"New value: +"Duplicacy snapshot ID, exactly as list_snapshots returns it, for example \"photos\"."
      • addedInput schema / properties / snapshot_id / maxLength
        Added value: +256
      • addedInput schema / properties / snapshot_id / minLength
        Added value: +1
      • addedInput schema / properties / storage_target
        Added value: +{
        +  "description": "Only this storage target, exactly as list_snapshots returns it in storage_targets, for example \"b2\". Omit for all.",
        +  "maxLength": 256,
        +  "type": "string"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "backups": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "exit_code": {
        +            "description": "Exit code of the last run: 0 is success, null means unknown",
        +            "type": [
        +              "null",
        +              "integer"
        +            ]
        +          },
        +          "last_bytes_new": {
        +            "type": "number"
        +          },
        +          "last_bytes_uploaded": {
        +            "type": "number"
        +          },
        +          "last_chunks_new": {
        +            "type": "number"
        +          },
        +          "last_duration_seconds": {
        +            "description": "Duration of the last run, in seconds",
        +            "type": "number"
        +          },
        +          "last_files_new": {
        +            "type": "number"
        +          },
        +          "last_files_total": {
        +            "type": "number"
        +          },
        +          "last_revision": {
        +            "type": "number"
        +          },
        +          "last_success": {
        +            "description": "Time of the last successful run, RFC 3339 in UTC",
        +            "type": "string"
        +          },
        +          "machine": {
        +            "type": "string"
        +          },
        +          "snapshot_id": {
        +            "type": "string"
        +          },
        +          "storage_target": {
        +            "type": "string"
        +          },
        +          "total_bytes_uploaded": {
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "snapshot_id",
        +          "storage_target",
        +          "machine",
        +          "last_duration_seconds",
        +          "last_files_total",
        +          "last_files_new",
        +          "last_bytes_uploaded",
        +          "last_bytes_new",
        +          "last_chunks_new",
        +          "exit_code",
        +          "last_revision",
        +          "total_bytes_uploaded"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "count": {
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "backups",
        +    "count"
        +  ],
        +  "type": "object"
        +}
    • Addedget_backup_overview
    • Changedget_backup_status7 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / machine
        Added value: +{
        +  "description": "Only this machine, exactly as list_snapshots returns it in machines, for example \"nas\". Omit for all.",
        +  "maxLength": 256,
        +  "type": "string"
        +}
      • changedInput schema / properties / snapshot_id / description
        Previous value: -"The snapshot ID to query status for"New value: +"Duplicacy snapshot ID, exactly as list_snapshots returns it, for example \"photos\"."
      • addedInput schema / properties / snapshot_id / maxLength
        Added value: +256
      • addedInput schema / properties / snapshot_id / minLength
        Added value: +1
      • addedInput schema / properties / storage_target
        Added value: +{
        +  "description": "Only this storage target, exactly as list_snapshots returns it in storage_targets, for example \"b2\". Omit for all.",
        +  "maxLength": 256,
        +  "type": "string"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "backups": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "exit_code": {
        +            "description": "Exit code of the last run: 0 is success, anything else is a failure, null means the exporter has not reported one",
        +            "type": [
        +              "null",
        +              "integer"
        +            ]
        +          },
        +          "last_bytes_new": {
        +            "description": "New bytes in the last run",
        +            "type": "number"
        +          },
        +          "last_bytes_uploaded": {
        +            "description": "Bytes uploaded by the last run",
        +            "type": "number"
        +          },
        +          "last_chunks_new": {
        +            "description": "New chunks in the last run",
        +            "type": "number"
        +          },
        +          "last_chunks_size_bytes": {
        +            "description": "Compressed size of the chunks the last snapshot references, in bytes",
        +            "type": "number"
        +          },
        +          "last_duration_seconds": {
        +            "description": "Duration of the last run, in seconds",
        +            "type": "number"
        +          },
        +          "last_files_new": {
        +            "description": "Files new in the last run",
        +            "type": "number"
        +          },
        +          "last_files_size_bytes": {
        +            "description": "Logical size of all files in the last snapshot, in bytes",
        +            "type": "number"
        +          },
        +          "last_files_total": {
        +            "description": "Files in the last snapshot",
        +            "type": "number"
        +          },
        +          "last_revision": {
        +            "description": "Revision number created by the last run",
        +            "type": "number"
        +          },
        +          "last_success": {
        +            "description": "Time of the last successful run, RFC 3339 in UTC",
        +            "type": "string"
        +          },
        +          "machine": {
        +            "description": "Machine that runs the backup",
        +            "type": "string"
        +          },
        +          "running": {
        +            "description": "True while a backup is in progress",
        +            "type": "boolean"
        +          },
        +          "snapshot_id": {
        +            "description": "Duplicacy snapshot ID",
        +            "type": "string"
        +          },
        +          "storage_target": {
        +            "description": "Storage the snapshot is backed up to",
        +            "type": "string"
        +          },
        +          "total_bytes_uploaded": {
        +            "description": "Bytes uploaded since the exporter started counting",
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "snapshot_id",
        +          "storage_target",
        +          "machine",
        +          "running",
        +          "exit_code"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "count": {
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "backups",
        +    "count"
        +  ],
        +  "type": "object"
        +}
    • Changedget_prune_status4 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / storage_target / description
        Previous value: -"(optional) Filter prune status to a specific storage target"New value: +"Only this storage target, exactly as list_snapshots returns it in storage_targets, for example \"b2\". Omit for all."
      • addedInput schema / properties / storage_target / maxLength
        Added value: +256
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "count": {
        +      "type": "integer"
        +    },
        +    "prunes": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "last_success": {
        +            "description": "Time of the last successful prune, RFC 3339 in UTC",
        +            "type": "string"
        +          },
        +          "machine": {
        +            "type": "string"
        +          },
        +          "running": {
        +            "description": "True while a prune is in progress",
        +            "type": "boolean"
        +          },
        +          "storage_target": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "storage_target",
        +          "machine",
        +          "running"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "prunes",
        +    "count"
        +  ],
        +  "type": "object"
        +}
    • Addedget_storage_usage
    • Changedlist_snapshots2 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "backups": {
        +      "description": "Every snapshot_id, storage_target and machine combination with backup metrics",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "machine": {
        +            "type": "string"
        +          },
        +          "snapshot_id": {
        +            "type": "string"
        +          },
        +          "storage_target": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "snapshot_id",
        +          "storage_target",
        +          "machine"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "count": {
        +      "description": "Number of snapshot IDs",
        +      "type": "integer"
        +    },
        +    "machines": {
        +      "description": "Every machine seen, sorted",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "snapshot_ids": {
        +      "description": "Every snapshot ID the exporter has seen, sorted",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "storage_targets": {
        +      "description": "Every storage target seen, sorted",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "snapshot_ids",
        +    "count",
        +    "backups",
        +    "storage_targets",
        +    "machines"
        +  ],
        +  "type": "object"
        +}
  2. 4 tool updatesv0.1.0
    • First observedget_backup_history
    • First observedget_backup_status
    • First observedget_prune_status
    • First observedlist_snapshots

TDQS

A4.1/5.0

Scored across 6 tools

Disambiguation4/5

The tools mostly have clearly distinct monitoring purposes: overview is an aggregate health check, status is one snapshot, and history is the last completed run. The main ambiguity is between get_backup_status and get_backup_history, since both return last-run details, but the descriptions explicitly distinguish current state versus completed-run history.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern: get_backup_history, get_backup_overview, get_backup_status, get_prune_status, get_storage_usage, and list_snapshots. The use of list_snapshots instead of get_snapshots is still a conventional verb_noun choice and does not break readability.

Tool Count5/5

Six tools is well-scoped for a read-only Duplicacy backup monitoring server. Each tool maps to a distinct monitoring concern: discovery, per-snapshot status/history, aggregate health, prune status, and storage usage.

Completeness4/5

The surface covers the core monitoring workflows: discovering snapshots, checking backup health, inspecting a snapshot, reviewing last-run history, prune status, and storage usage. Minor gaps exist, such as no explicit standalone tool for listing storage targets or machines, but list_snapshots exposes those values and agents can work around this.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    F
    maintenance
    An MCP server that enables Large Language Models to retrieve, analyze, and query metric data from Prometheus databases through pre-defined routes.
    33
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A lean MCP server that provides LLM agents with transparent access to multiple Prometheus instances for metrics analysis and SRE operations.
    4
    GPL 2.0
  • A
    license
    A
    quality
    C
    maintenance
    MCP server for administering Duplicacy backups via the duplicacy-web API, enabling AI clients to inspect and manage storages, repositories, schedules, and jobs.
    15
    MIT