Koskamo

SameDayDesk Page Change MCP

A free MCP server that compares two held JSON page observations to detect changes. It does not fetch URLs, take payment, or schedule observations, serving as a local diff tool for previously extracted data.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

SameDayDesk Page Change MCP logo, by SameDayDeskCommunity listingStreamable HTTPNo sign-inEndpoint checked 2026-11-01Published by SameDayDesk
MCP endpoint (Streamable HTTP)
https://agents.samedaydesk.com/mcp/page-change
Vendor documentation

What you can do with it

  • Compare two extract-batch JSON artifacts to detect page changes
  • Analyze differences in title and description fields between snapshots
  • Verify data integrity of previously captured web content

Source and maintenance

Community listingRegistry 1.0.0
Maintenance checked

Protocol and capabilities

Server
samedaydesk-page-compare 1.23.55
MCP protocol
2025-06-18
Tools
1 advertised
Resources
Not advertised
Resource templates
Not advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Compare two JSON page observations the caller already holds. The only tool is compare_page_observations. Do not fetch URLs, extract remote pages, schedule a later observation, or take payment.

Tools

1 advertised

compare_page_observations — Compare page observations
Advertised by the server during the last successful anonymous check.
Advertised read-only

Compare two already-held extract-batch JSON artifacts. charged is false. Not a paid SKU. Does not fetch, pay, or schedule a second observation. Compare only the explicitly selected data keys present on both matched rows. Missing keys are coverage unknown, not deletions; explicit null is a present value. Unselected metadata is not a content delta. SYNTHETIC offline construction example only. No URL fetch, payment, receipt, observation or freshness is evidenced. Complete request example (title changes, description stays unchanged): {"before":{"ok":true,"product":"samedaydesk-extract-batch","schemaVersion":"samedaydesk.extract-batch.v0","quote":{"amountAtomic":"10000","displayUsdc":"0.01","meaning":"SYNTHETIC offline construction example only. No URL fetch, payment, receipt, observation or freshness is evidenced."},"jobId":"0000000000000000000000000000000000000000000000000000000000000000","jobStatus":"completed","stopReason":null,"partial":false,"sources":[{"id":"item-001","source":"https://synthetic.example.invalid/page","status":"success","data":{"title":"Synthetic title before","description":"Stable synthetic description"},"notes":[],"error":null,"provenance":{"transport":"synthetic","note":"SYNTHETIC offline construction example only. No URL fetch, payment, receipt, observation or freshness is evidenced."}}],"accounting":{"requests":0,"bytes":0,"wallMs":0,"retries":0,"succeeded":0,"partial":0,"failed":0,"unknown":0,"skippedDuplicate":0},"costInputs":{"note":"SYNTHETIC offline construction example only. No URL fetch, payment, receipt, observation or freshness is evidenced."},"charged":false,"boundary":{"guaranteedUrlSuccess":false,"introductoryPrice":true,"sourceFetchBeforeAuthorization":false,"automaticRetries":false}},"after":{"ok":true,"product":"samedaydesk-extract-batch","schemaVersion":"samedaydesk.extract-batch.v0","quote":{"amountAtomic":"10000","displayUsdc":"0.01","meaning":"SYNTHETIC offline construction example only. No URL fetch, payment, receipt, observation or freshness is evidenced."},"jobId":"1111111111111111111111111111111111111111111111111111111111111111","jobStatus":"completed","stopReason":null,"partial":false,"sources":[{"id":"item-001","source":"https://synthetic.example.invalid/page","status":"success","data":{"title":"Synthetic title after","description":"Stable synthetic description"},"notes":[],"error":null,"provenance":{"transport":"synthetic","note":"SYNTHETIC offline construction example only. No URL fetch, payment, receipt, observation or freshness is evidenced."}}],"accounting":{"requests":0,"bytes":0,"wallMs":0,"retries":0,"succeeded":0,"partial":0,"failed":0,"unknown":0,"skippedDuplicate":0},"costInputs":{"note":"SYNTHETIC offline construction example only. No URL fetch, payment, receipt, observation or freshness is evidenced."},"charged":false,"boundary":{"guaranteedUrlSuccess":false,"introductoryPrice":true,"sourceFetchBeforeAuthorization":false,"automaticRetries":false}},"fields":["title","description"]}

compare_page_observations input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "before",
    "after",
    "fields"
  ],
  "properties": {
    "after": {
      "$ref": "#/properties/before"
    },
    "clock": {
      "type": [
        "string",
        "null"
      ],
      "description": "Optional caller UTC ISO-8601 timestamp with trailing Z, accepted for compatibility only; cannot attest freshness."
    },
    "before": {
      "anyOf": [
        {
          "type": "object",
          "required": [
            "ok",
            "product",
            "schemaVersion",
            "quote",
            "jobId",
            "jobStatus",
            "stopReason",
            "partial",
            "sources",
            "accounting",
            "costInputs",
            "charged",
            "boundary"
          ],
          "properties": {
            "ok": {
              "type": "boolean"
            },
            "error": {
              "$ref": "#/properties/before/anyOf/0/properties/quote/properties/meaning"
            },
            "jobId": {
              "type": "string",
              "pattern": "^[a-f0-9]{64}$"
            },
            "quote": {
              "type": "object",
              "required": [
                "amountAtomic",
                "displayUsdc",
                "meaning"
              ],
              "properties": {
                "meaning": {
                  "type": "string"
                },
                "displayUsdc": {
                  "type": "string",
                  "const": "0.01"
                },
                "amountAtomic": {
                  "type": "string",
                  "const": "10000"
                }
              },
              "additionalProperties": true
            },
            "charged": {
              "$ref": "#/properties/before/anyOf/0/properties/ok"
            },
            "partial": {
              "$ref": "#/properties/before/anyOf/0/properties/ok"
            },
            "product": {
              "type": "string",
              "const": "samedaydesk-extract-batch"
            },
            "sources": {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "id",
                  "source",
                  "status",
                  "data",
                  "notes",
                  "error",
                  "provenance"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Row identifier; does not replace source identity."
                  },
                  "data": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "lang": {
                            "description": "Selected extraction value: lang."
                          },
                          "text": {
                            "description": "Selected extraction value: text."
                          },
                          "links": {
                            "description": "Selected extraction value: links."
                          },
                          "title": {
                            "description": "Selected extraction value: title."
                          },
                          "jsonLd": {
                            "description": "Selected extraction value: jsonLd."
                          },
                          "twitter": {
                            "description": "Selected extraction value: twitter."
                          },
                          "headings": {
                            "description": "Selected extraction value: headings."
                          },
                          "canonical": {
                            "description": "Selected extraction value: canonical."
                          },
                          "openGraph": {
                            "description": "Selected extraction value: openGraph."
                          },
                          "aiReadiness": {
                            "description": "Selected extraction value: aiReadiness."
                          },
                          "description": {
                            "description": "Selected extraction value: description."
                          }
                        },
                        "description": "Compare only the explicitly selected data keys present on both matched rows. Missing keys are coverage unknown, not deletions; explicit null is a present value. Unselected metadata is not a content delta.",
                        "additionalProperties": true
                      },
                      {
                        "type": "null",
                        "description": "Compare only the explicitly selected data keys present on both matched rows. Missing keys are coverage unknown, not deletions; explicit null is a present value. Unselected metadata is not a content delta."
                      }
                    ],
                    "description": "Compare only the explicitly selected data keys present on both matched rows. Missing keys are coverage unknown, not deletions; explicit null is a present value. Unselected metadata is not a content delta."
                  },
                  "error": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "notes": {
                    "type": "array"
                  },
                  "source": {
                    "type": "string",
                    "pattern": "\\S",
                    "minLength": 1,
                    "description": "Stable source identity, separate from row id and observation time. Matching normalizes source strings (URL fragments removed). Use the same non-empty identity on both sides; duplicate active identities are ambiguous. Synthetic URL STRINGS are inert and are never fetched by this transform."
                  },
                  "status": {
                    "enum": [
                      "pending",
                      "success",
                      "partial",
                      "failure",
                      "unknown",
                      "skipped_duplicate"
                    ],
                    "type": "string"
                  },
                  "finalUrl": {
                    "$ref": "#/properties/before/anyOf/0/properties/stopReason"
                  },
                  "httpStatus": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "$ref": "#/properties/before/anyOf/0/properties/sources/items/properties/error/anyOf/1"
                      }
                    ]
                  },
                  "provenance": {
                    "$ref": "#/properties/before/anyOf/0/properties/sources/items/properties/error"
                  }
                },
                "additionalProperties": true
              },
              "maxItems": 5,
              "minItems": 1
            },
            "boundary": {
              "$ref": "#/properties/before/anyOf/0/properties/sources/items/properties/error/anyOf/0"
            },
            "jobStatus": {
              "enum": [
                "running",
                "completed",
                "completed_with_unknown",
                "stopped",
                "interrupted"
              ],
              "type": "string"
            },
            "accounting": {
              "$ref": "#/properties/before/anyOf/0/properties/sources/items/properties/error/anyOf/0"
            },
            "costInputs": {
              "$ref": "#/properties/before/anyOf/0/properties/sources/items/properties/error/anyOf/0"
            },
            "stopReason": {
              "type": [
                "string",
                "null"
              ]
            },
            "schemaVersion": {
              "type": "string",
              "const": "samedaydesk.extract-batch.v0"
            }
          },
          "description": "Representative merchant structure for useful comparisons; not a new paid request or proof of payment. Compare only the explicitly selected data keys present on both matched rows. Missing keys are coverage unknown, not deletions; explicit null is a present value. Unselected metadata is not a content delta.",
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "jobId",
            "status",
            "costParameters",
            "accounting",
            "items"
          ],
          "properties": {
            "items": {
              "type": "array",
              "items": {
                "$ref": "#/properties/before/anyOf/0/properties/sources/items"
              },
              "maxItems": 32,
              "minItems": 1
            },
            "jobId": {
              "$ref": "#/properties/before/anyOf/0/properties/quote/properties/meaning"
            },
            "status": {
              "$ref": "#/properties/before/anyOf/0/properties/quote/properties/meaning"
            },
            "accounting": {
              "$ref": "#/properties/before/anyOf/0/properties/sources/items/properties/error/anyOf/0"
            },
            "costParameters": {
              "$ref": "#/properties/before/anyOf/0/properties/sources/items/properties/error/anyOf/0"
            }
          },
          "description": "Existing C1 result compatibility. No merchant product/schemaVersion is required. Compare only the explicitly selected data keys present on both matched rows. Missing keys are coverage unknown, not deletions; explicit null is a present value. Unselected metadata is not a content delta.",
          "additionalProperties": true
        },
        {
          "type": "object",
          "required": [
            "body"
          ],
          "properties": {
            "body": {
              "anyOf": [
                {
                  "$ref": "#/properties/before/anyOf/0"
                },
                {
                  "$ref": "#/properties/before/anyOf/1"
                }
              ]
            },
            "status": {
              "$ref": "#/properties/before/anyOf/0/properties/quote/properties/meaning"
            },
            "mediaType": {
              "type": "string",
              "const": "application/json"
            },
            "observedAt": {
              "type": [
                "string",
                "null"
              ],
              "description": "Caller observation metadata only; does not attest freshness."
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "properties": {},
          "description": "Intentionally permissive diagnostic alternative, not a template for a useful comparison. Missing/wrong schemas, keys, source identities or fields do not become valid comparison evidence. A missing snapshot can be supplied as {missing:true}. Safety admission still rejects paths, URL dereference, limit raises and invalid envelopes.",
          "additionalProperties": true
        }
      ],
      "description": "Already held JSON artifact or JSON envelope, never a path or URL to dereference. Stable source identity, separate from row id and observation time. Matching normalizes source strings (URL fragments removed). Use the same non-empty identity on both sides; duplicate active identities are ambiguous. Synthetic URL STRINGS are inert and are never fetched by this transform. The structured branches describe representative comparable inputs. Incomplete objects remain admitted for diagnostic reports, subject to unchanged HTTP safety checks; HTTP 200 does not establish completeness or usefulness."
    },
    "fields": {
      "type": "array",
      "items": {
        "enum": [
          "title",
          "description",
          "canonical",
          "lang",
          "openGraph",
          "twitter",
          "jsonLd",
          "headings",
          "links",
          "text",
          "aiReadiness"
        ],
        "type": "string"
      },
      "maxItems": 11,
      "minItems": 1,
      "description": "Explicit non-empty unique subset of supported fields. Compare only the explicitly selected data keys present on both matched rows. Missing keys are coverage unknown, not deletions; explicit null is a present value. Unselected metadata is not a content delta."
    },
    "maxStaleMs": {
      "anyOf": [
        {
          "type": "integer",
          "minimum": 0,
          "description": "Optional freshness horizon, not a compute ceiling or freshness authority."
        },
        {
          "type": "null",
          "description": "Optional freshness horizon, not a compute ceiling or freshness authority."
        }
      ],
      "description": "Optional freshness horizon, not a compute ceiling or freshness authority."
    },
    "allowFreshClaim": {
      "type": "boolean",
      "const": false,
      "description": "Supplied inputs cannot attest freshness. True is rejected."
    }
  },
  "additionalProperties": false
}
compare_page_observations annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

Not advertised

No resource definitions available.

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
1097 ms
95th percentile latency
1097 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 1097 ms · metadata changed · 1 tool(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http samedaydesk-page-change-mcp https://agents.samedaydesk.com/mcp/page-change

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add samedaydesk-page-change-mcp --url https://agents.samedaydesk.com/mcp/page-change

Cursor

Merge this server into .cursor/mcp.json in your project, then enable samedaydesk-page-change-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "samedaydesk-page-change-mcp": {
      "url": "https://agents.samedaydesk.com/mcp/page-change"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "samedaydesk-page-change-mcp": {
      "type": "streamableHttp",
      "url": "https://agents.samedaydesk.com/mcp/page-change",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start samedaydesk-page-change-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "samedaydesk-page-change-mcp": {
      "type": "http",
      "url": "https://agents.samedaydesk.com/mcp/page-change"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http samedaydesk-page-change-mcp https://agents.samedaydesk.com/mcp/page-change

Claude Desktop

Merge this into claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\), then restart Claude Desktop.
Claude Desktop configuration
{
  "mcpServers": {
    "samedaydesk-page-change-mcp": {
      "url": "https://agents.samedaydesk.com/mcp/page-change"
    }
  }
}

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "samedaydesk-page-change-mcp": {
      "serverUrl": "https://agents.samedaydesk.com/mcp/page-change"
    }
  }
}

Let your agent find its tools

Find servers like SameDayDesk Page Change MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.