Change Detection Store

Change Detection Store

An MCP server that answers one question well: 'has this JSON changed since I last saw it?'

Category
访问服务器

README

Change Detection Store

An MCP server that answers one question well: "has this JSON changed since I last saw it?"

Why this exists

Say you want to track prices for a list of products, catch when an API response quietly changes shape, or watch stock levels across a few shops. The shape of the job is always the same: fetch the current state, compare it with what you saw last time, act only when something actually changed.

The fetching part is easy — a cron job, a script, or an LLM agent with a browsing tool. The remembering-and-comparing part is where projects get messy. Today you'd pick one of:

  • A hand-rolled snapshot store. A table or a bucket of JSON files, plus comparison code you rewrite for every project. Sooner or later it burns you, because the same data serialized twice is rarely byte-identical (key order, 1.0 vs 1) — so you get "changes" that aren't.
  • A full monitoring product like changedetection.io or Visualping. Great when you want their fetcher, scheduler and notifications. Overkill when you already own the fetching side and only miss the memory.
  • (For agents) pasting the previous value into the prompt and letting the model do the diffing. Works, but you pay tokens for it on every run and the comparison quality depends on the model's mood.

This project is the missing middle piece: a small service that only remembers and compares. Your script or agent sends the current value; the store hashes it canonically, writes only when the hash differs from last time, and answers changed: true/false. History accumulates real changes only, so "what happened to this key over the last month" is one call.

To be clear about the scope: it's a building block, not a monitoring product. It doesn't fetch, doesn't schedule, doesn't notify. It remembers and compares — that's the whole job, and it tries to do that one job properly: canonical hashing, concurrency-safe writes, a change history that cleans up after itself.

It speaks MCP, so you can add it to Claude as a custom connector and let the agent call the tools directly — but anything that can do OAuth and JSON-RPC can talk to it.

What a run looks like

sequenceDiagram
    participant A as Your agent / script
    participant S as Change Detection Store
    participant D as DynamoDB

    Note over A,S: every run starts the same way
    A->>S: create_store("prices")
    S-->>A: { created: false } — already exists, that's fine

    A->>S: patch_items(30 items with fresh values)
    S->>S: hash each value (RFC 8785 canonical JSON)
    S->>D: write only what differs
    S-->>A: 28 × changed:false, 2 × changed:true

    Note over A: act on the 2 real changes
    A->>S: get_item_history("prices", "product-8471")
    S-->>A: today's price, last week's price, ...

Twenty-eight of those thirty writes cost nothing — no DynamoDB write, no history entry, no noise. That asymmetry is the point: polling is cheap, only change is expensive.

How the change detection works

Values are hashed as SHA-256 over RFC 8785 canonical JSON. In practice:

  • key order doesn't matter — {"a":1,"b":2} and {"b":2,"a":1} are the same value
  • number formatting doesn't matter — 1.0, 1e0 and 1 are the same
  • array order DOES matter — [1,2] is not [2,1]; sort arrays client-side if your source returns them in random order

Every patch also takes an optional meta field. It's stored every time but never hashed — put things like lastSeenAt in there, so a timestamp doesn't count as a "change".

Deletes are soft: data disappears immediately and DynamoDB TTL removes it physically within about 7 days. History entries expire after 30 days on their own.

Architecture

flowchart LR
    C["Claude / your script"] -- "MCP + OAuth 2.0" --> L["Lambda<br/>(Function URL)"]
    L --> D[("DynamoDB<br/>single table, PK+SK")]
    L --> G["Cognito<br/>hosted login, group authz"]
    L --> M["Secrets Manager<br/>client credentials"]

One Lambda serves everything: the MCP endpoint, the OAuth discovery/proxy endpoints and the JWT gate. Storage is a single DynamoDB table (partition + sort key, no indexes) with on-demand billing — idle cost is close to zero. There's a CloudWatch dashboard (cds-health) with notes on how to read it, and an SNS topic for alarms.

Tools

  • create_store — idempotent; call it at the start of every run, it just says created: true/false
  • patch_item / patch_items — the core; batch takes up to 50 items and reports per key
  • get_item — returns { found: false } for a key that has no value yet (that's normal, not an error)
  • get_item_history — the change timeline of a key, newest first
  • list_stores, list_items, delete_item, delete_store

Running it locally

Node 22 or newer.

npm install
npm test                      # unit tests + CDK template assertions
npm run test:integration      # storage contract against DynamoDB Local (needs docker,
                              # or point CDS_DYNAMODB_ENDPOINT at a running instance)
npm run dev --workspace app   # MCP server on http://localhost:3000/mcp, no auth, in-memory

Point MCP Inspector at the dev server to poke around.

Deploying

You need an AWS account and credentials in your shell. Everything lands in eu-central-1 (edit infra/bin/app.ts for another region).

npx cdk bootstrap aws://<account-id>/eu-central-1    # once per account/region
npm run deploy --workspace infra
npm run create-user --workspace scripts -- --email you@example.com
npm run connection-info --workspace scripts

The last command prints the MCP URL and the OAuth client id. In Claude: Settings → Connectors → Add custom connector → paste the URL, put the client id under Advanced settings, connect, sign in with the user you just created.

Access is a Cognito group (cds-allowed) — the create-user script puts people in it. There's no self-signup, and the app client secret never leaves Secrets Manager.

Cost: close to nothing at low traffic. The KMS key is about a dollar a month; Lambda, DynamoDB on-demand and Cognito sit in or near their free tiers. Subscribe your email to the AlarmTopicArn stack output if you want to hear about problems.

Limitations, so you know what you're getting

  • No notifications. Nothing pushes when a value changes — your client asks. If you need push, DynamoDB Streams is the natural extension point.
  • No diffs. You get the current value and the history; comparing versions is on you.
  • Values up to 64 KB after canonicalization, history kept 30 days, list pages of 100.
  • Store names: a-z0-9_-, 3–12 chars. Item keys also allow A-Z and |, up to 32 chars, case-sensitive (external ids like source|ID6HfGma fit as-is).
  • One shared space: every user in the group sees all stores. No multi-tenancy.
  • No web UI — MCP only.
  • Concurrency is capped at 10 on purpose: it's a hard cost ceiling for an endpoint that's public by nature. Raise RESERVED_CONCURRENCY in the api construct if you need more.
  • Function URL quirk: the 401 challenge comes back as x-amzn-Remapped-www-authenticate. MCP clients don't care (they use the well-known discovery endpoints), but your curl scripts might.

License

MIT

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选