Tgms

io.github.zxf-work由 GitHub 账号 zxf-work 发布v0.7.0更新于 Oct 24, 2026

Bi-temporal graph store with 15 verified temporal operators as typed, deterministic MCP tools.

概览

AI 生成的概览

一个本地双时态图存储,为助手提供 15 个类型化、确定性的时间查询算子,并基于可审计的事件日志作答。

可以做什么
通过 15 个经验证的算子执行时间图查询:时间可达性、δ-模体、快照差异、突发检测、区间连接以及按边事件的分组聚合;算术与集合运算由专门算子完成,而非交给模型。读取信念日志,查看哪些信念被修订及修订时间,从而区分演化与更正。对照事件日志检查已保存答案是否仍然新鲜,并可注册、检查或刷新跨代衍生产物。生成内容寻址的追踪记录,使答案中的每条断言都能与产生它的证据进行机器核对。
适用场景
适用于助手需要回答图随时间如何变化的问题,包括某个过去日期在更正之前被相信的状态,以及答案需要逐条断言可审计而非自由生成时。
运行要求
作为本地 stdio 进程运行,可通过 uvx 或 pip 从 PyPI 安装;MCP 服务器通过 serve 命令并指定存储路径启动。演示无需 GPU、API 密钥或下载数据集;构建自有存储需要载入时间图数据,数据集加载器会从来源下载。
安装前请注意
服务器会读写本地图存储:数据导入、更正和产物刷新会改变已存数据,刷新会重新计算派生结果并传播到依赖项。数据集加载器会从外部来源获取数据。README 中的准确率与性能数字是项目自述,且覆盖范围有限,部分问题会被拒绝回答而非作答。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Tgms,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

TGMS — Agent-Native Bi-Temporal Graph Management System

[CI] [License: Apache-2.0] [Coverage: temporal/ 97%]

A temporal graph database whose query surface is built for LLM agents — and whose answers can be audited claim by claim.

Project page & blog: https://zxf-work.github.io/tgms/ · Paper: paper/main.pdf

LLM agents are unreliable at exactly the things temporal graph analytics requires: arithmetic, identifiers, and asserting only what the evidence shows. TGMS's answer is architectural — give the model no opportunity to do any of them:

  • a bi-temporal property graph (valid time × transaction time) that distinguishes evolution ("the edge ended") from correction ("we were wrong"), so agents can answer "what did we believe on March 1?" — a question latest-state snapshots and the RAG configurations we evaluated cannot express. Bi-temporality itself is inherited, not invented here — it has a four-decade literature, a place in SQL:2011, and production databases built around it. We measure against the clearest of those, XTDB: fed the same operation stream, the two systems agree on believed state at 400 of 400 probe points, with TGMS 3.9–4.7× faster at correction-heavy ingest on 23–27× less disk (the head-to-head);
  • and because a belief can be corrected after you've already acted on an answer, TGMS now tells you when that happened: tgms trace check reads a saved answer's dependency scope against the event log — no recompute, no store lock required — and returns FRESH / POSSIBLY_STALE / UNDECIDABLE, sound in the direction that matters (it never calls a stale answer fresh). Measured across two injection campaigns, 6,978 trials: 0 false-fresh verdicts on 447 changed answers in the M4 campaign (run 2, the record of account) and 0 more on 1,852 changed answers in the M5 carve-2 campaign (28,044 trials), where the obvious cheap check — "did the correction touch a row in the stored result?" — is wrong on 47.4% of the M4 trials;
  • and a saved result you want to keep, not just check, can now maintain itself: tgms artifact register/check/refresh turns it into a named, generation-numbered artifact — refresh recomputes only what you ask, the old generation stays byte-identical on disk, and a refresh propagates one hop to whatever else was built on top of it, even when that dependent's own scope was never touched. Measured across the M5 maintenance campaign: 0 false-fresh in 37,371 trials, 0 false-safe over 5,867 propagation decisions (99.0% resolved without recomputing anything), and a 600/600 pinned-answer exemption;
  • 15 verified temporal operators (reachability over time-respecting paths, δ-motifs, snapshot diffs, burst detection, interval joins, grouped aggregation over edge events, and the belief log itself) — typed, deterministic, bounded, cost-guarded, exposed as tools (MCP or in-process); identifiers must come from a resolver, arithmetic from a compute operator;
  • a Planner–Executor–Verifier loop: the LLM only plans and reports; plans are statically validated (including a grounding rule that makes fabricated identifiers impossible and output-field contracts that reject invented result paths), executed deterministically with content-addressed traces, and every claim in the written answer is machine-checked against the trace that produced it — including truncation taint, so "correct arithmetic over incomplete evidence" is caught too;
  • a purpose-built native storage engine (Rust, PyO3): bi-temporal columnar segments, a temporal-CSR traversal index, group commit, and a single-writer / many-reader concurrency mode — 24.6 bytes per edge version, versus 78.4 on ClickHouse and 549.7 on PostgreSQL for the same 1M-event log.

Quickstart

bash
pip install tgmstgms demo

No GPU, no API key, no dataset download. tgms demo builds a small store of its own in a temp directory and runs the arc every TGMS answer follows: what the graph currently believes, what it believed before a correction landed, and the trace that backs both claims up. Clean environment to first temporal result: under 5 minutes.

Once you want your own graph data, the native test suite, the MCP server, or an agent wired to a real LLM, see Full setup below — this quickstart is deliberately the smallest possible first step, not a tour of the operator surface.

Next steps, in the order most people need them: bring your own temporal graph data · give TGMS to an agent over MCP · audit an answer · maintain derived results · what you can rely on across versions · what's coming

Does it work?

Three different questions, three different answers. All three are reported because the third is the least flattering.

1. Does the agent layer beat the alternatives? Dev-split campaign (CollegeMsg, open-source models served locally on one 24 GB GPU. "Answer accuracy" is normalized typed-answer accuracy — counts and values scored strictly, interval answers credited at IoU ≥ 0.5. Full receipts ship with the paper and the eval records in benchmarks/results-v1/):

pooled answer accuracy, Qwen2.5-14BTGMSvector-RAGstatic-graph RAGtext-to-Cypher
all task families0.410.090.050.18
correction probes ("as of tt…")0.670.000.000.00
  • vs static-graph RAG: +36 points, paired-bootstrap 95% CI [0.18, 0.59]
  • verifier fault injection: 500/500 injected false claims caught, 0 false positives; on the frozen campaign, 0 of 199 emitted answers contained an unsupported claim with gating (21 of 220 without it) — coverage is 199/282, so some of that is bought by declining to answer
  • accuracy tracks planner capability where baselines stay flat: 13.8% / 34.0% / 62.8% at Qwen2.5 7B / 14B / 32B fp16, correction probes saturating at 100% at 32B

2. Is the engine competitive? Six systems answer one 13-query registry — TGMS native, TGMS-on-DuckDB, PostgreSQL, ClickHouse, Neo4j, Memgraph — with every cell hash-verified before it was timed:

query shapeTGMS nativebest other
temporal reachability, 200k14.7 ms3.9–7.3 s (Memgraph, Neo4j)
closed-triangle δ-motif, 200k28.7 ms2.1–5.5 s (Memgraph, Neo4j)
grouped aggregation, 200k14.5 ms32.6 ms (ClickHouse)
entity history by identity, 200k0.1 ms0.3 ms (PostgreSQL)
whole-window bucketed count, 10M84.7 ms37.9 ms (ClickHouse)

The last row is the one we cannot close: ClickHouse keeps a factor of 2.2 on whole-window aggregation at both 1M and 10M, and it is a constant of the shape rather than something that grows with scale. Three rounds of profiling took that gap from 12× to 2.2× and each round found our own implementation rather than the workload. Single latency cells reproduce to about ±20% between days, which is stated everywhere they are quoted.

At 10M events the full query suite runs inside 1.76 GB of peak RSS, 16 concurrent readers get 10.2× the throughput of one, and a live writer costs those readers 0–3% of per-query latency.

3. Can it answer the questions people actually ask? This is the honest one, and it now has a sequel. 110 questions were written by people who saw a plain-language description of two public datasets and never saw the operator list. Of those, 94 were expressible under the fixed 15-operator catalog — 10 were expressible when the study was pre-registered. Of LDBC SNB's 41 read templates, 3 executed — the operator-execution axis (does a plan compile, load, admit and run at all), a lower bar than the stricter ECQR result-contract axis, which stood at 7 of 41 — and that number had not moved in eight sessions, because 35 of the 38 misses needed labelled multi-way pattern matching: a deliberately deferred design decision, not a missing operator.

That deferred decision shipped. TGIR, a 12-primitive compositional temporal-graph IR, now runs the entire 15-operator catalog as byte-identical leaves and additionally compiles some question shapes — including labelled multi-way pattern matching — into chains of those primitives. Both axes were forecast before TGIR was built, frozen before the first row was measured, and moved to exactly the predicted level: LDBC operator-execution coverage 3 → 24 of 41, independent-question coverage 94 → 102 of 110, delivered/predicted 29/29 on the full 52-row forecast (28/28 on the 51 scoreable rows — one row was excluded by name in the freeze because its canonical corpus carries no corrections to find), 0 over-deliveries, 0 misses.

The store is still good and the surface is still narrower than "24 of 41" sounds. There is no LDBC SNB dataset in this repository. The 21 LDBC rows execute against a hand-built fixture carrying LDBC's labels, relationship types and multi-hop topology at a size a reviewer can read on one screen (scripts/build_ldbc_fixture.py); it establishes that a plan compiles, loads, admits and executes, and nothing about scale. The independent-question axis is the one measured on real data (bitcoin-otc, CollegeMsg), and it's where the admission/cost-guard claim is meaningful. Both instruments live in the repo (scripts/independent_questions.py, scripts/ldbc_fit.py), they re-run in seconds, and each capability shipped has been scored against a forecast made before it was built — delivered/predicted has now run 14/30, 4/7, 10/13, 14/16, 15/15, 4/8, 5/5, 4/5, and 29/29. 5/5 and 4/5 were the first forecasts made per question rather than in aggregate, and TGIR's 29/29 is the first forecast — made per row, before any row was measured — with zero misses across the whole universe.

What the operators can express

Fifteen operators — fourteen of them unchanged since D-044, because most of the growth since v0.4.0 happened inside them, driven question by question by the study above. The newest growth happened underneath them instead: TGIR, a 12-primitive compositional temporal-graph IR, now runs the entire operator set as byte-identical leaves — same semantics, digest- receipted, switchable off with TGIR_PLAN_PATH=off — and additionally compiles some question shapes, chiefly labelled multi-way pattern matching, into chains of those primitives. TGIR plans are not yet a user-facing query language: there is no public syntax for writing one directly, and the fifteen operators below are still the whole interface an agent (or you) calls. What changed is what happens underneath a call, and it is measured in the byte-reproducible record at benchmarks/tgir-v1/measured.yaml.

The pre-existing fifteen:

capabilitywhere it liveswhat it answers
grouped aggregationaggregate_eventscounts and distinct counts by time bucket, rel_type, endpoint or endpoint label
arithmeticcomputemean/median over rows; ratio/diff/percent over two scalars — never in the LLM
typed propertiesaggregate_eventspredicates and min/max/mean over an edge property, where a value participates only if its JSON type fits
set operationscompute, aggregate_eventsintersect/difference/union over uid lists, a cohort pre-filter, undirected and reciprocal pair modes
row arithmetic and joinscomputederive adds one computed column; join aligns two grouped results on a key unique on both sides
ordered sequencesaggregate_eventslongest gap between consecutive events, busiest sliding window of a given span, longest run with no gap over a threshold
calendar unitsaggregate_eventsgrouping by hour of day, day of week or month of year, at a fixed offset from UTC that is an argument rather than a default
the belief logversion_historywhich beliefs were revised and when — the only operator that reads the correction record rather than a state derived from it

Every one of these is verified against the same brute-force oracle as the operators themselves, and every one is measured in the session that shipped it. What is not there is written down too, question by question, in the re-audit tables of scripts/independent_questions.py and scripts/ldbc_fit.py — both of which print the current blocked-capability board on report.

Full setup (from source)

Everything below builds TGMS from a checkout instead of the PyPI wheel: real dataset loaders, the native-engine test suite, the MCP server, and an agent loop wired to an actual LLM.

bash
# macOS note: if this repo sits in an iCloud-synced folder, keep the venv# outside it (iCloud sets the hidden flag on .pth files and Python 3.12+# silently skips them):  export UV_PROJECT_ENVIRONMENT=$HOME/.venvs/tgmsuv sync --extra agentmake test                     # 271 tests: property, oracle, metamorphic, e2e
bash
# build a real store + task suite (downloads CollegeMsg from SNAP)make data-collegemsg suite-collegemsg
bash
# call one verified operator — no LLM neededuv run tgms call temporal_reachability \  '{"src": "n9", "window": {"t_a": 1082040961000000, "t_b": 1088000000000000}}' \  --store stores/collegemsg
bash
# verifier acceptance experiment (deterministic, no LLM)uv run tgms eval c2 --store stores/collegemsg \  --suite stores/suite-collegemsg/suite.json --mutants 500

With any OpenAI-compatible LLM endpoint (e.g. vllm serve Qwen/Qwen2.5-7B-Instruct):

bash
uv run tgms ask "How many nodes can n9 reach between ... and ...?" \  --store stores/collegemsg --model openai/Qwen/Qwen2.5-7B-Instruct \  --api-base http://localhost:8000/v1 --html trace.html   # auditable trace page
bash
bash scripts/run_webapp.sh    # interactive guided demo at localhost:8080

Interfaces

SurfaceEntry pointWhat it's for
Python librarytgms.open(...), Agent(store, model=…).ask(…)research code, notebooks
MCP servertgms serve --store PATHhand the verified toolbox to any MCP-capable agent
CLItgms demo/ingest/synth/tasks/call/ask/bench/memory/eval/tracereproducibility
Trace viewertgms ask … --html trace.htmlask → answer → audit the evidence (static, self-contained HTML)
Freshness checktgms trace check record.json --store PATHis this answer still fresh? — FRESH/POSSIBLY_STALE/UNDECIDABLE against the event log, no recompute
Demo GUItgms webapp … / scripts/run_webapp.shguided tour: operators → agent → tamper demo → time travel → freshness check

Correctness

Every operator is verified against an independent brute-force oracle (500 randomized cases per operator; 97% line coverage in tgms/temporal/ across both backends), plus metamorphic properties — diff composition and bi-temporal immutability: any result pinned to a past belief state is byte-identical before and after later corrections. The same suite runs unmodified against both backends, which is the whole acceptance argument for the native engine: it has to satisfy the same human-owned ground truth that DuckDB does.

bash
TGMS_TEST_BACKEND=native make test    # same tests, native engine

The write path is property-tested over random assert/retract/correct interleavings, and the append-only event log replays into either backend with identical store digests. Process rules are enforced in CI and are not advisory: tests and the oracle may never share a commit with the implementation they judge, and every number quoted on the project site is resolved from docs/site_facts.json at build time, so a stale figure fails the build rather than the review. See CONTRIBUTING.md.

Layout

tgms/core       clock, bi-temporal data model, error taxonomytgms/storage    StorageAdapter ABC, native + DuckDB backends, event log, TCSR indextgms/temporal   operator algebra O1–O15 + brute-force oracletgms/tools      tool schemas, MCP server / ToolRouter, trace viewer, demo GUItgms/agent      plan IR, planner, executor, verifier, reporter, memorytgms/data       dataset loaders (SHA-256 pinned) + synthetic generatortgms/eval       task suites, baselines, matrix harness, metrics, fault injectioncrates/         the native engine: bi-temporal segments, TCSR, motif kernel

Datasets are never bundled: loaders download from source (SNAP) and pin SHA-256 manifests. See docs/eval/ for design, positioning, measurements, and roadmap.

License

Apache-2.0 — see LICENSE. Cite via CITATION.cff.


mcp-name: io.github.zxf-work/tgms

来源:README.md,提交 6dd332e

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

1
  1. v0.7.0最新Sep 16, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分