feat(cli): implement deterministic gatekeeper subcommand and optimize Tokio runtime
This commit is contained in:
commit
a2febd1b00
10 files changed
+3386
No files matched your search
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
Generated
+986
@@ -0,0 +1,986 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"is_terminal_polyfill",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "3.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"once_cell_polyfill",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-trait"
|
||||||
|
version = "0.1.92"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.23.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-buffer"
|
||||||
|
version = "0.10.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.20.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytes"
|
||||||
|
version = "1.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.6.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
"clap_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.6.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "4.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crypto-common"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deranged"
|
||||||
|
version = "0.5.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.10.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||||
|
dependencies = [
|
||||||
|
"block-buffer",
|
||||||
|
"crypto-common",
|
||||||
|
"subtle",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs"
|
||||||
|
version = "6.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
|
||||||
|
dependencies = [
|
||||||
|
"dirs-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs-sys"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"option-ext",
|
||||||
|
"redox_users",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.3.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-executor",
|
||||||
|
"futures-io",
|
||||||
|
"futures-sink",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-channel"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-core"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-executor"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-io"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-macro"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-sink"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-task"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-util"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
|
"futures-macro",
|
||||||
|
"futures-sink",
|
||||||
|
"futures-task",
|
||||||
|
"memchr",
|
||||||
|
"pin-project-lite",
|
||||||
|
"slab",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.14.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"r-efi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "glob"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hmac"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
|
||||||
|
dependencies = [
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"itoa",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is_terminal_polyfill"
|
||||||
|
version = "1.70.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.105"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce57d20d1ea864ce2ac172ab472d409214f4fd359f0b2a2775abdf522e2af99e"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"futures-util",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.189"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libredox"
|
||||||
|
version = "0.1.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8d8f1ea3f21fd3405dcaf6c9b5c1630af9afc422d9073ea39c5f6d6c772e08ed"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
|
||||||
|
dependencies = [
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mcp-memory"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"clap",
|
||||||
|
"dirs",
|
||||||
|
"glob",
|
||||||
|
"rust-mcp-sdk",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"strsim",
|
||||||
|
"tokio",
|
||||||
|
"uuid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "1.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4b18443e9c262bfe8fa82f51666e2642c53393f7e5c27b3e1aeab922cff5b9d8"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-conv"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_threads"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.21.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell_polyfill"
|
||||||
|
version = "1.70.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "option-ext"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.12.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.9.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"smallvec",
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "powerfmt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.107"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.47"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "r-efi"
|
||||||
|
version = "6.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.5.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_users"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.17",
|
||||||
|
"libredox",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-mcp-macros"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "58bd70356e3da5f64bb9cae7b1acc90279378c9220c6b69731d8af945938fef8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-mcp-schema"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a66664d256795cdd61b7d4d6516d8afe041c947bedd1d10aff9e41e15771b43"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-mcp-sdk"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9849649137179b679d8115c79716fcf03b1bd7d3b579bb61081eed59d9bbabcb"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"base64",
|
||||||
|
"bytes",
|
||||||
|
"futures",
|
||||||
|
"hmac",
|
||||||
|
"http",
|
||||||
|
"rust-mcp-macros",
|
||||||
|
"rust-mcp-schema",
|
||||||
|
"rust-mcp-transport",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sha2",
|
||||||
|
"thiserror",
|
||||||
|
"time",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"uuid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-mcp-transport"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1421cf8c7524c398b94c84af024a5af59c146bdbc1d4afed076b2eac9b0a99df"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"bytes",
|
||||||
|
"futures",
|
||||||
|
"rust-mcp-schema",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.229"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_core"
|
||||||
|
version = "1.0.229"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.229"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.151"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
"zmij",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha2"
|
||||||
|
version = "0.10.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
|
||||||
|
dependencies = [
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slab"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9be42f50aa861c555654aa3a37f52f4b1074bacf4e48fe0ef7fa584e80f1f0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "socket2"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subtle"
|
||||||
|
version = "2.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.119"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "3.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.55"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134"
|
||||||
|
dependencies = [
|
||||||
|
"deranged",
|
||||||
|
"libc",
|
||||||
|
"num-conv",
|
||||||
|
"num_threads",
|
||||||
|
"powerfmt",
|
||||||
|
"serde_core",
|
||||||
|
"time-core",
|
||||||
|
"time-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-core"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.2.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85"
|
||||||
|
dependencies = [
|
||||||
|
"num-conv",
|
||||||
|
"time-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio"
|
||||||
|
version = "1.53.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"libc",
|
||||||
|
"mio",
|
||||||
|
"parking_lot",
|
||||||
|
"pin-project-lite",
|
||||||
|
"signal-hook-registry",
|
||||||
|
"socket2",
|
||||||
|
"tokio-macros",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-macros"
|
||||||
|
version = "2.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-stream"
|
||||||
|
version = "0.1.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing"
|
||||||
|
version = "0.1.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project-lite",
|
||||||
|
"tracing-attributes",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-attributes"
|
||||||
|
version = "0.1.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-core"
|
||||||
|
version = "0.1.36"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.20.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uuid"
|
||||||
|
version = "1.26.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5772d71c9be8a8a6ac2117d949c5b224c1b72241bb611d9a3012edcf8af7812"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.4.3",
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.1+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.128"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"rustversion",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.128"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.128"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.128"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-link"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.61.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zmij"
|
||||||
|
version = "1.0.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "mcp-memory"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
async-trait = "0.1.92"
|
||||||
|
clap = { version = "4.6.6", features = ["derive"] }
|
||||||
|
dirs = "6.0.0"
|
||||||
|
glob = "0.3.4"
|
||||||
|
rust-mcp-sdk = { version = "2.0.0", default-features = false, features = ["server", "macros", "stdio"] }
|
||||||
|
serde = { version = "1.0.229", features = ["derive"] }
|
||||||
|
serde_json = "1.0.151"
|
||||||
|
strsim = "0.11.1"
|
||||||
|
tokio = { version = "1.53.1", features = ["full"] }
|
||||||
|
uuid = { version = "1.26.0", features = ["v4"] }
|
||||||
+133
@@ -0,0 +1,133 @@
|
|||||||
|
# MCP Memory Server Guidelines
|
||||||
|
|
||||||
|
This server provides an OS-agnostic, persistent Knowledge Graph and working memory. The following guidelines dictate **when** and **how** to best utilize these tools.
|
||||||
|
|
||||||
|
## 1. Ephemeral Working Memory (Sticky Notes)
|
||||||
|
- **Tools:** dd_sticky_note, ␍ead_sticky_notes
|
||||||
|
- **When to use:**
|
||||||
|
- When you need to remember a specific context, broken build state, or pending task across conversation boundaries (e.g., "We are in the middle of refactoring main.rs, next step is testing").
|
||||||
|
- When saving short-term scratchpad thoughts that don't belong in the permanent knowledge graph.
|
||||||
|
- **Behavior:** Notes have a 24-hour TTL and are pruned automatically. Always consider reading sticky notes at the start of a session if picking up an ongoing task.
|
||||||
|
|
||||||
|
## 2. The Knowledge Graph (Entities & Relations)
|
||||||
|
- **Tools:** search_nodes, open_nodes, ␍ead_graph
|
||||||
|
- **When to use search_nodes:** Use this for **fuzzy searching** when you aren't 100% sure of the exact entity name, or you want to find everything related to a topic (e.g., "Docker", "Jenkins"). It uses Jaro-Winkler distance and token matching.
|
||||||
|
- **When to use open_nodes:** Use this for **1-hop traversal**. If you know a specific entity name (e.g., "auth-service") and want to see how it connects to other services, open_nodes will pull the entity AND all directly connected neighbors.
|
||||||
|
|
||||||
|
## 3. Graph Maintenance & Condensation
|
||||||
|
- **Tool:** condense_entity
|
||||||
|
- **When to use:** Proactively use this tool if you notice an entity's observations array is getting excessively long (e.g., >10 items) or repetitive. Condense the list into a shorter, more concise summary of the core facts to preserve token limits.
|
||||||
|
|
||||||
|
## 4. The Audit Ledger (Code Changes)
|
||||||
|
- **Tools:** log_code_change, query_recent_changes
|
||||||
|
- **When to use log_code_change:** *MANDATORY.* Immediately after successfully making significant file modifications (e.g., refactoring a script, fixing a bug). Log the file path and a short description.
|
||||||
|
- **When to use query_recent_changes:** When the user asks "What did we do yesterday?", "What changed recently?", or when trying to debug a newly introduced issue. (The ledger retains 7 days of history, max 1000 items).
|
||||||
|
|
||||||
|
## 5. Architectural Visualization
|
||||||
|
- **Tool:** isualize_graph
|
||||||
|
- **When to use:** When you need to explain complex system relationships, dependencies, or architectures to the user. This tool outputs a raw Mermaid.js string. Put the output inside a ``mermaid` markdown block in an Artifact so the user can see a visual diagram.
|
||||||
|
|
||||||
|
## 6. Structured Task Queue (Agentic Kanban)
|
||||||
|
- **Tools:** `add_task`, `update_task_status`, `list_active_tasks`
|
||||||
|
- **When to use:** Use this for structured checklist tracking of complex, multi-day features or goals (e.g., when the user initiates a `/goal`).
|
||||||
|
- **Behavior:** Log tasks with a title and description. When resuming sessions, always run `list_active_tasks` to see what is still `pending`, `in_progress`, or `blocked`, and pick up where you left off. Use `update_task_status` to transition tasks to `done`.
|
||||||
|
|
||||||
|
## 7. Snippet & Command Vault
|
||||||
|
- **Tools:** `store_snippet`, `search_snippets`, `delete_snippet`
|
||||||
|
- **When to use:** Use the Vault to store exactly multi-line code snippets, Nushell pipelines, or complex commands that the user relies on frequently.
|
||||||
|
- **Behavior:** The vault guarantees precise syntactic preservation of the script (unlike Graph observations). Search snippets when trying to recall an exact query or pipeline.
|
||||||
|
|
||||||
|
## 8. Context Namespaces (Project Scopes)
|
||||||
|
- **Feature:** `namespace` optional parameter
|
||||||
|
- **When to use:** When using `read_graph`, `search_nodes`, or `visualize_graph`, you can now pass `namespace` to isolate graph queries to a specific project scope (e.g. "scascanner").
|
||||||
|
- **Behavior:** When calling `create_entities` or `create_relations`, you can inject `namespace: "your_project"` into the entity schema to isolate it from the global scope.
|
||||||
|
|
||||||
|
## 9. Architectural Decision Records (ADRs)
|
||||||
|
- **Tools:** log_decision, query_decisions
|
||||||
|
- **When to use:** Use this whenever you make a non-trivial architectural, environmental, or tooling decision (e.g. choosing a specific framework, a specific deployment flag, bypassing a rule with a workaround).
|
||||||
|
- **Behavior:** This permanently stores the context, decision, and consequence of *why* something is done the way it is, preventing future agents from second-guessing or reverting it.
|
||||||
|
|
||||||
|
## 10. Graph Refactoring & Maintenance
|
||||||
|
- **Tools:** merge_entities, ind_orphans
|
||||||
|
- **When to use:** Run ind_orphans periodically or when you notice graph clutter to safely delete unused nodes. Use merge_entities when you notice duplicated semantic concepts (e.g. API_Gateway vs APIGateway).
|
||||||
|
- **Behavior:** merge_entities will safely combine their observations and automatically remap all relations pointing to or from the deleted duplicate.
|
||||||
|
|
||||||
|
## 11. Dynamic Learned Preferences
|
||||||
|
- **Tools:** learn_preference, ␍ead_preferences
|
||||||
|
- **When to use:** When the user corrects you on a specific local nuance (e.g. "Actually, use Python 3.10 instead of 3.12 for this repo").
|
||||||
|
- **Behavior:** Use this Key-Value store to record dynamic behavioral preferences to ensure you adapt instantly without modifying global Markdown files.
|
||||||
|
|
||||||
|
## Error Vault / Troubleshooting
|
||||||
|
When you spend time resolving a tricky environment issue, build error, or logic bug, immediately record the fix to save future time.
|
||||||
|
- **log_error_fix:** Provide the signature (the exact error string or stack trace snippet) and the solution.
|
||||||
|
- **search_error_fixes:** When encountering a weird bug, query this vault first before debugging from scratch.
|
||||||
|
|
||||||
|
## Pinned Workspaces (Hot Files)
|
||||||
|
To maintain focus on the active "working set" of files in large repositories, use pins.
|
||||||
|
- **pin_file / unpin_file:** Pin the 3-5 files you are actively modifying to the current
|
||||||
|
amespace (project).
|
||||||
|
- **list_pinned_files:** When starting a new session or returning to a project, always list pinned files first to instantly regain context on what was being worked on.
|
||||||
|
|
||||||
|
## Rolling Session Summaries (Project Timeline)
|
||||||
|
To maintain a chronological narrative of the project's evolution beyond just code diffs.
|
||||||
|
- **add_session_summary:** At the end of every major coding session, write a 2-sentence summary of what was accomplished and add it to the
|
||||||
|
amespace.
|
||||||
|
- **get_project_timeline:** When rejoining a project after a long time, read the timeline to instantly understand the recent architectural history.
|
||||||
|
|
||||||
|
## Agent Handoffs (The Inbox)
|
||||||
|
When working in a multi-session or multi-agent environment, agents need to communicate context across time.
|
||||||
|
- **leave_handoff_memo:** Leave a quick message describing current progress, roadblocks, or the literal next step to take.
|
||||||
|
- **read_handoff_memos:** ALWAYS check for memos when waking up in a new project namespace.
|
||||||
|
- **clear_handoff_memos:** Clear the memo after you have successfully read it and absorbed its context.
|
||||||
|
|
||||||
|
## Environment & Blueprint Tracker
|
||||||
|
Stop wasting tokens rediscovering how to run or configure the project.
|
||||||
|
- **update_env_fingerprint:** Run this when you set up a new project to snapshot the OS, shell, and key language versions (e.g. python, ␍ustc).
|
||||||
|
- **read_env_fingerprint:** Query this to instantly know how the project is run.
|
||||||
|
- **log_env_requirement:** Log required .env variables (e.g. DATABASE_URL) without logging the secret itself.
|
||||||
|
|
||||||
|
## Milestones (Epics)
|
||||||
|
Organize granular tasks into high-level phases.
|
||||||
|
- **add_milestone:** Group a large subset of work into a cohesive phase (e.g., "V1 MVP", "CI/CD Setup").
|
||||||
|
- **update_milestone:** Mark a milestone as active, blocked, or completed.
|
||||||
|
- **list_milestones:** Use this to ensure task priorities align with the current active milestone.
|
||||||
|
|
||||||
|
## Standup Reports
|
||||||
|
When asked for a progress update or standup report, do not guess or read raw git logs.
|
||||||
|
- **generate_standup_report:** Generates a structured JSON containing all asks updated, code_changes logged, and session_summaries added within the last N hours. Format this cleanly as a markdown report for the user.
|
||||||
|
|
||||||
|
## Infrastructure & Environment Registry
|
||||||
|
Avoid asking the user for URLs or connection details repeatedly.
|
||||||
|
- **register_environment:** Save connection details for Dev, QA, Staging, or Prod environments.
|
||||||
|
- **get_environment_details:** Query this to know how to connect to databases, APIs, or VPNs.
|
||||||
|
|
||||||
|
## Pre-Push / PR Quality Checklists
|
||||||
|
Ensure high code quality and prevent incomplete pull requests.
|
||||||
|
- **add_pr_checklist_item:** Add recurring repository chores (e.g., "Run cargo fmt", "Update CHANGELOG").
|
||||||
|
- **get_pr_checklist:** Query and explicitly verify EVERY item on this list before triggering git push or merging PRs.
|
||||||
|
- **clear_pr_checklist:** Clear if the project lifecycle changes dramatically.
|
||||||
|
|
||||||
|
## Tech Debt & Refactor Backlog
|
||||||
|
Keep the main task board clean by isolating "hacky" workarounds.
|
||||||
|
- **log_tech_debt:** Record why a shortcut was taken and what the ideal solution should be.
|
||||||
|
- **resolve_tech_debt:** Mark a debt as paid off once refactored.
|
||||||
|
- **list_tech_debt:** Query this before starting a refactoring session.
|
||||||
|
|
||||||
|
## Context Workspaces
|
||||||
|
When shifting context rapidly (e.g. from building a feature to fixing a prod bug), save your state.
|
||||||
|
- **save_context_workspace:** Save your active pinned files and task IDs under a named workspace (e.g., "Feature X").
|
||||||
|
- **load_context_workspace:** Retrieve a saved workspace to instantly restore your context when returning to that task.
|
||||||
|
- **list_context_workspaces:** List all saved workspaces in a project.
|
||||||
|
|
||||||
|
## Omni-Search (Global Vault Search)
|
||||||
|
When you remember a vague keyword but don't know which specific vault it's stored in.
|
||||||
|
- **omni_search:** Searches across the Knowledge Graph, Tasks, Snippets, ADRs, Tech Debt, Memos, and Error Fixes simultaneously.
|
||||||
|
|
||||||
|
## Project Health Dashboard
|
||||||
|
When starting a new session, get a numerical aggregate of the project's current state.
|
||||||
|
- **get_project_health:** Returns a quick digest of active tasks, unread memos, unresolved tech debt, and pending PR checklist items.
|
||||||
|
|
||||||
|
## Git Context Binding (VCS Sync)
|
||||||
|
To maintain absolute traceability, we link memory items directly to the exact git commits they occurred on.
|
||||||
|
- When calling **log_code_change**, **log_error_fix**, or **log_tech_debt**, you should execute git rev-parse HEAD and git branch --show-current in the project directory first (if it's a git repo).
|
||||||
|
- Pass the resulting hash and branch name into the git_commit and git_branch arguments of those tools to permanently link the memory item to the VCS state.
|
||||||
+1231
File diff suppressed because it is too large.
Load diff
+257
@@ -0,0 +1,257 @@
|
|||||||
|
mod handlers;
|
||||||
|
mod models;
|
||||||
|
mod state;
|
||||||
|
mod store;
|
||||||
|
mod tools;
|
||||||
|
|
||||||
|
use crate::handlers::MemoryHandler;
|
||||||
|
use crate::models::*;
|
||||||
|
use crate::state::MemoryState;
|
||||||
|
use crate::store::Store;
|
||||||
|
use rust_mcp_sdk::{
|
||||||
|
McpServer, ServerDetails, StdioTransport, ToMcpServerHandler, TransportOptions,
|
||||||
|
error::SdkResult,
|
||||||
|
mcp_server::{McpServerOptions, server_runtime},
|
||||||
|
schema::{Implementation, ServerCapabilities, ServerCapabilitiesTools},
|
||||||
|
};
|
||||||
|
use std::fs;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::sync::{Arc, RwLock};
|
||||||
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
|
use tokio::time::sleep;
|
||||||
|
|
||||||
|
use clap::{Parser, Subcommand};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(author, version, about, long_about = None)]
|
||||||
|
struct Cli {
|
||||||
|
#[command(subcommand)]
|
||||||
|
command: Option<Commands>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand)]
|
||||||
|
enum Commands {
|
||||||
|
Gate {
|
||||||
|
#[command(subcommand)]
|
||||||
|
subcmd: GateCommands,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand)]
|
||||||
|
enum GateCommands {
|
||||||
|
Set {
|
||||||
|
#[arg(long)]
|
||||||
|
action: String,
|
||||||
|
#[arg(long)]
|
||||||
|
target: String,
|
||||||
|
#[arg(long)]
|
||||||
|
namespace: Option<String>,
|
||||||
|
#[arg(short = 'p', long = "param")]
|
||||||
|
params: Vec<String>,
|
||||||
|
#[arg(long, conflicts_with = "block")]
|
||||||
|
authorize: bool,
|
||||||
|
#[arg(long, conflicts_with = "authorize")]
|
||||||
|
block: bool,
|
||||||
|
#[arg(long)]
|
||||||
|
reason: Option<String>,
|
||||||
|
},
|
||||||
|
Verify {
|
||||||
|
#[arg(long)]
|
||||||
|
action: String,
|
||||||
|
#[arg(long)]
|
||||||
|
target: String,
|
||||||
|
#[arg(long)]
|
||||||
|
namespace: Option<String>,
|
||||||
|
#[arg(short = 'p', long = "param")]
|
||||||
|
params: Vec<String>,
|
||||||
|
#[arg(long)]
|
||||||
|
consume: bool,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async fn reconcile_worker(state: Arc<MemoryState>) {
|
||||||
|
loop {
|
||||||
|
sleep(Duration::from_secs(5)).await;
|
||||||
|
let pattern = format!("{}/delta_*.json", state.base_dir.display());
|
||||||
|
let has_local = {
|
||||||
|
let session = state.session_graph.read().unwrap();
|
||||||
|
!session.entities.is_empty() || !session.relations.is_empty()
|
||||||
|
};
|
||||||
|
let has_files = glob::glob(&pattern).map(|p| p.count() > 0).unwrap_or(false);
|
||||||
|
if has_local || has_files {
|
||||||
|
state.apply_sync_write(|_master| {});
|
||||||
|
}
|
||||||
|
|
||||||
|
let now = SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_secs();
|
||||||
|
state.ledger.modify(|ledger| {
|
||||||
|
let seven_days = now.saturating_sub(7 * 24 * 60 * 60);
|
||||||
|
ledger.retain(|c| c.timestamp >= seven_days);
|
||||||
|
if ledger.len() > 1000 {
|
||||||
|
let excess = ledger.len() - 1000;
|
||||||
|
ledger.drain(0..excess);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
state.sticky.modify(|notes| {
|
||||||
|
notes.retain(|note| note.timestamp >= now.saturating_sub(24 * 60 * 60));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn run_server(state: Arc<MemoryState>) -> SdkResult<()> {
|
||||||
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
rt.block_on(async {
|
||||||
|
let state_clone = state.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
reconcile_worker(state_clone).await;
|
||||||
|
});
|
||||||
|
|
||||||
|
let server_details = ServerDetails {
|
||||||
|
server_info: Implementation {
|
||||||
|
name: "gemini-mcp-memory".into(),
|
||||||
|
version: "3.0.0".into(),
|
||||||
|
title: Some("MCP Memory Server".into()),
|
||||||
|
description: Some("Persistent memory MCP server".into()),
|
||||||
|
icons: vec![],
|
||||||
|
website_url: None,
|
||||||
|
},
|
||||||
|
capabilities: ServerCapabilities {
|
||||||
|
tools: Some(ServerCapabilitiesTools {
|
||||||
|
list_changed: Some(true),
|
||||||
|
}),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
instructions: None,
|
||||||
|
meta: None,
|
||||||
|
};
|
||||||
|
let server = server_runtime::create_server(McpServerOptions {
|
||||||
|
transport: StdioTransport::new(TransportOptions::default())?,
|
||||||
|
handler: MemoryHandler { state }.to_mcp_server_handler(),
|
||||||
|
server_details,
|
||||||
|
message_observer: None,
|
||||||
|
});
|
||||||
|
server.start().await
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> SdkResult<()> {
|
||||||
|
let cli = Cli::parse();
|
||||||
|
|
||||||
|
let base_dir = std::env::var("MCP_MEMORY_STORE_DIR").unwrap_or_else(|_| {
|
||||||
|
dirs::home_dir()
|
||||||
|
.map(|mut h| {
|
||||||
|
h.push(".gemini/mcp_memory");
|
||||||
|
h.to_string_lossy().into_owned()
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| ".gemini/mcp_memory".into())
|
||||||
|
});
|
||||||
|
let base = PathBuf::from(base_dir);
|
||||||
|
fs::create_dir_all(&base).expect("Failed to create store dir");
|
||||||
|
|
||||||
|
let state = Arc::new(MemoryState {
|
||||||
|
master_path: base.join("knowledge_graph_master.json"),
|
||||||
|
delta_path: base.join(format!("delta_{}.json", uuid::Uuid::new_v4())),
|
||||||
|
session_graph: RwLock::new(KnowledgeGraph::default()),
|
||||||
|
base_dir: base.clone(),
|
||||||
|
master_cache: RwLock::new((KnowledgeGraph::default(), SystemTime::UNIX_EPOCH)),
|
||||||
|
ledger: Store::new(base.join("audit_ledger.json")),
|
||||||
|
sticky: Store::new(base.join("sticky_notes.json")),
|
||||||
|
tasks: Store::new(base.join("tasks.json")),
|
||||||
|
snippets: Store::new(base.join("snippets.json")),
|
||||||
|
adrs: Store::new(base.join("adrs.json")),
|
||||||
|
prefs: Store::new(base.join("preferences.json")),
|
||||||
|
error_fixes: Store::new(base.join("error_fixes.json")),
|
||||||
|
pinned_files: Store::new(base.join("pinned_files.json")),
|
||||||
|
session_summaries: Store::new(base.join("session_summaries.json")),
|
||||||
|
handoff_memos: Store::new(base.join("handoff_memos.json")),
|
||||||
|
env_fingerprints: Store::new(base.join("env_fingerprints.json")),
|
||||||
|
env_requirements: Store::new(base.join("env_requirements.json")),
|
||||||
|
milestones: Store::new(base.join("milestones.json")),
|
||||||
|
environments: Store::new(base.join("environments.json")),
|
||||||
|
pr_checklists: Store::new(base.join("pr_checklists.json")),
|
||||||
|
tech_debts: Store::new(base.join("tech_debts.json")),
|
||||||
|
gates: Store::new(base.join("gates.json")),
|
||||||
|
context_workspaces: Store::new(base.join("context_workspaces.json")),
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(command) = cli.command {
|
||||||
|
match command {
|
||||||
|
Commands::Gate { subcmd } => {
|
||||||
|
match subcmd {
|
||||||
|
GateCommands::Set { action, target, namespace, params, authorize, block, reason } => {
|
||||||
|
let status = if authorize { "authorized".to_string() } else if block { "blocked".to_string() } else { "pending".to_string() };
|
||||||
|
let mut param_map = HashMap::new();
|
||||||
|
for p in params {
|
||||||
|
if let Some((k, v)) = p.split_once('=') {
|
||||||
|
param_map.insert(k.to_string(), v.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let record = GateRecord {
|
||||||
|
id: uuid::Uuid::new_v4().to_string(),
|
||||||
|
action: action.clone(),
|
||||||
|
target: target.clone(),
|
||||||
|
namespace,
|
||||||
|
params: param_map,
|
||||||
|
status,
|
||||||
|
reason,
|
||||||
|
timestamp: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
|
||||||
|
};
|
||||||
|
state.gates.modify(|gates| {
|
||||||
|
gates.retain(|g| !(g.action == record.action && g.target == record.target));
|
||||||
|
gates.push(record);
|
||||||
|
});
|
||||||
|
println!("Gate state updated.");
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
GateCommands::Verify { action, target, namespace, params, consume } => {
|
||||||
|
let mut param_map = HashMap::new();
|
||||||
|
for p in params {
|
||||||
|
if let Some((k, v)) = p.split_once('=') {
|
||||||
|
param_map.insert(k.to_string(), v.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut found = None;
|
||||||
|
let mut to_remove = None;
|
||||||
|
state.gates.modify(|gates| {
|
||||||
|
if let Some(idx) = gates.iter().position(|g| g.action == action && g.target == target && g.namespace == namespace && g.params == param_map) {
|
||||||
|
found = Some(gates[idx].clone());
|
||||||
|
if consume {
|
||||||
|
to_remove = Some(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(idx) = to_remove {
|
||||||
|
gates.remove(idx);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
match found {
|
||||||
|
Some(record) => {
|
||||||
|
if record.status == "authorized" {
|
||||||
|
std::process::exit(0);
|
||||||
|
} else {
|
||||||
|
if let Some(r) = record.reason {
|
||||||
|
eprintln!("❌ Action blocked. Reason: {}", r);
|
||||||
|
} else {
|
||||||
|
eprintln!("❌ Action blocked.");
|
||||||
|
}
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
eprintln!("❌ Action not yet authorized (no gate record found).");
|
||||||
|
std::process::exit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run_server(state)
|
||||||
|
}
|
||||||
+175
@@ -0,0 +1,175 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct CodeChange {
|
||||||
|
pub timestamp: u64,
|
||||||
|
pub file_path: String,
|
||||||
|
pub description: String,
|
||||||
|
pub git_commit: Option<String>,
|
||||||
|
pub git_branch: Option<String>,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct StickyNote {
|
||||||
|
pub timestamp: u64,
|
||||||
|
pub content: String,
|
||||||
|
}
|
||||||
|
pub fn default_namespace() -> String {
|
||||||
|
"global".to_string()
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Entity {
|
||||||
|
pub name: String,
|
||||||
|
#[serde(rename = "entityType")]
|
||||||
|
pub entity_type: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub observations: Vec<String>,
|
||||||
|
#[serde(default = "default_namespace")]
|
||||||
|
pub namespace: String,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
||||||
|
pub struct Relation {
|
||||||
|
pub from: String,
|
||||||
|
pub to: String,
|
||||||
|
#[serde(rename = "relationType")]
|
||||||
|
pub relation_type: String,
|
||||||
|
#[serde(default = "default_namespace")]
|
||||||
|
pub namespace: String,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
|
pub struct KnowledgeGraph {
|
||||||
|
#[serde(default)]
|
||||||
|
pub entities: HashMap<String, Entity>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub relations: Vec<Relation>,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct Task {
|
||||||
|
pub id: String,
|
||||||
|
pub title: String,
|
||||||
|
pub status: String,
|
||||||
|
pub description: String,
|
||||||
|
pub created_at: u64,
|
||||||
|
pub updated_at: u64,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct Snippet {
|
||||||
|
pub name: String,
|
||||||
|
pub language: String,
|
||||||
|
pub code: String,
|
||||||
|
pub description: String,
|
||||||
|
pub updated_at: u64,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct Adr {
|
||||||
|
pub id: String,
|
||||||
|
pub title: String,
|
||||||
|
pub context: String,
|
||||||
|
pub decision: String,
|
||||||
|
pub consequence: String,
|
||||||
|
pub timestamp: u64,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct Preference {
|
||||||
|
pub key: String,
|
||||||
|
pub value: String,
|
||||||
|
pub updated_at: u64,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct ErrorFix {
|
||||||
|
pub signature: String,
|
||||||
|
pub solution: String,
|
||||||
|
pub timestamp: u64,
|
||||||
|
pub git_commit: Option<String>,
|
||||||
|
pub git_branch: Option<String>,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct PinnedFile {
|
||||||
|
pub namespace: String,
|
||||||
|
pub file_path: String,
|
||||||
|
pub timestamp: u64,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct SessionSummary {
|
||||||
|
pub timestamp: u64,
|
||||||
|
pub summary: String,
|
||||||
|
pub namespace: String,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct HandoffMemo {
|
||||||
|
pub id: String,
|
||||||
|
pub author: String,
|
||||||
|
pub content: String,
|
||||||
|
pub namespace: String,
|
||||||
|
pub timestamp: u64,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct EnvFingerprint {
|
||||||
|
pub namespace: String,
|
||||||
|
pub os: String,
|
||||||
|
pub shell: String,
|
||||||
|
pub tool_versions: HashMap<String, String>,
|
||||||
|
pub updated_at: u64,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct EnvRequirement {
|
||||||
|
pub namespace: String,
|
||||||
|
pub key: String,
|
||||||
|
pub description: String,
|
||||||
|
pub is_secret: bool,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct Milestone {
|
||||||
|
pub id: String,
|
||||||
|
pub title: String,
|
||||||
|
pub status: String,
|
||||||
|
pub namespace: String,
|
||||||
|
pub target_date: Option<u64>,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct EnvironmentDetail {
|
||||||
|
pub namespace: String,
|
||||||
|
pub name: String,
|
||||||
|
pub url: String,
|
||||||
|
pub description: String,
|
||||||
|
pub requires_vpn: bool,
|
||||||
|
pub updated_at: u64,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct PrChecklistItem {
|
||||||
|
pub namespace: String,
|
||||||
|
pub id: String,
|
||||||
|
pub description: String,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct TechDebt {
|
||||||
|
pub id: String,
|
||||||
|
pub namespace: String,
|
||||||
|
pub description: String,
|
||||||
|
pub ideal_solution: String,
|
||||||
|
pub is_resolved: bool,
|
||||||
|
pub created_at: u64,
|
||||||
|
pub git_commit: Option<String>,
|
||||||
|
pub git_branch: Option<String>,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct ContextWorkspace {
|
||||||
|
pub name: String,
|
||||||
|
pub namespace: String,
|
||||||
|
pub pinned_files: Vec<String>,
|
||||||
|
pub active_task_ids: Vec<String>,
|
||||||
|
pub saved_at: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct GateRecord {
|
||||||
|
pub id: String,
|
||||||
|
pub action: String,
|
||||||
|
pub target: String,
|
||||||
|
pub namespace: Option<String>,
|
||||||
|
pub params: std::collections::HashMap<String, String>,
|
||||||
|
pub status: String,
|
||||||
|
pub reason: Option<String>,
|
||||||
|
pub timestamp: u64,
|
||||||
|
}
|
||||||
+141
@@ -0,0 +1,141 @@
|
|||||||
|
use crate::models::*;
|
||||||
|
use crate::store::{Store, read_json_file, write_json_atomic};
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
use std::fs;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::sync::RwLock;
|
||||||
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
|
pub struct MemoryState {
|
||||||
|
pub base_dir: PathBuf,
|
||||||
|
pub master_path: PathBuf,
|
||||||
|
pub delta_path: PathBuf,
|
||||||
|
pub session_graph: RwLock<KnowledgeGraph>,
|
||||||
|
pub master_cache: RwLock<(KnowledgeGraph, SystemTime)>,
|
||||||
|
pub ledger: Store<Vec<CodeChange>>,
|
||||||
|
pub sticky: Store<Vec<StickyNote>>,
|
||||||
|
pub tasks: Store<Vec<Task>>,
|
||||||
|
pub snippets: Store<Vec<Snippet>>,
|
||||||
|
pub adrs: Store<Vec<Adr>>,
|
||||||
|
pub prefs: Store<HashMap<String, Preference>>,
|
||||||
|
pub error_fixes: Store<Vec<ErrorFix>>,
|
||||||
|
pub pinned_files: Store<Vec<PinnedFile>>,
|
||||||
|
pub session_summaries: Store<Vec<SessionSummary>>,
|
||||||
|
pub handoff_memos: Store<Vec<HandoffMemo>>,
|
||||||
|
pub env_fingerprints: Store<HashMap<String, EnvFingerprint>>,
|
||||||
|
pub env_requirements: Store<Vec<EnvRequirement>>,
|
||||||
|
pub milestones: Store<Vec<Milestone>>,
|
||||||
|
pub environments: Store<Vec<EnvironmentDetail>>,
|
||||||
|
pub pr_checklists: Store<Vec<PrChecklistItem>>,
|
||||||
|
pub tech_debts: Store<Vec<TechDebt>>,
|
||||||
|
pub gates: Store<Vec<GateRecord>>,
|
||||||
|
pub context_workspaces: Store<Vec<ContextWorkspace>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemoryState {
|
||||||
|
fn master_mtime(&self) -> SystemTime {
|
||||||
|
fs::metadata(&self.master_path)
|
||||||
|
.and_then(|m| m.modified())
|
||||||
|
.unwrap_or(SystemTime::UNIX_EPOCH)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unique_items<T: Eq + std::hash::Hash + Clone>(input: Vec<T>) -> Vec<T> {
|
||||||
|
let mut keys = HashSet::new();
|
||||||
|
let mut list = Vec::new();
|
||||||
|
for entry in input {
|
||||||
|
if keys.insert(entry.clone()) {
|
||||||
|
list.push(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list
|
||||||
|
}
|
||||||
|
pub fn merge_graphs(dest: &mut KnowledgeGraph, src: &KnowledgeGraph) {
|
||||||
|
for (name, src_ent) in &src.entities {
|
||||||
|
let dest_ent = dest
|
||||||
|
.entities
|
||||||
|
.entry(name.clone())
|
||||||
|
.or_insert_with(|| src_ent.clone());
|
||||||
|
if dest_ent.name == src_ent.name {
|
||||||
|
dest_ent.observations.extend(src_ent.observations.clone());
|
||||||
|
dest_ent.observations = Self::unique_items(dest_ent.observations.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dest.relations.extend(src.relations.clone());
|
||||||
|
dest.relations = Self::unique_items(dest.relations.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_master_cached(&self) -> KnowledgeGraph {
|
||||||
|
let current_mtime = self.master_mtime();
|
||||||
|
{
|
||||||
|
let lock = self.master_cache.read().unwrap();
|
||||||
|
if lock.1 == current_mtime {
|
||||||
|
return lock.0.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut lock = self.master_cache.write().unwrap();
|
||||||
|
let new_mtime = self.master_mtime();
|
||||||
|
if lock.1 != new_mtime {
|
||||||
|
lock.0 = read_json_file(&self.master_path);
|
||||||
|
lock.1 = new_mtime;
|
||||||
|
}
|
||||||
|
lock.0.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_full_graph(&self) -> KnowledgeGraph {
|
||||||
|
let mut master = self.read_master_cached();
|
||||||
|
let pattern = format!("{}/delta_*.json", self.base_dir.display());
|
||||||
|
if let Ok(paths) = glob::glob(&pattern) {
|
||||||
|
for path in paths.flatten() {
|
||||||
|
if path == self.delta_path {
|
||||||
|
let session_graph = self.session_graph.read().unwrap();
|
||||||
|
Self::merge_graphs(&mut master, &session_graph);
|
||||||
|
} else {
|
||||||
|
let d: KnowledgeGraph = read_json_file(&path);
|
||||||
|
Self::merge_graphs(&mut master, &d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
master
|
||||||
|
}
|
||||||
|
pub fn write_to_local_delta<F: FnOnce(&mut KnowledgeGraph)>(&self, update_fn: F) {
|
||||||
|
let mut session_graph = self.session_graph.write().unwrap();
|
||||||
|
update_fn(&mut session_graph);
|
||||||
|
let _ = write_json_atomic(&self.delta_path, &*session_graph);
|
||||||
|
}
|
||||||
|
pub fn apply_sync_write<F: FnOnce(&mut KnowledgeGraph)>(&self, update_fn: F) {
|
||||||
|
let lock_path = self.base_dir.join("master.lock");
|
||||||
|
let mut attempts = 0;
|
||||||
|
loop {
|
||||||
|
if fs::OpenOptions::new()
|
||||||
|
.create_new(true)
|
||||||
|
.write(true)
|
||||||
|
.open(&lock_path)
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if attempts > 100 {
|
||||||
|
let _ = fs::remove_file(&lock_path);
|
||||||
|
}
|
||||||
|
attempts += 1;
|
||||||
|
std::thread::sleep(Duration::from_millis(50));
|
||||||
|
}
|
||||||
|
let mut master = self.get_full_graph();
|
||||||
|
let pattern = format!("{}/delta_*.json", self.base_dir.display());
|
||||||
|
if let Ok(paths) = glob::glob(&pattern) {
|
||||||
|
for path in paths.flatten() {
|
||||||
|
let _ = fs::remove_file(&path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*self.session_graph.write().unwrap() = KnowledgeGraph::default();
|
||||||
|
update_fn(&mut master);
|
||||||
|
let _ = write_json_atomic(&self.master_path, &master);
|
||||||
|
|
||||||
|
let mut cache_lock = self.master_cache.write().unwrap();
|
||||||
|
cache_lock.0 = master;
|
||||||
|
cache_lock.1 = self.master_mtime();
|
||||||
|
|
||||||
|
let _ = fs::remove_file(&lock_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
use std::fs;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::RwLock;
|
||||||
|
use std::time::SystemTime;
|
||||||
|
|
||||||
|
pub fn read_json_file<T: DeserializeOwned + Default>(path: &Path) -> T {
|
||||||
|
if let Ok(data) = fs::read(path)
|
||||||
|
&& let Ok(parsed) = serde_json::from_slice(&data) {
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
let bak_path = path.with_extension("json.bak");
|
||||||
|
if let Ok(data) = fs::read(&bak_path)
|
||||||
|
&& let Ok(parsed) = serde_json::from_slice(&data) {
|
||||||
|
let _ = fs::write(path, data);
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
T::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_json_atomic<T: Serialize>(path: &Path, data: &T) -> std::io::Result<()> {
|
||||||
|
if path.exists() {
|
||||||
|
let bak_path = path.with_extension("json.bak");
|
||||||
|
let _ = fs::copy(path, &bak_path);
|
||||||
|
}
|
||||||
|
let tmp_path = path.with_extension("json.tmp");
|
||||||
|
let json_data = serde_json::to_string_pretty(data)?;
|
||||||
|
fs::write(&tmp_path, json_data)?;
|
||||||
|
fs::rename(&tmp_path, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Store<T> {
|
||||||
|
pub path: PathBuf,
|
||||||
|
pub cache: RwLock<(T, SystemTime)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: DeserializeOwned + Default + Serialize + Clone> Store<T> {
|
||||||
|
fn mtime(&self) -> SystemTime {
|
||||||
|
fs::metadata(&self.path)
|
||||||
|
.and_then(|m| m.modified())
|
||||||
|
.unwrap_or(SystemTime::UNIX_EPOCH)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(path: PathBuf) -> Self {
|
||||||
|
let mtime = fs::metadata(&path)
|
||||||
|
.and_then(|m| m.modified())
|
||||||
|
.unwrap_or(SystemTime::UNIX_EPOCH);
|
||||||
|
let initial_data = read_json_file(&path);
|
||||||
|
Self {
|
||||||
|
path,
|
||||||
|
cache: RwLock::new((initial_data, mtime)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(&self) -> T {
|
||||||
|
let current_mtime = self.mtime();
|
||||||
|
{
|
||||||
|
let lock = self.cache.read().unwrap();
|
||||||
|
if lock.1 == current_mtime {
|
||||||
|
return lock.0.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut lock = self.cache.write().unwrap();
|
||||||
|
let new_mtime = self.mtime();
|
||||||
|
if lock.1 != new_mtime {
|
||||||
|
lock.0 = read_json_file(&self.path);
|
||||||
|
lock.1 = new_mtime;
|
||||||
|
}
|
||||||
|
lock.0.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn modify<F: FnOnce(&mut T)>(&self, f: F) {
|
||||||
|
let mut lock = self.cache.write().unwrap();
|
||||||
|
let current_mtime = self.mtime();
|
||||||
|
if lock.1 != current_mtime {
|
||||||
|
lock.0 = read_json_file(&self.path);
|
||||||
|
}
|
||||||
|
f(&mut lock.0);
|
||||||
|
let _ = write_json_atomic(&self.path, &lock.0);
|
||||||
|
lock.1 = self.mtime();
|
||||||
|
}
|
||||||
|
}
|
||||||
+364
@@ -0,0 +1,364 @@
|
|||||||
|
use rust_mcp_sdk::macros;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[macros::mcp_tool(name = "create_entities", description = "Create multiple new entities")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct CreateEntitiesTool {
|
||||||
|
pub entities: Vec<serde_json::Value>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(
|
||||||
|
name = "create_relations",
|
||||||
|
description = "Create multiple new relations"
|
||||||
|
)]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct CreateRelationsTool {
|
||||||
|
pub relations: Vec<serde_json::Value>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(
|
||||||
|
name = "add_observations",
|
||||||
|
description = "Add observations to entities"
|
||||||
|
)]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct AddObservationsTool {
|
||||||
|
pub observations: Vec<serde_json::Value>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(
|
||||||
|
name = "delete_entities",
|
||||||
|
description = "Delete entities and relations"
|
||||||
|
)]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct DeleteEntitiesTool {
|
||||||
|
#[serde(rename = "entityNames")]
|
||||||
|
pub entity_names: Vec<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "delete_observations", description = "Delete observations")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct DeleteObservationsTool {
|
||||||
|
pub deletions: Vec<serde_json::Value>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "delete_relations", description = "Delete relations")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct DeleteRelationsTool {
|
||||||
|
pub relations: Vec<serde_json::Value>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "read_graph", description = "Read the entire knowledge graph")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct ReadGraphTool {
|
||||||
|
pub namespace: Option<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "search_nodes", description = "Search for nodes")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct SearchNodesTool {
|
||||||
|
pub query: String,
|
||||||
|
pub namespace: Option<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "open_nodes", description = "Open specific nodes")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct OpenNodesTool {
|
||||||
|
pub names: Vec<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "log_code_change", description = "Log a code change")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct LogCodeChangeTool {
|
||||||
|
#[serde(rename = "filePath")]
|
||||||
|
pub file_path: String,
|
||||||
|
pub description: String,
|
||||||
|
pub git_commit: Option<String>,
|
||||||
|
pub git_branch: Option<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "query_recent_changes", description = "Query the audit ledger")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct QueryRecentChangesTool {}
|
||||||
|
#[macros::mcp_tool(name = "visualize_graph", description = "Generate Mermaid diagram")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct VisualizeGraphTool {
|
||||||
|
pub query: Option<String>,
|
||||||
|
pub namespace: Option<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "add_sticky_note", description = "Add a sticky note")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct AddStickyNoteTool {
|
||||||
|
pub content: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "read_sticky_notes", description = "Read sticky notes")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct ReadStickyNotesTool {}
|
||||||
|
#[macros::mcp_tool(name = "condense_entity", description = "Condense observations")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct CondenseEntityTool {
|
||||||
|
#[serde(rename = "entityName")]
|
||||||
|
pub entity_name: String,
|
||||||
|
pub summarized_observations: Vec<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "add_task", description = "Add a task")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct AddTaskTool {
|
||||||
|
pub title: String,
|
||||||
|
pub description: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "update_task_status", description = "Update task status")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct UpdateTaskStatusTool {
|
||||||
|
pub id: String,
|
||||||
|
pub status: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "list_active_tasks", description = "List active tasks")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct ListActiveTasksTool {}
|
||||||
|
#[macros::mcp_tool(name = "store_snippet", description = "Store code snippet")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct StoreSnippetTool {
|
||||||
|
pub name: String,
|
||||||
|
pub language: String,
|
||||||
|
pub code: String,
|
||||||
|
pub description: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "search_snippets", description = "Search snippets")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct SearchSnippetsTool {
|
||||||
|
pub query: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "delete_snippet", description = "Delete snippet")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct DeleteSnippetTool {
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(
|
||||||
|
name = "log_decision",
|
||||||
|
description = "Log architectural decision record"
|
||||||
|
)]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct LogDecisionTool {
|
||||||
|
pub title: String,
|
||||||
|
pub context: String,
|
||||||
|
pub decision: String,
|
||||||
|
pub consequence: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "query_decisions", description = "Query decision records")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct QueryDecisionsTool {
|
||||||
|
pub query: Option<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(
|
||||||
|
name = "merge_entities",
|
||||||
|
description = "Merge source entity into target entity"
|
||||||
|
)]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct MergeEntitiesTool {
|
||||||
|
#[serde(rename = "sourceEntity")]
|
||||||
|
pub source_entity: String,
|
||||||
|
#[serde(rename = "targetEntity")]
|
||||||
|
pub target_entity: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "find_orphans", description = "Find entities with no relations")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct FindOrphansTool {}
|
||||||
|
#[macros::mcp_tool(
|
||||||
|
name = "learn_preference",
|
||||||
|
description = "Store an AI behavioral preference"
|
||||||
|
)]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct LearnPreferenceTool {
|
||||||
|
pub key: String,
|
||||||
|
pub value: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(
|
||||||
|
name = "read_preferences",
|
||||||
|
description = "Read all learned behavioral preferences"
|
||||||
|
)]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct ReadPreferencesTool {}
|
||||||
|
#[macros::mcp_tool(name = "log_error_fix", description = "Log an error fix")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct LogErrorFixTool {
|
||||||
|
pub signature: String,
|
||||||
|
pub solution: String,
|
||||||
|
pub git_commit: Option<String>,
|
||||||
|
pub git_branch: Option<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "search_error_fixes", description = "Search error fixes")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct SearchErrorFixesTool {
|
||||||
|
pub query: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "pin_file", description = "Pin a file to working set")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct PinFileTool {
|
||||||
|
pub namespace: String,
|
||||||
|
pub file_path: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "unpin_file", description = "Unpin a file")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct UnpinFileTool {
|
||||||
|
pub namespace: String,
|
||||||
|
pub file_path: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "list_pinned_files", description = "List pinned files")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct ListPinnedFilesTool {
|
||||||
|
pub namespace: Option<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "add_session_summary", description = "Add a session summary")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct AddSessionSummaryTool {
|
||||||
|
pub summary: String,
|
||||||
|
pub namespace: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "get_project_timeline", description = "Get project timeline")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct GetProjectTimelineTool {
|
||||||
|
pub namespace: Option<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(
|
||||||
|
name = "leave_handoff_memo",
|
||||||
|
description = "Leave memo for next session"
|
||||||
|
)]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct LeaveHandoffMemoTool {
|
||||||
|
pub content: String,
|
||||||
|
pub namespace: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "read_handoff_memos", description = "Read pending memos")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct ReadHandoffMemosTool {
|
||||||
|
pub namespace: Option<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "clear_handoff_memos", description = "Clear read memos")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct ClearHandoffMemosTool {
|
||||||
|
pub ids: Vec<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "update_env_fingerprint", description = "Update env versions")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct UpdateEnvFingerprintTool {
|
||||||
|
pub namespace: String,
|
||||||
|
pub tool_versions: std::collections::HashMap<String, String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "read_env_fingerprint", description = "Read env footprint")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct ReadEnvFingerprintTool {
|
||||||
|
pub namespace: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "log_env_requirement", description = "Log env var requirement")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct LogEnvRequirementTool {
|
||||||
|
pub namespace: String,
|
||||||
|
pub key: String,
|
||||||
|
pub description: String,
|
||||||
|
pub is_secret: bool,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "add_milestone", description = "Add project milestone")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct AddMilestoneTool {
|
||||||
|
pub title: String,
|
||||||
|
pub namespace: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "update_milestone", description = "Update milestone status")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct UpdateMilestoneTool {
|
||||||
|
pub id: String,
|
||||||
|
pub status: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "list_milestones", description = "List milestones")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct ListMilestonesTool {
|
||||||
|
pub namespace: Option<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(
|
||||||
|
name = "generate_standup_report",
|
||||||
|
description = "Generate a standup report"
|
||||||
|
)]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct GenerateStandupReportTool {
|
||||||
|
pub namespace: String,
|
||||||
|
pub hours_lookback: u64,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "register_environment", description = "Register an environment")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct RegisterEnvironmentTool {
|
||||||
|
pub namespace: String,
|
||||||
|
pub name: String,
|
||||||
|
pub url: String,
|
||||||
|
pub description: String,
|
||||||
|
pub requires_vpn: bool,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(
|
||||||
|
name = "get_environment_details",
|
||||||
|
description = "Get environment details"
|
||||||
|
)]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct GetEnvironmentDetailsTool {
|
||||||
|
pub namespace: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(
|
||||||
|
name = "add_pr_checklist_item",
|
||||||
|
description = "Add a PR checklist item"
|
||||||
|
)]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct AddPrChecklistItemTool {
|
||||||
|
pub namespace: String,
|
||||||
|
pub description: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "get_pr_checklist", description = "Get the PR checklist")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct GetPrChecklistTool {
|
||||||
|
pub namespace: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "clear_pr_checklist", description = "Clear the PR checklist")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct ClearPrChecklistTool {
|
||||||
|
pub namespace: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "log_tech_debt", description = "Log tech debt")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct LogTechDebtTool {
|
||||||
|
pub namespace: String,
|
||||||
|
pub description: String,
|
||||||
|
pub ideal_solution: String,
|
||||||
|
pub git_commit: Option<String>,
|
||||||
|
pub git_branch: Option<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "resolve_tech_debt", description = "Resolve tech debt")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct ResolveTechDebtTool {
|
||||||
|
pub id: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "list_tech_debt", description = "List tech debt")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct ListTechDebtTool {
|
||||||
|
pub namespace: String,
|
||||||
|
pub include_resolved: bool,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "save_context_workspace", description = "Save current context")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct SaveContextWorkspaceTool {
|
||||||
|
pub namespace: String,
|
||||||
|
pub name: String,
|
||||||
|
pub pinned_files: Vec<String>,
|
||||||
|
pub active_task_ids: Vec<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "load_context_workspace", description = "Load context")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct LoadContextWorkspaceTool {
|
||||||
|
pub namespace: String,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "list_context_workspaces", description = "List contexts")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct ListContextWorkspacesTool {
|
||||||
|
pub namespace: String,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(name = "omni_search", description = "Search across all memory vaults")]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct OmniSearchTool {
|
||||||
|
pub query: String,
|
||||||
|
pub namespace: Option<String>,
|
||||||
|
}
|
||||||
|
#[macros::mcp_tool(
|
||||||
|
name = "get_project_health",
|
||||||
|
description = "Get project health metrics"
|
||||||
|
)]
|
||||||
|
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
|
||||||
|
pub struct GetProjectHealthTool {
|
||||||
|
pub namespace: String,
|
||||||
|
}
|
||||||
Reference in new issue
Block a user