Refactor to Pure Native JSON-RPC (Ditch SDKs)

This commit is contained in:
Riz Ashraf committed 2026-09-08 21:50:40 +01:00
1 parent 5f0eba8a80
commit f9dee11f32
9 files changed
+575 -1169

No files matched your search

Generated
+72 -512
View File
@@ -99,30 +99,6 @@ version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
[[package]]
name = "aws-lc-rs"
version = "1.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e"
dependencies = [
"aws-lc-sys",
"untrusted 0.7.1",
"zeroize",
]
[[package]]
name = "aws-lc-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27"
dependencies = [
"cc",
"cmake",
"dunce",
"fs_extra",
"pkg-config",
]
[[package]] [[package]]
name = "axum" name = "axum"
version = "0.8.9" version = "0.8.9"
@@ -175,35 +151,12 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "axum-server"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1df331683d982a0b9492b38127151e6453639cd34926eb9c07d4cd8c6d22bfc"
dependencies = [
"bytes",
"either",
"fs-err",
"http",
"http-body",
"hyper",
"hyper-util",
"tokio",
"tower-service",
]
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.22.1" version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.13.1" version = "2.13.1"
@@ -219,15 +172,6 @@ dependencies = [
"crunchy", "crunchy",
] ]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]] [[package]]
name = "bon" name = "bon"
version = "3.10.1" version = "3.10.1"
@@ -306,8 +250,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures 0.3.1", "cpufeatures",
"rand_core 0.10.1", "rand_core",
] ]
[[package]] [[package]]
@@ -350,59 +294,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
[[package]]
name = "cmake"
version = "0.1.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "colorchoice" name = "colorchoice"
version = "1.0.5" version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
[[package]]
name = "cookie"
version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a373e3602691c3cdea496d2f0ee5935151e6168fe87739483c463db1b2f2f87"
dependencies = [
"percent-encoding",
"time",
"version_check",
]
[[package]]
name = "cookie_store"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15b2c103cf610ec6cae3da84a766285b42fd16aad564758459e6ecf128c75206"
dependencies = [
"cookie",
"document-features",
"idna",
"log",
"publicsuffix",
"serde",
"serde_derive",
"serde_json",
"time",
"url",
]
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.3.1" version = "0.3.1"
@@ -461,16 +358,6 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[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]] [[package]]
name = "darling" name = "darling"
version = "0.24.1" version = "0.24.1"
@@ -520,17 +407,6 @@ dependencies = [
"serde_core", "serde_core",
] ]
[[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]] [[package]]
name = "dirs" name = "dirs"
version = "6.0.0" version = "6.0.0"
@@ -563,15 +439,6 @@ dependencies = [
"syn 3.0.5", "syn 3.0.5",
] ]
[[package]]
name = "document-features"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
dependencies = [
"litrs",
]
[[package]] [[package]]
name = "downcast-rs" name = "downcast-rs"
version = "2.0.2" version = "2.0.2"
@@ -579,10 +446,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc" checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc"
[[package]] [[package]]
name = "dunce" name = "dyn-clone"
version = "1.0.5" version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
[[package]] [[package]]
name = "either" name = "either"
@@ -656,16 +523,6 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "fs-err"
version = "3.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91aa448ca50d7e79433bdf3ee8d99215430d2ec02ade5aefab2a073a1822e8a"
dependencies = [
"autocfg",
"tokio",
]
[[package]] [[package]]
name = "fs4" name = "fs4"
version = "0.13.1" version = "0.13.1"
@@ -676,27 +533,6 @@ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
[[package]]
name = "fs_extra"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
[[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]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.34" version = "0.3.34"
@@ -704,7 +540,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-sink",
] ]
[[package]] [[package]]
@@ -713,17 +548,6 @@ version = "0.3.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" 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]] [[package]]
name = "futures-io" name = "futures-io"
version = "0.3.34" version = "0.3.34"
@@ -759,7 +583,6 @@ version = "0.3.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc"
dependencies = [ dependencies = [
"futures-channel",
"futures-core", "futures-core",
"futures-io", "futures-io",
"futures-macro", "futures-macro",
@@ -770,16 +593,6 @@ dependencies = [
"slab", "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]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.17" version = "0.2.17"
@@ -803,7 +616,7 @@ dependencies = [
"js-sys", "js-sys",
"libc", "libc",
"r-efi", "r-efi",
"rand_core 0.10.1", "rand_core",
"wasm-bindgen", "wasm-bindgen",
] ]
@@ -813,25 +626,6 @@ version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b"
[[package]]
name = "h2"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef8e5e5a340588f4452631496976cf8636d4a7ecf600239fdc27615d2530bc16"
dependencies = [
"atomic-waker",
"bytes",
"fnv",
"futures-core",
"futures-sink",
"http",
"indexmap",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.16.1" version = "0.16.1"
@@ -843,27 +637,12 @@ dependencies = [
"foldhash", "foldhash",
] ]
[[package]]
name = "hashbrown"
version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.5.0" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hmac"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
"digest",
]
[[package]] [[package]]
name = "htmlescape" name = "htmlescape"
version = "0.3.1" version = "0.3.1"
@@ -925,7 +704,6 @@ dependencies = [
"bytes", "bytes",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"h2",
"http", "http",
"http-body", "http-body",
"httparse", "httparse",
@@ -959,7 +737,7 @@ version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0"
dependencies = [ dependencies = [
"base64 0.22.1", "base64",
"bytes", "bytes",
"futures-channel", "futures-channel",
"futures-util", "futures-util",
@@ -1086,16 +864,6 @@ dependencies = [
"icu_properties", "icu_properties",
] ]
[[package]]
name = "indexmap"
version = "2.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855"
dependencies = [
"equivalent",
"hashbrown 0.17.1",
]
[[package]] [[package]]
name = "inventory" name = "inventory"
version = "0.3.24" version = "0.3.24"
@@ -1153,24 +921,6 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "jsonwebtoken"
version = "10.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eba32bfb4ffdeaca3e34431072faf01745c9b26d25504aa7a6cf5684334fc4fc"
dependencies = [
"aws-lc-rs",
"base64 0.22.1",
"getrandom 0.2.17",
"js-sys",
"pem",
"serde",
"serde_json",
"signature",
"simple_asn1",
"zeroize",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.5.0" version = "1.5.0"
@@ -1210,12 +960,6 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae"
[[package]]
name = "litrs"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.14" version = "0.4.14"
@@ -1237,7 +981,7 @@ version = "0.16.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39"
dependencies = [ dependencies = [
"hashbrown 0.16.1", "hashbrown",
] ]
[[package]] [[package]]
@@ -1269,12 +1013,12 @@ dependencies = [
"futures-util", "futures-util",
"glob", "glob",
"reqwest", "reqwest",
"rust-mcp-axum", "schemars",
"rust-mcp-sdk",
"serde", "serde",
"serde_json", "serde_json",
"tantivy", "tantivy",
"tokio", "tokio",
"tokio-stream",
"tokio-util", "tokio-util",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
@@ -1322,16 +1066,6 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "mime_guess"
version = "2.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
dependencies = [
"mime",
"unicase",
]
[[package]] [[package]]
name = "minimal-lexical" name = "minimal-lexical"
version = "0.2.1" version = "0.2.1"
@@ -1374,31 +1108,12 @@ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
[[package]]
name = "num-bigint"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367"
dependencies = [
"num-integer",
"num-traits",
]
[[package]] [[package]]
name = "num-conv" name = "num-conv"
version = "0.2.2" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
[[package]]
name = "num-integer"
version = "0.1.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b"
dependencies = [
"num-traits",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.19" version = "0.2.19"
@@ -1408,15 +1123,6 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "num_threads"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.21.4" version = "1.21.4"
@@ -1482,16 +1188,6 @@ dependencies = [
"windows-link", "windows-link",
] ]
[[package]]
name = "pem"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
dependencies = [
"base64 0.22.1",
"serde_core",
]
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.3.2" version = "2.3.2"
@@ -1544,22 +1240,6 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "psl-types"
version = "2.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac"
[[package]]
name = "publicsuffix"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf"
dependencies = [
"idna",
"psl-types",
]
[[package]] [[package]]
name = "quinn" name = "quinn"
version = "0.11.11" version = "0.11.11"
@@ -1639,16 +1319,7 @@ checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
dependencies = [ dependencies = [
"chacha20", "chacha20",
"getrandom 0.4.3", "getrandom 0.4.3",
"rand_core 0.10.1", "rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom 0.2.17",
] ]
[[package]] [[package]]
@@ -1663,7 +1334,7 @@ version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a"
dependencies = [ dependencies = [
"rand_core 0.10.1", "rand_core",
] ]
[[package]] [[package]]
@@ -1706,6 +1377,26 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "ref-cast"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3"
dependencies = [
"ref-cast-impl",
]
[[package]]
name = "ref-cast-impl"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a"
dependencies = [
"proc-macro2",
"quote",
"syn 3.0.5",
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.13.1" version = "1.13.1"
@@ -1741,10 +1432,8 @@ version = "0.12.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
dependencies = [ dependencies = [
"base64 0.22.1", "base64",
"bytes", "bytes",
"cookie",
"cookie_store",
"futures-core", "futures-core",
"futures-util", "futures-util",
"http", "http",
@@ -1755,7 +1444,6 @@ dependencies = [
"hyper-util", "hyper-util",
"js-sys", "js-sys",
"log", "log",
"mime_guess",
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"quinn", "quinn",
@@ -1789,100 +1477,10 @@ dependencies = [
"cfg-if", "cfg-if",
"getrandom 0.2.17", "getrandom 0.2.17",
"libc", "libc",
"untrusted 0.9.0", "untrusted",
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "rust-mcp-axum"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fdd00ac2a7ee6389439a865292faea8ef678b3e01ad66046ea8cf320587dc7"
dependencies = [
"async-trait",
"axum",
"axum-server",
"futures",
"http",
"rust-mcp-sdk",
"thiserror",
"tokio",
"tracing",
]
[[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 0.23.1",
"bytes",
"futures",
"hmac",
"http",
"http-body",
"http-body-util",
"jsonwebtoken",
"reqwest",
"rust-mcp-macros",
"rust-mcp-schema",
"rust-mcp-transport",
"serde",
"serde_json",
"sha2",
"thiserror",
"time",
"tokio",
"tokio-stream",
"tracing",
"url",
"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",
"reqwest",
"rust-mcp-schema",
"serde",
"serde_json",
"thiserror",
"tokio",
"tokio-stream",
"tracing",
]
[[package]] [[package]]
name = "rust-stemmers" name = "rust-stemmers"
version = "1.2.0" version = "1.2.0"
@@ -1944,7 +1542,7 @@ checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2"
dependencies = [ dependencies = [
"ring", "ring",
"rustls-pki-types", "rustls-pki-types",
"untrusted 0.9.0", "untrusted",
] ]
[[package]] [[package]]
@@ -1959,6 +1557,31 @@ version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
[[package]]
name = "schemars"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a"
dependencies = [
"dyn-clone",
"ref-cast",
"schemars_derive",
"serde",
"serde_json",
]
[[package]]
name = "schemars_derive"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d98c67716b46af2f0b8cf752abc930f6f9aecfbf671ecfb531db8a31dbe4e2ba"
dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
"syn 3.0.5",
]
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
@@ -1995,6 +1618,17 @@ dependencies = [
"syn 3.0.5", "syn 3.0.5",
] ]
[[package]]
name = "serde_derive_internals"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f852137cce035d6a4df67ccce505ff6b3e9fd3a10e3e52b24dc71e650bb1a9bd"
dependencies = [
"proc-macro2",
"quote",
"syn 3.0.5",
]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.151" version = "1.0.151"
@@ -2031,17 +1665,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures 0.2.17",
"digest",
]
[[package]] [[package]]
name = "sharded-slab" name = "sharded-slab"
version = "0.1.7" version = "0.1.7"
@@ -2067,27 +1690,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "signature"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
"rand_core 0.6.4",
]
[[package]]
name = "simple_asn1"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d585997b0ac10be3c5ee635f1bab02d512760d14b7c468801ac8a01d9ae5f1d"
dependencies = [
"num-bigint",
"num-traits",
"thiserror",
"time",
]
[[package]] [[package]]
name = "sketches-ddsketch" name = "sketches-ddsketch"
version = "0.4.1" version = "0.4.1"
@@ -2187,7 +1789,7 @@ checksum = "edde6a10743fff00a4e1a8c9ef020bf5f3cbad301b7d2d39f2b07f123c4eac07"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"arc-swap", "arc-swap",
"base64 0.22.1", "base64",
"bitpacking", "bitpacking",
"bon", "bon",
"byteorder", "byteorder",
@@ -2376,9 +1978,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134"
dependencies = [ dependencies = [
"deranged", "deranged",
"libc",
"num-conv", "num-conv",
"num_threads",
"powerfmt", "powerfmt",
"serde_core", "serde_core",
"time-core", "time-core",
@@ -2484,7 +2084,6 @@ dependencies = [
"bytes", "bytes",
"futures-core", "futures-core",
"futures-sink", "futures-sink",
"libc",
"pin-project-lite", "pin-project-lite",
"tokio", "tokio",
] ]
@@ -2605,12 +2204,6 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
[[package]]
name = "typenum"
version = "1.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
[[package]] [[package]]
name = "typetag" name = "typetag"
version = "0.2.23" version = "0.2.23"
@@ -2635,24 +2228,12 @@ dependencies = [
"syn 3.0.5", "syn 3.0.5",
] ]
[[package]]
name = "unicase"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.24" version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]] [[package]]
name = "untrusted" name = "untrusted"
version = "0.9.0" version = "0.9.0"
@@ -2669,7 +2250,6 @@ dependencies = [
"idna", "idna",
"percent-encoding", "percent-encoding",
"serde", "serde",
"serde_derive",
] ]
[[package]] [[package]]
@@ -2708,12 +2288,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]] [[package]]
name = "want" name = "want"
version = "0.3.1" version = "0.3.1"
@@ -3000,20 +2574,6 @@ name = "zeroize"
version = "1.9.0" version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
dependencies = [
"zeroize_derive",
]
[[package]]
name = "zeroize_derive"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.119",
]
[[package]] [[package]]
name = "zerotrie" name = "zerotrie"
+2 -2
View File
@@ -11,12 +11,12 @@ dirs = "6.0.0"
futures-util = "0.3.34" futures-util = "0.3.34"
glob = "0.3.4" glob = "0.3.4"
reqwest = { version = "0.12", default-features = false, features = ["stream", "rustls-tls"] } reqwest = { version = "0.12", default-features = false, features = ["stream", "rustls-tls"] }
rust-mcp-axum = "2.0.0" schemars = "1.2.2"
rust-mcp-sdk = "2.0.0"
serde = { version = "1.0.229", features = ["derive"] } serde = { version = "1.0.229", features = ["derive"] }
serde_json = "1.0.151" serde_json = "1.0.151"
tantivy = "0.26.1" tantivy = "0.26.1"
tokio = { version = "1.53.1", features = ["full"] } tokio = { version = "1.53.1", features = ["full"] }
tokio-stream = "0.1.19"
tokio-util = { version = "0.7.19", features = ["io"] } tokio-util = { version = "0.7.19", features = ["io"] }
tracing = "0.1.44" tracing = "0.1.44"
tracing-subscriber = "0.3.23" tracing-subscriber = "0.3.23"
-73
View File
@@ -1,73 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Brain Monitor</title>
<style>
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; padding: 40px; background-color: #f0f2f5; color: #333; }
h1 { color: #2c3e50; text-align: center; margin-bottom: 30px; }
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; max-width: 800px; margin: 0 auto; }
.stat-card { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.05); text-align: center; transition: transform 0.2s ease; }
.stat-card:hover { transform: translateY(-5px); }
.stat-value { font-size: 2.5em; font-weight: bold; color: #3498db; margin: 10px 0; }
.stat-label { font-size: 1.1em; color: #7f8c8d; text-transform: uppercase; letter-spacing: 1px; }
.status-dot { display: inline-block; width: 10px; height: 10px; background-color: #2ecc71; border-radius: 50%; margin-right: 8px; box-shadow: 0 0 5px #2ecc71; }
.header-bar { max-width: 800px; margin: 0 auto 20px; display: flex; justify-content: space-between; align-items: center; }
</style>
</head>
<body>
<div class="header-bar">
<h1>🧠 Antigravity Brain Monitor</h1>
<div><span class="status-dot"></span>System Online</div>
</div>
<div class="grid">
<div class="stat-card">
<div class="stat-label">Entities</div>
<div class="stat-value" id="val-entities">-</div>
</div>
<div class="stat-card">
<div class="stat-label">Relations</div>
<div class="stat-value" id="val-relations">-</div>
</div>
<div class="stat-card">
<div class="stat-label">Active Tasks</div>
<div class="stat-value" id="val-tasks">-</div>
</div>
<div class="stat-card">
<div class="stat-label">Snippets</div>
<div class="stat-value" id="val-snippets">-</div>
</div>
<div class="stat-card">
<div class="stat-label">Tech Debt</div>
<div class="stat-value" id="val-tech_debts">-</div>
</div>
<div class="stat-card">
<div class="stat-label">ADRs</div>
<div class="stat-value" id="val-adrs">-</div>
</div>
</div>
<script>
async function fetchStats() {
try {
const response = await fetch('/api/stats');
const data = await response.json();
document.getElementById('val-entities').innerText = data.entities;
document.getElementById('val-relations').innerText = data.relations;
document.getElementById('val-tasks').innerText = data.tasks;
document.getElementById('val-snippets').innerText = data.snippets;
document.getElementById('val-tech_debts').innerText = data.tech_debts;
document.getElementById('val-adrs').innerText = data.adrs;
} catch (err) {
console.error("Failed to fetch stats:", err);
}
}
// Initial fetch
fetchStats();
// Poll every 2 seconds
setInterval(fetchStats, 2000);
</script>
</body>
</html>
+296 -338
View File
File diff suppressed because it is too large. Load diff
+77 -80
View File
@@ -1,5 +1,6 @@
mod handlers; mod handlers;
mod models; mod models;
mod mcp;
mod state; mod state;
mod store; mod store;
mod tools; mod tools;
@@ -9,12 +10,7 @@ use crate::handlers::MemoryHandler;
use crate::models::*; use crate::models::*;
use crate::state::MemoryState; use crate::state::MemoryState;
use crate::store::Store; use crate::store::Store;
use rust_mcp_sdk::{
ServerDetails, ToMcpServerHandler,
error::SdkResult,
schema::{Implementation, ServerCapabilities, ServerCapabilitiesTools},
};
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
@@ -109,94 +105,95 @@ async fn reconcile_worker(state: Arc<MemoryState>) {
} }
use rust_mcp_axum::{create_axum_server, AxumServerOptions};
fn run_server(state: Arc<MemoryState>) -> SdkResult<()> {
use axum::{
extract::{State, Query},
response::sse::{Event, Sse},
routing::{get, post},
Json, Router,
};
use futures_util::stream::Stream;
use std::convert::Infallible;
use tokio::sync::mpsc;
use tokio_stream::wrappers::ReceiverStream;
use std::sync::atomic::{AtomicUsize, Ordering};
struct AppState {
handler: Arc<MemoryHandler>,
clients: RwLock<HashMap<String, mpsc::Sender<Result<Event, Infallible>>>>,
next_id: AtomicUsize,
}
fn run_server(state: Arc<MemoryState>) -> Result<(), Box<dyn std::error::Error>> {
let rt = tokio::runtime::Runtime::new().unwrap(); let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async { rt.block_on(async {
let state_clone = state.clone(); tokio::spawn(reconcile_worker(Arc::clone(&state)));
tokio::spawn(async move { let app_state = Arc::new(AppState {
reconcile_worker(state_clone).await; handler: Arc::new(MemoryHandler { state }),
clients: RwLock::new(HashMap::new()),
next_id: AtomicUsize::new(1),
}); });
let server_details = ServerDetails { let app = Router::new()
server_info: Implementation { .route("/sse", get(sse_handler))
name: "gemini-mcp-memory".into(), .route("/messages", post(message_handler))
version: "3.0.0".into(), .with_state(app_state);
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 options = AxumServerOptions {
host: "0.0.0.0".to_string(),
port: 3000,
custom_sse_endpoint: Some("/sse".to_string()),
..Default::default()
};
let server = create_axum_server(
server_details,
MemoryHandler { state: state.clone() }.to_mcp_server_handler(),
options,
);
let server = server.with_route(
"/gate/verify",
axum::routing::get(|| async move {
axum::http::StatusCode::OK
}),
).with_route(
"/dashboard",
axum::routing::get(|| async move {
axum::response::Html(include_str!("dashboard.html"))
}),
).with_route(
"/api/stats",
axum::routing::get({
let state_clone = state.clone();
move || async move {
let (entities, relations) = {
let graph = state_clone.get_full_graph();
(graph.entities.len(), graph.relations.len())
};
let tasks = state_clone.tasks.read().len();
let snippets = state_clone.snippets.read().len();
let tech_debts = state_clone.tech_debts.read().len();
let adrs = state_clone.adrs.read().len();
axum::Json(serde_json::json!({
"entities": entities,
"relations": relations,
"tasks": tasks,
"snippets": snippets,
"tech_debts": tech_debts,
"adrs": adrs
}))
}
}),
);
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
eprintln!("MCP Memory Server running on http://0.0.0.0:3000/sse"); eprintln!("MCP Memory Server running on http://0.0.0.0:3000/sse");
server.start().await.unwrap(); axum::serve(listener, app).await.unwrap();
Ok(()) Ok(())
}) })
} }
async fn sse_handler(
State(state): State<Arc<AppState>>,
) -> Sse<impl Stream<Item = Result<Event, Infallible>>> {
let session_id = format!("{}", state.next_id.fetch_add(1, Ordering::SeqCst));
let (tx, rx) = mpsc::channel::<Result<Event, Infallible>>(100);
state.clients.write().unwrap().insert(session_id.clone(), tx.clone());
let _ = tx.send(Ok(Event::default().event("endpoint").data(format!("?sessionId={}", session_id)))).await;
let stream = ReceiverStream::new(rx);
Sse::new(stream).keep_alive(axum::response::sse::KeepAlive::new())
}
#[derive(serde::Deserialize)]
struct SessionQuery {
#[serde(rename = "sessionId")]
session_id: String,
}
async fn message_handler(
State(state): State<Arc<AppState>>,
Query(query): Query<SessionQuery>,
Json(payload): Json<serde_json::Value>,
) -> axum::http::StatusCode {
let handler = Arc::clone(&state.handler);
let session_id = query.session_id.clone();
let clients = Arc::clone(&state);
tokio::spawn(async move {
if let Some(response) = handler.handle_request(payload).await {
let tx_opt = clients.clients.read().unwrap().get(&session_id).cloned();
if let Some(tx) = tx_opt {
let data = serde_json::to_string(&response).unwrap();
let _ = tx.send(Ok(Event::default().event("message").data(data))).await;
}
}
});
axum::http::StatusCode::ACCEPTED
}
mod proxy; mod proxy;
fn main() -> SdkResult<()> {
fn main() -> Result<(), Box<dyn std::error::Error>> {
let cli = Cli::parse(); let cli = Cli::parse();
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
+32
View File
@@ -0,0 +1,32 @@
use schemars::JsonSchema;
use serde_json::json;
pub fn success(id: serde_json::Value, result: serde_json::Value) -> serde_json::Value {
json!({
"jsonrpc": "2.0",
"id": id,
"result": result
})
}
pub fn error(id: serde_json::Value, code: i32, message: &str) -> serde_json::Value {
json!({
"jsonrpc": "2.0",
"id": id,
"error": {
"code": code,
"message": message
}
})
}
pub fn tool_def<T: JsonSchema>(name: &str, description: &str) -> serde_json::Value {
let schema = schemars::schema_for!(T);
let schema_val = serde_json::to_value(&schema).unwrap();
// MCP expects standard JSON schema. Schemars returns draft-07.
json!({
"name": name,
"description": description,
"inputSchema": schema_val
})
}
+20 -6
View File
@@ -1,22 +1,32 @@
use rust_mcp_sdk::error::SdkResult;
use tokio_util::io::StreamReader; use tokio_util::io::StreamReader;
use tokio::io::AsyncBufReadExt; use tokio::io::AsyncBufReadExt;
use futures_util::StreamExt; use futures_util::StreamExt;
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::RwLock; use tokio::sync::RwLock;
pub fn run_proxy(target_url: &str) -> SdkResult<bool> { pub fn run_proxy(target_url: &str) -> Result<bool, Box<dyn std::error::Error + Send + Sync>> {
let rt = tokio::runtime::Runtime::new().unwrap(); let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async { rt.block_on(async {
let client = reqwest::Client::builder().build().unwrap(); let client = reqwest::Client::builder().build().unwrap();
let sse_url = format!("{}/sse", target_url); let sse_url = format!("{}/sse", target_url);
let resp = match client.get(&sse_url).send().await { eprintln!("[PROXY] Connecting to Streamable HTTP: {}", sse_url);
let resp = match client.get(&sse_url)
.header("Accept", "text/event-stream")
.send().await {
Ok(r) => r, Ok(r) => r,
Err(_) => return Ok(true), // Connection failed (Leader is dead) Err(e) => {
eprintln!("[PROXY] Connection failed: {}", e);
return Ok(true);
}
}; };
let post_url = Arc::new(RwLock::new(format!("{}/messages", target_url))); if resp.status() == reqwest::StatusCode::GONE {
eprintln!("[PROXY] Streamable HTTP endpoint is gone.");
return Ok(true);
}
let post_url = Arc::new(RwLock::new(format!("{}/messages", target_url))); // Will be updated by endpoint event
let post_url_clone = Arc::clone(&post_url); let post_url_clone = Arc::clone(&post_url);
let (tx, mut rx) = tokio::sync::mpsc::channel(1); let (tx, mut rx) = tokio::sync::mpsc::channel(1);
@@ -47,7 +57,11 @@ pub fn run_proxy(target_url: &str) -> SdkResult<bool> {
if url.is_empty() { if url.is_empty() {
url = url_arc.read().await.clone(); url = url_arc.read().await.clone();
} }
let _ = client.post(&url).header("Content-Type", "application/json").body(body).send().await; let _ = client.post(&url)
.header("Accept", "application/json, text/event-stream")
.header("Content-Type", "application/json")
.body(body)
.send().await;
}); });
} }
let _ = tx_clone.blocking_send(false); // Stdin EOF let _ = tx_clone.blocking_send(false); // Stdin EOF
+58 -151
View File
@@ -1,64 +1,45 @@
use rust_mcp_sdk::macros; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[macros::mcp_tool(name = "create_entities", description = "Create multiple new entities")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct CreateEntitiesTool { pub struct CreateEntitiesTool {
pub entities: Vec<serde_json::Value>, pub entities: Vec<serde_json::Value>,
} }
#[macros::mcp_tool( #[derive(Debug, Deserialize, Serialize, JsonSchema)]
name = "create_relations",
description = "Create multiple new relations"
)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct CreateRelationsTool { pub struct CreateRelationsTool {
pub relations: Vec<serde_json::Value>, pub relations: Vec<serde_json::Value>,
} }
#[macros::mcp_tool( #[derive(Debug, Deserialize, Serialize, JsonSchema)]
name = "add_observations",
description = "Add observations to entities"
)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct AddObservationsTool { pub struct AddObservationsTool {
pub observations: Vec<serde_json::Value>, pub observations: Vec<serde_json::Value>,
} }
#[macros::mcp_tool( #[derive(Debug, Deserialize, Serialize, JsonSchema)]
name = "delete_entities",
description = "Delete entities and relations"
)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct DeleteEntitiesTool { pub struct DeleteEntitiesTool {
#[serde(rename = "entityNames")] #[serde(rename = "entityNames")]
pub entity_names: Vec<String>, pub entity_names: Vec<String>,
} }
#[macros::mcp_tool(name = "delete_observations", description = "Delete observations")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct DeleteObservationsTool { pub struct DeleteObservationsTool {
pub deletions: Vec<serde_json::Value>, pub deletions: Vec<serde_json::Value>,
} }
#[macros::mcp_tool(name = "delete_relations", description = "Delete relations")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct DeleteRelationsTool { pub struct DeleteRelationsTool {
pub relations: Vec<serde_json::Value>, pub relations: Vec<serde_json::Value>,
} }
#[macros::mcp_tool(name = "read_graph", description = "Read the entire knowledge graph")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct ReadGraphTool { pub struct ReadGraphTool {
pub namespace: Option<String>, pub namespace: Option<String>,
} }
#[macros::mcp_tool(name = "search_nodes", description = "Search for nodes")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct SearchNodesTool { pub struct SearchNodesTool {
pub query: String, pub query: String,
pub namespace: Option<String>, pub namespace: Option<String>,
} }
#[macros::mcp_tool(name = "open_nodes", description = "Open specific nodes")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct OpenNodesTool { pub struct OpenNodesTool {
pub names: Vec<String>, pub names: Vec<String>,
} }
#[macros::mcp_tool(name = "log_code_change", description = "Log a code change")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct LogCodeChangeTool { pub struct LogCodeChangeTool {
#[serde(rename = "filePath")] #[serde(rename = "filePath")]
pub file_path: String, pub file_path: String,
@@ -66,218 +47,165 @@ pub struct LogCodeChangeTool {
pub git_commit: Option<String>, pub git_commit: Option<String>,
pub git_branch: Option<String>, pub git_branch: Option<String>,
} }
#[macros::mcp_tool(name = "query_recent_changes", description = "Query the audit ledger")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct QueryRecentChangesTool {} pub struct QueryRecentChangesTool {}
#[macros::mcp_tool(name = "visualize_graph", description = "Generate Mermaid diagram")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct VisualizeGraphTool { pub struct VisualizeGraphTool {
pub query: Option<String>, pub query: Option<String>,
pub namespace: Option<String>, pub namespace: Option<String>,
} }
#[macros::mcp_tool(name = "add_sticky_note", description = "Add a sticky note")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct AddStickyNoteTool { pub struct AddStickyNoteTool {
pub content: String, pub content: String,
} }
#[macros::mcp_tool(name = "read_sticky_notes", description = "Read sticky notes")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct ReadStickyNotesTool {} pub struct ReadStickyNotesTool {}
#[macros::mcp_tool(name = "condense_entity", description = "Condense observations")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct CondenseEntityTool { pub struct CondenseEntityTool {
#[serde(rename = "entityName")] #[serde(rename = "entityName")]
pub entity_name: String, pub entity_name: String,
pub summarized_observations: Vec<String>, pub summarized_observations: Vec<String>,
} }
#[macros::mcp_tool(name = "add_task", description = "Add a task")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct AddTaskTool { pub struct AddTaskTool {
pub title: String, pub title: String,
pub description: String, pub description: String,
pub git_branch: Option<String>, pub git_branch: Option<String>,
} }
#[macros::mcp_tool(name = "update_task_status", description = "Update task status")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct UpdateTaskStatusTool { pub struct UpdateTaskStatusTool {
pub id: String, pub id: String,
pub status: String, pub status: String,
} }
#[macros::mcp_tool(name = "list_active_tasks", description = "List active tasks")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct ListActiveTasksTool { pub git_branch: Option<String>, } pub struct ListActiveTasksTool { pub git_branch: Option<String>, }
#[macros::mcp_tool(name = "store_snippet", description = "Store code snippet")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct StoreSnippetTool { pub struct StoreSnippetTool {
pub name: String, pub name: String,
pub language: String, pub language: String,
pub code: String, pub code: String,
pub description: String, pub description: String,
} }
#[macros::mcp_tool(name = "search_snippets", description = "Search snippets")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct SearchSnippetsTool { pub struct SearchSnippetsTool {
pub query: String, pub query: String,
} }
#[macros::mcp_tool(name = "delete_snippet", description = "Delete snippet")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct DeleteSnippetTool { pub struct DeleteSnippetTool {
pub name: String, pub name: String,
} }
#[macros::mcp_tool( #[derive(Debug, Deserialize, Serialize, JsonSchema)]
name = "log_decision",
description = "Log architectural decision record"
)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct LogDecisionTool { pub struct LogDecisionTool {
pub title: String, pub title: String,
pub context: String, pub context: String,
pub decision: String, pub decision: String,
pub consequence: String, pub consequence: String,
} }
#[macros::mcp_tool(name = "query_decisions", description = "Query decision records")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct QueryDecisionsTool { pub struct QueryDecisionsTool {
pub query: Option<String>, pub query: Option<String>,
} }
#[macros::mcp_tool( #[derive(Debug, Deserialize, Serialize, JsonSchema)]
name = "merge_entities",
description = "Merge source entity into target entity"
)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct MergeEntitiesTool { pub struct MergeEntitiesTool {
#[serde(rename = "sourceEntity")] #[serde(rename = "sourceEntity")]
pub source_entity: String, pub source_entity: String,
#[serde(rename = "targetEntity")] #[serde(rename = "targetEntity")]
pub target_entity: String, pub target_entity: String,
} }
#[macros::mcp_tool(name = "find_orphans", description = "Find entities with no relations")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct FindOrphansTool {} pub struct FindOrphansTool {}
#[macros::mcp_tool( #[derive(Debug, Deserialize, Serialize, JsonSchema)]
name = "learn_preference",
description = "Store an AI behavioral preference"
)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct LearnPreferenceTool { pub struct LearnPreferenceTool {
pub key: String, pub key: String,
pub value: String, pub value: String,
} }
#[macros::mcp_tool( #[derive(Debug, Deserialize, Serialize, JsonSchema)]
name = "read_preferences",
description = "Read all learned behavioral preferences"
)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct ReadPreferencesTool {} pub struct ReadPreferencesTool {}
#[macros::mcp_tool(name = "log_error_fix", description = "Log an error fix")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct LogErrorFixTool { pub struct LogErrorFixTool {
pub signature: String, pub signature: String,
pub solution: String, pub solution: String,
pub git_commit: Option<String>, pub git_commit: Option<String>,
pub git_branch: Option<String>, pub git_branch: Option<String>,
} }
#[macros::mcp_tool(name = "search_error_fixes", description = "Search error fixes")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct SearchErrorFixesTool { pub struct SearchErrorFixesTool {
pub query: String, pub query: String,
} }
#[macros::mcp_tool(name = "pin_file", description = "Pin a file to working set")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct PinFileTool { pub struct PinFileTool {
pub namespace: String, pub namespace: String,
pub file_path: String, pub file_path: String,
pub git_branch: Option<String>, pub git_branch: Option<String>,
} }
#[macros::mcp_tool(name = "unpin_file", description = "Unpin a file")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct UnpinFileTool { pub struct UnpinFileTool {
pub namespace: String, pub namespace: String,
pub file_path: String, pub file_path: String,
} }
#[macros::mcp_tool(name = "list_pinned_files", description = "List pinned files")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct ListPinnedFilesTool { pub struct ListPinnedFilesTool {
pub namespace: Option<String>, pub namespace: Option<String>,
pub git_branch: Option<String>, pub git_branch: Option<String>,
} }
#[macros::mcp_tool(name = "add_session_summary", description = "Add a session summary")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct AddSessionSummaryTool { pub struct AddSessionSummaryTool {
pub summary: String, pub summary: String,
pub namespace: String, pub namespace: String,
} }
#[macros::mcp_tool(name = "get_project_timeline", description = "Get project timeline")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct GetProjectTimelineTool { pub struct GetProjectTimelineTool {
pub namespace: Option<String>, pub namespace: Option<String>,
} }
#[macros::mcp_tool( #[derive(Debug, Deserialize, Serialize, JsonSchema)]
name = "leave_handoff_memo",
description = "Leave memo for next session"
)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct LeaveHandoffMemoTool { pub struct LeaveHandoffMemoTool {
pub content: String, pub content: String,
pub namespace: String, pub namespace: String,
} }
#[macros::mcp_tool(name = "read_handoff_memos", description = "Read pending memos")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct ReadHandoffMemosTool { pub struct ReadHandoffMemosTool {
pub namespace: Option<String>, pub namespace: Option<String>,
} }
#[macros::mcp_tool(name = "clear_handoff_memos", description = "Clear read memos")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct ClearHandoffMemosTool { pub struct ClearHandoffMemosTool {
pub ids: Vec<String>, pub ids: Vec<String>,
} }
#[macros::mcp_tool(name = "update_env_fingerprint", description = "Update env versions")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct UpdateEnvFingerprintTool { pub struct UpdateEnvFingerprintTool {
pub namespace: String, pub namespace: String,
pub tool_versions: std::collections::HashMap<String, String>, pub tool_versions: std::collections::HashMap<String, String>,
} }
#[macros::mcp_tool(name = "read_env_fingerprint", description = "Read env footprint")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct ReadEnvFingerprintTool { pub struct ReadEnvFingerprintTool {
pub namespace: String, pub namespace: String,
} }
#[macros::mcp_tool(name = "log_env_requirement", description = "Log env var requirement")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct LogEnvRequirementTool { pub struct LogEnvRequirementTool {
pub namespace: String, pub namespace: String,
pub key: String, pub key: String,
pub description: String, pub description: String,
pub is_secret: bool, pub is_secret: bool,
} }
#[macros::mcp_tool(name = "add_milestone", description = "Add project milestone")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct AddMilestoneTool { pub struct AddMilestoneTool {
pub title: String, pub title: String,
pub namespace: String, pub namespace: String,
} }
#[macros::mcp_tool(name = "update_milestone", description = "Update milestone status")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct UpdateMilestoneTool { pub struct UpdateMilestoneTool {
pub id: String, pub id: String,
pub status: String, pub status: String,
} }
#[macros::mcp_tool(name = "list_milestones", description = "List milestones")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct ListMilestonesTool { pub struct ListMilestonesTool {
pub namespace: Option<String>, pub namespace: Option<String>,
} }
#[macros::mcp_tool( #[derive(Debug, Deserialize, Serialize, JsonSchema)]
name = "generate_standup_report",
description = "Generate a standup report"
)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct GenerateStandupReportTool { pub struct GenerateStandupReportTool {
pub namespace: String, pub namespace: String,
pub hours_lookback: u64, pub hours_lookback: u64,
} }
#[macros::mcp_tool(name = "register_environment", description = "Register an environment")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct RegisterEnvironmentTool { pub struct RegisterEnvironmentTool {
pub namespace: String, pub namespace: String,
pub name: String, pub name: String,
@@ -285,35 +213,24 @@ pub struct RegisterEnvironmentTool {
pub description: String, pub description: String,
pub requires_vpn: bool, pub requires_vpn: bool,
} }
#[macros::mcp_tool( #[derive(Debug, Deserialize, Serialize, JsonSchema)]
name = "get_environment_details",
description = "Get environment details"
)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct GetEnvironmentDetailsTool { pub struct GetEnvironmentDetailsTool {
pub namespace: String, pub namespace: String,
} }
#[macros::mcp_tool( #[derive(Debug, Deserialize, Serialize, JsonSchema)]
name = "add_pr_checklist_item",
description = "Add a PR checklist item"
)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct AddPrChecklistItemTool { pub struct AddPrChecklistItemTool {
pub namespace: String, pub namespace: String,
pub description: String, pub description: String,
} }
#[macros::mcp_tool(name = "get_pr_checklist", description = "Get the PR checklist")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct GetPrChecklistTool { pub struct GetPrChecklistTool {
pub namespace: String, pub namespace: String,
} }
#[macros::mcp_tool(name = "clear_pr_checklist", description = "Clear the PR checklist")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct ClearPrChecklistTool { pub struct ClearPrChecklistTool {
pub namespace: String, pub namespace: String,
} }
#[macros::mcp_tool(name = "log_tech_debt", description = "Log tech debt")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct LogTechDebtTool { pub struct LogTechDebtTool {
pub namespace: String, pub namespace: String,
pub description: String, pub description: String,
@@ -321,47 +238,37 @@ pub struct LogTechDebtTool {
pub git_commit: Option<String>, pub git_commit: Option<String>,
pub git_branch: Option<String>, pub git_branch: Option<String>,
} }
#[macros::mcp_tool(name = "resolve_tech_debt", description = "Resolve tech debt")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct ResolveTechDebtTool { pub struct ResolveTechDebtTool {
pub id: String, pub id: String,
} }
#[macros::mcp_tool(name = "list_tech_debt", description = "List tech debt")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct ListTechDebtTool { pub struct ListTechDebtTool {
pub namespace: String, pub namespace: String,
pub include_resolved: bool, pub include_resolved: bool,
} }
#[macros::mcp_tool(name = "save_context_workspace", description = "Save current context")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct SaveContextWorkspaceTool { pub struct SaveContextWorkspaceTool {
pub namespace: String, pub namespace: String,
pub name: String, pub name: String,
pub pinned_files: Vec<String>, pub pinned_files: Vec<String>,
pub active_task_ids: Vec<String>, pub active_task_ids: Vec<String>,
} }
#[macros::mcp_tool(name = "load_context_workspace", description = "Load context")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct LoadContextWorkspaceTool { pub struct LoadContextWorkspaceTool {
pub namespace: String, pub namespace: String,
pub name: String, pub name: String,
} }
#[macros::mcp_tool(name = "list_context_workspaces", description = "List contexts")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct ListContextWorkspacesTool { pub struct ListContextWorkspacesTool {
pub namespace: String, pub namespace: String,
} }
#[macros::mcp_tool(name = "omni_search", description = "Search across all memory vaults")] #[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct OmniSearchTool { pub struct OmniSearchTool {
pub query: String, pub query: String,
pub namespace: Option<String>, pub namespace: Option<String>,
} }
#[macros::mcp_tool( #[derive(Debug, Deserialize, Serialize, JsonSchema)]
name = "get_project_health",
description = "Get project health metrics"
)]
#[derive(Debug, Deserialize, Serialize, macros::JsonSchema)]
pub struct GetProjectHealthTool { pub struct GetProjectHealthTool {
pub namespace: String, pub namespace: String,
} }
+18 -7
View File
@@ -20,16 +20,23 @@ fn run_proxy(target_url: &str) -> Result<bool, Box<dyn std::error::Error>> {
let client = reqwest::Client::builder().build()?; let client = reqwest::Client::builder().build()?;
let sse_url = format!("{}/sse", target_url); let sse_url = format!("{}/sse", target_url);
eprintln!("[PROXY] Connecting to SSE: {}", sse_url); eprintln!("[PROXY] Connecting to Streamable HTTP: {}", sse_url);
let resp = match client.get(&sse_url).send().await { let resp = match client.get(&sse_url)
.header("Accept", "text/event-stream")
.send().await {
Ok(r) => r, Ok(r) => r,
Err(e) => { Err(e) => {
eprintln!("[PROXY] SSE connection failed: {}", e); eprintln!("[PROXY] Connection failed: {}", e);
return Ok(true); return Ok(true);
} }
}; };
let post_url = Arc::new(RwLock::new(format!("{}/messages", target_url))); if resp.status() == reqwest::StatusCode::GONE {
eprintln!("[PROXY] Streamable HTTP endpoint is gone.");
return Ok(true);
}
let post_url = Arc::new(RwLock::new(format!("{}/messages", target_url))); // Will be updated by endpoint event
let post_url_clone = Arc::clone(&post_url); let post_url_clone = Arc::clone(&post_url);
let (tx, mut rx) = tokio::sync::mpsc::channel(1); let (tx, mut rx) = tokio::sync::mpsc::channel(1);
@@ -62,7 +69,11 @@ fn run_proxy(target_url: &str) -> Result<bool, Box<dyn std::error::Error>> {
url = url_arc.read().await.clone(); url = url_arc.read().await.clone();
} }
eprintln!("[PROXY] POSTing to {}", url); eprintln!("[PROXY] POSTing to {}", url);
let res = client.post(&url).header("Content-Type", "application/json").body(body).send().await; let res = client.post(&url)
.header("Accept", "application/json, text/event-stream")
.header("Content-Type", "application/json")
.body(body)
.send().await;
eprintln!("[PROXY] POST response: {:?}", res.map(|r| r.status())); eprintln!("[PROXY] POST response: {:?}", res.map(|r| r.status()));
}); });
} }
@@ -81,7 +92,7 @@ fn run_proxy(target_url: &str) -> Result<bool, Box<dyn std::error::Error>> {
while let Ok(bytes) = reader.read_line(&mut line).await { while let Ok(bytes) = reader.read_line(&mut line).await {
if bytes == 0 { break; } if bytes == 0 { break; }
let trimmed = line.trim(); let trimmed = line.trim();
eprintln!("[PROXY] SSE read: {}", trimmed); eprintln!("[PROXY] Stream read: {}", trimmed);
if trimmed.starts_with("event: message") { if trimmed.starts_with("event: message") {
is_message = true; is_message = true;
is_endpoint = false; is_endpoint = false;
@@ -102,7 +113,7 @@ fn run_proxy(target_url: &str) -> Result<bool, Box<dyn std::error::Error>> {
} }
line.clear(); line.clear();
} }
eprintln!("[PROXY] SSE stream closed"); eprintln!("[PROXY] Stream closed");
let _ = tx_clone2.send(true).await; let _ = tx_clone2.send(true).await;
}); });