diff --git a/Cargo.lock b/Cargo.lock index 6e57996..14acc1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -255,6 +255,29 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" +[[package]] +name = "aws-lc-rs" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce2b2dcc879c3bae0d371e77c99f2238400ef24ec001394befa67b6e543add9e" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f09fae7be8bb3174e05c6afdb34199e6dc0c7c04ba9fa237b1967adfbde27483" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", + "pkg-config", +] + [[package]] name = "base16" version = "0.2.1" @@ -279,6 +302,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "base64ct" version = "1.8.3" @@ -392,7 +421,7 @@ dependencies = [ "num-traits", "once_cell", "rand 0.8.7", - "reqwest", + "reqwest 0.12.28", "schemars", "serde", "serde-map-to-array", @@ -407,24 +436,24 @@ dependencies = [ [[package]] name = "casper-rust-wasm-sdk" version = "2.2.2" -source = "git+https://github.com/casper-ecosystem/casper-rust-wasm-sdk?branch=dev#8047203c43bc5ffbd0c3d329e73e1afbbe6b2447" +source = "git+https://github.com/casper-ecosystem/casper-rust-wasm-sdk?branch=dev#518e48fa465d9bddbc10be6c657cfd02fc0c0229" dependencies = [ "async-trait", "base16", - "base64 0.22.1", + "base64 0.23.1", "bigdecimal", "blake2 0.10.6", "casper-client", "casper-types", "chrono", "futures-util", - "getrandom 0.3.4", + "getrandom 0.4.3", "hex", "humantime", "num-traits", "once_cell", - "rand 0.9.5", - "reqwest", + "rand 0.10.2", + "reqwest 0.13.4", "serde", "serde_json", "thiserror 2.0.20", @@ -477,20 +506,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d262e149917187838d5b42777c8253bcb64500067342904e7d429499a6f277e" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] [[package]] name = "ceps-client" version = "1.0.0" -source = "git+https://github.com/Interchouette-ITC/ceps-rust-ts-client?branch=dev#d7f73fd57b266340c17c4d744fe4fca70666f3d2" +source = "git+https://github.com/Interchouette-ITC/ceps-rust-ts-client?branch=dev#574c30052bf9d1cadd2e1a66609e975eefd4e92b" dependencies = [ "base64 0.22.1", "blake2 0.10.6", "casper-rust-wasm-sdk", "casper-types", "hex", - "reqwest", + "reqwest 0.12.28", "serde", "serde_json", "thiserror 2.0.20", @@ -506,7 +537,7 @@ dependencies = [ "ceps-client", "dotenvy", "parking_lot", - "reqwest", + "reqwest 0.13.4", "serde", "serde_json", "tempfile", @@ -555,6 +586,25 @@ dependencies = [ "windows-link", ] +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -868,6 +918,12 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "dyn-clone" version = "1.0.20" @@ -1045,11 +1101,17 @@ dependencies = [ "percent-encoding", ] +[[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.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a88cf1f829d945f548cf8fec32c61b1f202b6d93b45848602fc02af4b12ad218" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" dependencies = [ "futures-channel", "futures-core", @@ -1062,9 +1124,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -1072,15 +1134,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-executor" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6754879cc9f2c66f88c6e5c35344bb0bdb0708b0352b1201815667c7eabc7458" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" dependencies = [ "futures-core", "futures-task", @@ -1089,38 +1151,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-macro" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.3", ] [[package]] name = "futures-sink" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-channel", "futures-core", @@ -1157,20 +1219,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi 5.3.0", - "wasip2", - "wasm-bindgen", -] - [[package]] name = "getrandom" version = "0.4.3" @@ -1180,7 +1228,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi 6.0.0", + "r-efi", "rand_core 0.10.1", "wasm-bindgen", ] @@ -1297,9 +1345,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" dependencies = [ "bytes", "futures-core", @@ -1600,6 +1648,65 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys", + "log", + "simd_cesu8", + "thiserror 2.0.20", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.119", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + [[package]] name = "js-sys" version = "0.3.104" @@ -1827,9 +1934,9 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" dependencies = [ "num-traits", ] @@ -2051,6 +2158,7 @@ version = "0.11.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560" dependencies = [ + "aws-lc-rs", "bytes", "getrandom 0.4.3", "lru-slab", @@ -2090,12 +2198,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - [[package]] name = "r-efi" version = "6.0.0" @@ -2109,20 +2211,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" dependencies = [ "libc", - "rand_chacha 0.3.1", + "rand_chacha", "rand_core 0.6.4", ] -[[package]] -name = "rand" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.5", -] - [[package]] name = "rand" version = "0.10.2" @@ -2144,16 +2236,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.5", -] - [[package]] name = "rand_core" version = "0.6.4" @@ -2163,15 +2245,6 @@ dependencies = [ "getrandom 0.2.17", ] -[[package]] -name = "rand_core" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" -dependencies = [ - "getrandom 0.3.4", -] - [[package]] name = "rand_core" version = "0.10.1" @@ -2241,7 +2314,6 @@ dependencies = [ "bytes", "encoding_rs", "futures-core", - "futures-util", "h2", "http 1.5.0", "http-body", @@ -2266,6 +2338,46 @@ dependencies = [ "tokio", "tokio-native-tls", "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + +[[package]] +name = "reqwest" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "futures-util", + "http 1.5.0", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", "tokio-util", "tower", "tower-http", @@ -2275,7 +2387,6 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", ] [[package]] @@ -2371,6 +2482,7 @@ version = "0.23.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" dependencies = [ + "aws-lc-rs", "once_cell", "ring", "rustls-pki-types", @@ -2379,6 +2491,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pki-types" version = "1.15.1" @@ -2389,12 +2513,40 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" -version = "0.103.13" +version = "0.103.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +checksum = "0527518605e68109d875e248ea259b6758801cf165e4b2c2733ae3b51f12535a" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted 0.9.0", @@ -2662,6 +2814,22 @@ version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" +[[package]] +name = "simd_cesu8" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "slab" version = "0.4.12" @@ -3286,15 +3454,6 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" -[[package]] -name = "wasip2" -version = "1.0.4+wasi-0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" -dependencies = [ - "wit-bindgen", -] - [[package]] name = "wasm-bindgen" version = "0.2.127" @@ -3352,9 +3511,9 @@ dependencies = [ [[package]] name = "wasm-streams" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" dependencies = [ "futures-util", "js-sys", @@ -3383,6 +3542,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "1.0.9" @@ -3585,12 +3753,6 @@ dependencies = [ "url", ] -[[package]] -name = "wit-bindgen" -version = "0.57.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" - [[package]] name = "writeable" version = "0.6.3" diff --git a/Cargo.toml b/Cargo.toml index 7b1b4ae..840bada 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,9 @@ repository = "https://github.com/Interchouette-ITC/ceps-rust-api" license-file = "LICENSE" [workspace.dependencies] -actix-web = { version = "4.9", default-features = false, features = ["macros"] } +actix-web = { version = "4.14", default-features = false, features = [ + "macros", +] } actix-cors = { version = "0.7", default-features = false } serde = { version = "1", features = ["derive"] } serde_json = "1" @@ -25,9 +27,10 @@ utoipa = { version = "5", features = ["actix_extras"] } utoipa-swagger-ui = { version = "9", features = ["actix-web"] } thiserror = "2" dotenvy = "0.15" -reqwest = { version = "0.12", default-features = false, features = [ +reqwest = { version = "0.13", default-features = false, features = [ "json", - "rustls-tls", + "query", + "rustls", ] } parking_lot = "0.12" ceps-client = { git = "https://github.com/Interchouette-ITC/ceps-rust-ts-client", branch = "dev" } diff --git a/docs/mcp.md b/docs/mcp.md index 3dfc144..14f2a4b 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -1,6 +1,6 @@ # MCP for agents -Rust binary `ceps-rust-api-mcp` **v1.0.0** (mcpkit), dual transport (stdio / Streamable HTTP). +Rust binary `ceps-rust-api-mcp` **v1.0.0** (rmcp), dual transport (stdio / Streamable HTTP). **Separate package:** lives in [`mcp/`](../mcp/) - **no dependency** on the `ceps-rust-api` library crate. Lifecycle uses Make/Docker; product tools call the HTTP API on `:8080`. @@ -28,11 +28,11 @@ docker run --rm -d --name ceps-rust-api-mcp \ From a clone, `make mcp-http` pulls the Hub image (builds locally only if pull fails) and passes `CEPS_HOST_ROOT=$(CURDIR)`. -| Mode | How | Endpoint | -| --- | --- | --- | -| **HTTP** (Docker / Hub) | `make mcp-http` | `http://127.0.0.1:4790/mcp` | -| **HTTP** (host) | `make run-mcp-http` | same URL | -| **stdio** (host) | `make run-mcp` | process on stdin/stdout | +| Mode | How | Endpoint | +| ----------------------- | ------------------- | --------------------------- | +| **HTTP** (Docker / Hub) | `make mcp-http` | `http://127.0.0.1:4790/mcp` | +| **HTTP** (host) | `make run-mcp-http` | same URL | +| **stdio** (host) | `make run-mcp` | process on stdin/stdout | ```bash ceps-rust-api-mcp # stdio @@ -44,36 +44,36 @@ Example Cursor config: [`mcp/mcp.json.example`](../mcp/mcp.json.example). Produc ## Make matrix (MCP itself) -| Command | Effect | -| --- | --- | -| `make mcp-build` | Host release-build MCP binary | -| `make mcp-docker-build` | Build `ceps-rust-api-mcp:1.0.0` (+ `:latest`) | -| `make mcp-docker-build-dev` | Build `:dev` (Hub + GHCR tags) | -| `make mcp-http` | Pull Hub image (or build) + start sidecar on **4790** | -| `make mcp-http-stop` | Stop MCP sidecar | -| `make mcp-docker-push-dev` / `mcp-docker-push-release` | Push Hub + GHCR | -| `make run-mcp` | Host **stdio** MCP | -| `make run-mcp-http` | Host HTTP on `127.0.0.1:4790` | +| Command | Effect | +| ------------------------------------------------------ | ----------------------------------------------------- | +| `make mcp-build` | Host release-build MCP binary | +| `make mcp-docker-build` | Build `ceps-rust-api-mcp:1.0.0` (+ `:latest`) | +| `make mcp-docker-build-dev` | Build `:dev` (Hub + GHCR tags) | +| `make mcp-http` | Pull Hub image (or build) + start sidecar on **4790** | +| `make mcp-http-stop` | Stop MCP sidecar | +| `make mcp-docker-push-dev` / `mcp-docker-push-release` | Push Hub + GHCR | +| `make run-mcp` | Host **stdio** MCP | +| `make run-mcp-http` | Host HTTP on `127.0.0.1:4790` | Compose: [`docker/docker-compose.mcp.yml`](../docker/docker-compose.mcp.yml). Image Dockerfile: [`mcp/Dockerfile`](../mcp/Dockerfile) (includes `docker`/`make`/`curl` so lifecycle tools work via the mounted repo + docker.sock). ### Host binds / docker.sock -| Claim | Verdict | -| --- | --- | -| MCP uses sock + in-container `/workspace` | **True** - setup only | +| Claim | Verdict | +| ------------------------------------------------ | ---------------------------------------------------------------------------------------- | +| MCP uses sock + in-container `/workspace` | **True** - setup only | | Lifecycle start tools need a safe host bind root | **True** - refuse when `CEPS_API_ROOT=/workspace` and `CEPS_HOST_ROOT` is missing/unsafe | Always pass `-e CEPS_HOST_ROOT=`. Mounting `docker.sock` is still host-root equivalent for anything Docker can do; the refuse guard only blocks the known `/workspace` bind-root class. ### Published MCP images -| Registry | Image | -| --- | --- | -| Docker Hub | `interchouette/ceps-rust-api-mcp` | -| Personal GHCR | `ghcr.io/groussac/ceps-rust-api-mcp` (Make/CI only) | -| Worker GHCR | `ghcr.io/interchouette/ceps-rust-api-mcp` (Make/CI only) | -| Org GHCR | `ghcr.io/interchouette-itc/ceps-rust-api-mcp` | +| Registry | Image | +| ------------- | -------------------------------------------------------- | +| Docker Hub | `interchouette/ceps-rust-api-mcp` | +| Personal GHCR | `ghcr.io/groussac/ceps-rust-api-mcp` (Make/CI only) | +| Worker GHCR | `ghcr.io/interchouette/ceps-rust-api-mcp` (Make/CI only) | +| Org GHCR | `ghcr.io/interchouette-itc/ceps-rust-api-mcp` | Tags: `:dev`, `:X.Y.Z`, `:latest`. @@ -91,32 +91,32 @@ cargo clippy --all-targets -- -D warnings MCP drives **Docker/Make** from `CEPS_API_ROOT`. Not exposed: `mcp-docker-push-*` / version-bump. -| Tool | Make / behavior | -| --- | --- | -| `ceps_api_help` | `make help` + tool map | -| `ceps_api_build` / `ceps_api_build_release` / `ceps_api_check` | matching targets; optional `features` | -| `ceps_api_lint` / `ceps_api_test` / `ceps_api_verify` | lint + test suite | -| `ceps_api_docker_build` | API image | -| `ceps_api_docker_run` | compose up `:8080` (refuses unsafe host bind root) | -| `ceps_api_docker_run_kms` | compose with `kms` profile | -| `ceps_api_docker_stop` | compose down | -| `ceps_api_version_show` | `make version-show` | -| `ceps_api_start` / `ceps_api_stop` | host `cargo run` API (pid under `mcp/.run/`) | -| `ceps_api_status` | containers + `GET /health` | +| Tool | Make / behavior | +| -------------------------------------------------------------- | -------------------------------------------------- | +| `ceps_api_help` | `make help` + tool map | +| `ceps_api_build` / `ceps_api_build_release` / `ceps_api_check` | matching targets; optional `features` | +| `ceps_api_lint` / `ceps_api_test` / `ceps_api_verify` | lint + test suite | +| `ceps_api_docker_build` | API image | +| `ceps_api_docker_run` | compose up `:8080` (refuses unsafe host bind root) | +| `ceps_api_docker_run_kms` | compose with `kms` profile | +| `ceps_api_docker_stop` | compose down | +| `ceps_api_version_show` | `make version-show` | +| `ceps_api_start` / `ceps_api_stop` | host `cargo run` API (pid under `mcp/.run/`) | +| `ceps_api_status` | containers + `GET /health` | ### HTTP API Base URL: `CEPS_API_URL` (default `http://127.0.0.1:8080`). POST tools take a JSON `body` string. -| Group | Tools (prefix `ceps_api_`) | -| --- | --- | -| Platform | `hello`, `health`, `openapi` | -| Chain | `put_transaction` → `POST /v1/chain/put-transaction` | -| CEP-18 mutate | `cep18_install`, `upgrade`, `transfer`, `transfer_from`, `approve`, `increase_allowance`, `decrease_allowance`, `mint`, `burn`, `change_events_mode`, `change_security` | -| CEP-18 query | `cep18_name`, `symbol`, `decimals`, `total_supply`, `events_mode`, `is_mint_and_burn_enabled`, `balance_of`, `allowances` | -| CEP-78 mutate | `cep78_install`, `upgrade`, `mint`, `transfer`, `burn`, `register_owner`, `approve`, `revoke`, `set_approval_for_all`, `set_token_metadata`, `set_variables`, `mint_session`, `transfer_session`, `updated_receipts` | -| CEP-78 query | `cep78_collection_name`, `collection_symbol`, `total_token_supply`, `number_of_minted_tokens`, `events_mode`, `owner_of`, `balance_of`, `is_approved_for_all`, `get_approved`, `metadata` | +| Group | Tools (prefix `ceps_api_`) | +| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Platform | `hello`, `health`, `openapi` | +| Chain | `put_transaction` → `POST /v1/chain/put-transaction` | +| CEP-18 mutate | `cep18_install`, `upgrade`, `transfer`, `transfer_from`, `approve`, `increase_allowance`, `decrease_allowance`, `mint`, `burn`, `change_events_mode`, `change_security` | +| CEP-18 query | `cep18_name`, `symbol`, `decimals`, `total_supply`, `events_mode`, `is_mint_and_burn_enabled`, `balance_of`, `allowances` | +| CEP-78 mutate | `cep78_install`, `upgrade`, `mint`, `transfer`, `burn`, `register_owner`, `approve`, `revoke`, `set_approval_for_all`, `set_token_metadata`, `set_variables`, `mint_session`, `transfer_session`, `updated_receipts` | +| CEP-78 query | `cep78_collection_name`, `collection_symbol`, `total_token_supply`, `number_of_minted_tokens`, `events_mode`, `owner_of`, `balance_of`, `is_approved_for_all`, `get_approved`, `metadata` | | CEP-85 mutate | `cep85_install`, `upgrade`, `mint`, `batch_mint`, `transfer`, `batch_transfer`, `burn`, `batch_burn`, `set_approval_for_all`, `set_uri`, `set_total_supply_of`, `set_total_supply_of_batch`, `change_security`, `set_modalities` | -| CEP-85 query | `cep85_collection_name`, `collection_uri`, `balance_of`, `supply_of`, `total_supply_of`, `uri`, `is_non_fungible`, `is_approved_for_all` | -| CEP-95 mutate | `cep95_install`, `transfer_from`, `safe_transfer_from`, `approve`, `revoke_approval`, `approve_for_all`, `revoke_approval_for_all`, `mint`, `burn`, `bind_odra_install` | -| CEP-95 query | `cep95_name`, `symbol`, `total_supply`, `owner_of`, `balance_of`, `get_approved`, `is_approved_for_all`, `token_metadata` | +| CEP-85 query | `cep85_collection_name`, `collection_uri`, `balance_of`, `supply_of`, `total_supply_of`, `uri`, `is_non_fungible`, `is_approved_for_all` | +| CEP-95 mutate | `cep95_install`, `transfer_from`, `safe_transfer_from`, `approve`, `revoke_approval`, `approve_for_all`, `revoke_approval_for_all`, `mint`, `burn`, `bind_odra_install` | +| CEP-95 query | `cep95_name`, `symbol`, `total_supply`, `owner_of`, `balance_of`, `get_approved`, `is_approved_for_all`, `token_metadata` | diff --git a/mcp/Cargo.lock b/mcp/Cargo.lock index c344539..7563f8b 100644 --- a/mcp/Cargo.lock +++ b/mcp/Cargo.lock @@ -2,21 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "addr2line" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - [[package]] name = "aho-corasick" version = "1.1.5" @@ -91,39 +76,6 @@ version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" -[[package]] -name = "async-lock" -version = "3.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" -dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-stream" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] - [[package]] name = "async-trait" version = "0.1.92" @@ -147,6 +99,29 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" +[[package]] +name = "aws-lc-rs" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce2b2dcc879c3bae0d371e77c99f2238400ef24ec001394befa67b6e543add9e" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f09fae7be8bb3174e05c6afdb34199e6dc0c7c04ba9fa237b1967adfbde27483" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", + "pkg-config", +] + [[package]] name = "axum" version = "0.8.9" @@ -155,7 +130,6 @@ checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ "axum-core", "bytes", - "form_urlencoded", "futures-util", "http", "http-body", @@ -171,13 +145,11 @@ dependencies = [ "serde_core", "serde_json", "serde_path_to_error", - "serde_urlencoded", "sync_wrapper", "tokio", - "tower 0.5.3", + "tower", "tower-layer", "tower-service", - "tracing", ] [[package]] @@ -196,38 +168,19 @@ dependencies = [ "sync_wrapper", "tower-layer", "tower-service", - "tracing", ] [[package]] -name = "backtrace" -version = "0.3.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-link", -] - -[[package]] -name = "backtrace-ext" -version = "0.2.1" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" -dependencies = [ - "backtrace", -] +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64" -version = "0.22.1" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" [[package]] name = "bitflags" @@ -235,15 +188,6 @@ 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" @@ -263,6 +207,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d262e149917187838d5b42777c8253bcb64500067342904e7d429499a6f277e" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -271,10 +217,12 @@ name = "ceps-rust-api-mcp" version = "1.0.0" dependencies = [ "anyhow", + "axum", "clap", - "mcpkit", - "mcpkit-axum", "reqwest", + "rmcp", + "schemars", + "serde", "serde_json", "tokio", "tracing", @@ -300,8 +248,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" dependencies = [ "cfg-if", - "cpufeatures 0.3.0", - "rand_core 0.10.1", + "cpufeatures", + "rand_core", ] [[package]] @@ -311,10 +259,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", - "js-sys", "num-traits", "serde", - "wasm-bindgen", "windows-link", ] @@ -359,56 +305,60 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] -name = "colorchoice" -version = "1.0.5" +name = "cmake" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] [[package]] -name = "core-foundation-sys" -version = "0.8.7" +name = "colorchoice" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] -name = "cpufeatures" -version = "0.2.17" +name = "combine" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ - "libc", + "bytes", + "memchr", ] [[package]] -name = "cpufeatures" -version = "0.3.0" +name = "core-foundation" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ + "core-foundation-sys", "libc", ] [[package]] -name = "crossbeam-utils" -version = "0.8.22" +name = "core-foundation-sys" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] -name = "crypto-common" -version = "0.1.7" +name = "cpufeatures" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" dependencies = [ - "generic-array", - "typenum", + "libc", ] [[package]] name = "darling" -version = "0.20.11" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +checksum = "88490bf1b990d87eaaa7ac8aa887f629a08e7359765b4911faf63c3763347d23" dependencies = [ "darling_core", "darling_macro", @@ -416,51 +366,26 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.11" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +checksum = "084e274f91c482280130e1e34e0b8d6e66776a060d7b6de7b84289ca778868c4" dependencies = [ - "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.119", + "syn 3.0.3", ] [[package]] name = "darling_macro" -version = "0.20.11" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +checksum = "68f5792fa0d41cd2325ce0ffa64f0a340eaebd4971a3a0c5e1ffd2cc488a355e" dependencies = [ "darling_core", "quote", - "syn 2.0.119", -] - -[[package]] -name = "dashmap" -version = "6.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c" -dependencies = [ - "cfg-if", - "crossbeam-utils", - "hashbrown", - "lock_api", - "once_cell", - "parking_lot_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", + "syn 3.0.3", ] [[package]] @@ -475,33 +400,25 @@ dependencies = [ ] [[package]] -name = "errno" -version = "0.3.14" +name = "dunce" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] -name = "event-listener" -version = "5.4.2" +name = "dyn-clone" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" -dependencies = [ - "parking", - "pin-project-lite", -] +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] -name = "event-listener-strategy" -version = "0.5.4" +name = "errno" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ - "event-listener", - "pin-project-lite", + "libc", + "windows-sys 0.61.2", ] [[package]] @@ -510,12 +427,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b73573e6edcd2af0cdf47bd6cb58f0b3839491263c314eaad1ccf24430e1de" -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - [[package]] name = "form_urlencoded" version = "1.2.2" @@ -525,11 +436,17 @@ dependencies = [ "percent-encoding", ] +[[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.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a88cf1f829d945f548cf8fec32c61b1f202b6d93b45848602fc02af4b12ad218" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" dependencies = [ "futures-channel", "futures-core", @@ -542,9 +459,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -552,15 +469,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-executor" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6754879cc9f2c66f88c6e5c35344bb0bdb0708b0352b1201815667c7eabc7458" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" dependencies = [ "futures-core", "futures-task", @@ -569,38 +486,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-macro" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.3", ] [[package]] name = "futures-sink" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-channel", "futures-core", @@ -613,16 +530,6 @@ dependencies = [ "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" @@ -646,22 +553,10 @@ dependencies = [ "js-sys", "libc", "r-efi", - "rand_core 0.10.1", + "rand_core", "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - [[package]] name = "heck" version = "0.5.0" @@ -690,9 +585,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" dependencies = [ "bytes", "futures-core", @@ -747,7 +642,6 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots", ] [[package]] @@ -756,7 +650,7 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-util", @@ -912,12 +806,6 @@ version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a756c3fac73139e83f14c2d742155dd2b78d3ee56597b419a0579b7bdd6dd78" -[[package]] -name = "is_ci" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" - [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -930,6 +818,65 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys", + "log", + "simd_cesu8", + "thiserror", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.119", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + [[package]] name = "js-sys" version = "0.3.104" @@ -953,27 +900,12 @@ version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" -[[package]] -name = "linux-raw-sys" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" - [[package]] name = "litemap" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - [[package]] name = "log" version = "0.4.33" @@ -1001,180 +933,18 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" -[[package]] -name = "mcpkit" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611987760f629f10e9ed341e17257f06d9d84a2d4a1fb5f51ad5494ee949a64f" -dependencies = [ - "mcpkit-client", - "mcpkit-core", - "mcpkit-macros", - "mcpkit-server", - "mcpkit-transport", -] - -[[package]] -name = "mcpkit-axum" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "857b0619fafbd36edbfb38eae4e0ce7b5b0d72fa6ed732a6cba50225878a09c1" -dependencies = [ - "async-stream", - "axum", - "dashmap", - "futures", - "mcpkit-core", - "mcpkit-server", - "mcpkit-transport", - "serde", - "serde_json", - "thiserror", - "tokio", - "tower 0.4.13", - "tower-http 0.5.2", - "tracing", - "uuid", -] - -[[package]] -name = "mcpkit-client" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01f0933987f0e47cf3ed8ed5f66e668709fda49fb1b53d52a2896acbbf3c1fae" -dependencies = [ - "async-lock", - "futures", - "mcpkit-core", - "mcpkit-transport", - "serde", - "serde_json", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "mcpkit-core" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56b6092b7d3accd451fd3b985915c8bab18825d8509e2086316fdc596fd81090" -dependencies = [ - "base64", - "chrono", - "event-listener", - "getrandom 0.2.17", - "miette", - "rand 0.8.7", - "serde", - "serde_json", - "sha2", - "thiserror", - "url", - "uuid", -] - -[[package]] -name = "mcpkit-macros" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17d18e85040a2e5ba06bf506fa8ce3575ec2e2a8c0d6fa5669b538f5a7615aba" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.119", -] - -[[package]] -name = "mcpkit-server" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864e40f35b80805cc99e2a311d839f02fa3f24c9c980e6bcebb66a76e864d08d" -dependencies = [ - "futures", - "mcpkit-core", - "mcpkit-transport", - "serde", - "serde_json", - "tokio", - "tracing", -] - -[[package]] -name = "mcpkit-transport" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ca03ba82a2a6c3cf4d5723609467ac41d4bf885a795513b8a62feeae2a5a43" -dependencies = [ - "async-lock", - "async-trait", - "bytes", - "event-listener", - "futures", - "mcpkit-core", - "pin-project-lite", - "rand 0.8.7", - "reqwest", - "serde", - "serde_json", - "thiserror", - "tokio", - "tracing", - "url", -] - [[package]] name = "memchr" version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" -[[package]] -name = "miette" -version = "7.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f98efec8807c63c752b5bd61f862c165c115b0a35685bdcfd9238c7aeb592b7" -dependencies = [ - "backtrace", - "backtrace-ext", - "cfg-if", - "miette-derive", - "owo-colors", - "supports-color", - "supports-hyperlinks", - "supports-unicode", - "terminal_size", - "textwrap", - "unicode-width 0.1.14", -] - -[[package]] -name = "miette-derive" -version = "7.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] - [[package]] name = "mime" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", -] - [[package]] name = "mio" version = "1.2.2" @@ -1204,15 +974,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "object" -version = "0.37.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.21.4" @@ -1226,39 +987,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] -name = "owo-colors" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" - -[[package]] -name = "parking" -version = "2.2.1" +name = "openssl-probe" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] -name = "parking_lot" -version = "0.12.5" +name = "pastey" +version = "0.2.3" 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", -] +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" [[package]] name = "percent-encoding" @@ -1272,6 +1010,12 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + [[package]] name = "potential_utf" version = "0.1.5" @@ -1281,15 +1025,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - [[package]] name = "proc-macro2" version = "1.0.107" @@ -1325,10 +1060,11 @@ version = "0.11.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560" dependencies = [ + "aws-lc-rs", "bytes", "getrandom 0.4.3", "lru-slab", - "rand 0.10.2", + "rand", "rand_pcg", "ring", "rustc-hash", @@ -1370,45 +1106,15 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" -[[package]] -name = "rand" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.4", -] - [[package]] name = "rand" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" -dependencies = [ - "chacha20", - "getrandom 0.4.3", - "rand_core 0.10.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ - "getrandom 0.2.17", + "chacha20", + "getrandom 0.4.3", + "rand_core", ] [[package]] @@ -1423,16 +1129,27 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" dependencies = [ - "rand_core 0.10.1", + "rand_core", ] [[package]] -name = "redox_syscall" -version = "0.5.18" +name = "ref-cast" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "216e8f773d7923bcba9ceb86a86c93cabb3903a11872fc3f138c49630e50b96d" dependencies = [ - "bitflags", + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9283685feec7d69af75fb0e858d5e7378f33fe4fc699383b2916ab9273e03c" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", ] [[package]] @@ -1454,14 +1171,13 @@ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "reqwest" -version = "0.12.28" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-core", - "futures-util", "http", "http-body", "http-body-util", @@ -1475,22 +1191,20 @@ dependencies = [ "quinn", "rustls", "rustls-pki-types", + "rustls-platform-verifier", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", "tokio", "tokio-rustls", - "tokio-util", - "tower 0.5.3", - "tower-http 0.6.11", + "tower", + "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-streams", "web-sys", - "webpki-roots", ] [[package]] @@ -1508,10 +1222,48 @@ dependencies = [ ] [[package]] -name = "rustc-demangle" -version = "0.1.28" +name = "rmcp" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8dddc5b1924b9a59fba420166160ca2c4663a4e01803e52eda33070f56d63c8" +dependencies = [ + "async-trait", + "base64 0.23.1", + "bytes", + "chrono", + "futures", + "http", + "http-body", + "http-body-util", + "pastey", + "pin-project-lite", + "rand", + "rmcp-macros", + "schemars", + "serde", + "serde_json", + "sse-stream", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tower-service", + "tracing", + "uuid", +] + +[[package]] +name = "rmcp-macros" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" +checksum = "6898e24cd16342b59bfa8a53c2c04b9cf62fc8a2cfea57b9c038b09984bfc521" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "serde_json", + "syn 3.0.3", +] [[package]] name = "rustc-hash" @@ -1520,16 +1272,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] -name = "rustix" -version = "1.1.4" +name = "rustc_version" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.61.2", + "semver", ] [[package]] @@ -1538,14 +1286,26 @@ version = "0.23.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" dependencies = [ + "aws-lc-rs", "once_cell", - "ring", "rustls-pki-types", "rustls-webpki", "subtle", "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pki-types" version = "1.15.1" @@ -1556,12 +1316,40 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" -version = "0.103.13" +version = "0.103.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +checksum = "0527518605e68109d875e248ea259b6758801cf165e4b2c2733ae3b51f12535a" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -1580,10 +1368,77 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] -name = "scopeguard" -version = "1.2.0" +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "schemars" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" +dependencies = [ + "chrono", + "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.3", +] + +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" @@ -1615,6 +1470,17 @@ dependencies = [ "syn 3.0.3", ] +[[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.3", +] + [[package]] name = "serde_json" version = "1.0.151" @@ -1651,17 +1517,6 @@ dependencies = [ "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]] name = "sharded-slab" version = "0.1.7" @@ -1687,6 +1542,22 @@ dependencies = [ "libc", ] +[[package]] +name = "simd_cesu8" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "slab" version = "0.4.12" @@ -1709,6 +1580,19 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "sse-stream" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c123f296ade4ec4b8b0f6162116e6629f5146922ca5ab40ca9d3c2e73ab4761e" +dependencies = [ + "bytes", + "futures-util", + "http-body", + "http-body-util", + "pin-project-lite", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -1727,27 +1611,6 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "supports-color" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6" -dependencies = [ - "is_ci", -] - -[[package]] -name = "supports-hyperlinks" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e396b6523b11ccb83120b115a0b7366de372751aa6edf19844dfb13a6af97e91" - -[[package]] -name = "supports-unicode" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" - [[package]] name = "syn" version = "2.0.119" @@ -1790,26 +1653,6 @@ dependencies = [ "syn 2.0.119", ] -[[package]] -name = "terminal_size" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" -dependencies = [ - "rustix", - "windows-sys 0.61.2", -] - -[[package]] -name = "textwrap" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" -dependencies = [ - "unicode-linebreak", - "unicode-width 0.2.2", -] - [[package]] name = "thiserror" version = "2.0.20" @@ -1873,7 +1716,6 @@ dependencies = [ "bytes", "libc", "mio", - "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", @@ -1903,27 +1745,28 @@ dependencies = [ ] [[package]] -name = "tokio-util" -version = "0.7.19" +name = "tokio-stream" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" +checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b" dependencies = [ - "bytes", "futures-core", - "futures-sink", "pin-project-lite", "tokio", ] [[package]] -name = "tower" -version = "0.4.13" +name = "tokio-util" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" dependencies = [ - "tower-layer", - "tower-service", - "tracing", + "bytes", + "futures-core", + "futures-sink", + "libc", + "pin-project-lite", + "tokio", ] [[package]] @@ -1939,24 +1782,6 @@ dependencies = [ "tokio", "tower-layer", "tower-service", - "tracing", -] - -[[package]] -name = "tower-http" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" -dependencies = [ - "bitflags", - "bytes", - "http", - "http-body", - "http-body-util", - "pin-project-lite", - "tower-layer", - "tower-service", - "tracing", ] [[package]] @@ -1971,7 +1796,7 @@ dependencies = [ "http", "http-body", "pin-project-lite", - "tower 0.5.3", + "tower", "tower-layer", "tower-service", "url", @@ -1995,7 +1820,6 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -2057,36 +1881,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[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 = "unicode-linebreak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" - -[[package]] -name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unicode-width" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" - [[package]] name = "untrusted" version = "0.9.0" @@ -2103,7 +1903,6 @@ dependencies = [ "idna", "percent-encoding", "serde", - "serde_derive", ] [[package]] @@ -2126,7 +1925,6 @@ checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239" dependencies = [ "getrandom 0.4.3", "js-sys", - "serde_core", "wasm-bindgen", ] @@ -2137,10 +1935,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] -name = "version_check" -version = "0.9.5" +name = "walkdir" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] [[package]] name = "want" @@ -2212,19 +2014,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-streams" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" -dependencies = [ - "futures-util", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "web-sys" version = "0.3.104" @@ -2246,14 +2035,23 @@ dependencies = [ ] [[package]] -name = "webpki-roots" +name = "webpki-root-certs" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" +checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" dependencies = [ "rustls-pki-types", ] +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "windows-core" version = "0.62.2" @@ -2424,26 +2222,6 @@ dependencies = [ "synstructure", ] -[[package]] -name = "zerocopy" -version = "0.8.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] - [[package]] name = "zerofrom" version = "0.1.8" diff --git a/mcp/Cargo.toml b/mcp/Cargo.toml index 394f376..0e28ce4 100644 --- a/mcp/Cargo.toml +++ b/mcp/Cargo.toml @@ -21,13 +21,25 @@ path = "src/lib.rs" [dependencies] anyhow = "1" +axum = { version = "0.8", default-features = false, features = [ + "http1", + "tokio", + "json", +] } clap = { version = "4", features = ["derive", "env"] } -mcpkit = "0.7" -mcpkit-axum = "0.7" -reqwest = { version = "0.12", default-features = false, features = [ +reqwest = { version = "0.13", default-features = false, features = [ "json", - "rustls-tls", + "query", + "rustls", +] } +rmcp = { version = "3.1.2", default-features = false, features = [ + "server", + "macros", + "transport-io", + "transport-streamable-http-server", ] } +schemars = "1" +serde = { version = "1", features = ["derive"] } serde_json = "1" tokio = { version = "1", features = [ "macros", @@ -41,9 +53,10 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } [dev-dependencies] -reqwest = { version = "0.12", default-features = false, features = [ +reqwest = { version = "0.13", default-features = false, features = [ "json", - "rustls-tls", + "query", + "rustls", ] } serde_json = "1" tokio = { version = "1", features = ["macros", "rt-multi-thread"] } diff --git a/mcp/Dockerfile b/mcp/Dockerfile index 10f507e..d185b95 100644 --- a/mcp/Dockerfile +++ b/mcp/Dockerfile @@ -1,4 +1,4 @@ -# ceps-rust-api-mcp — Streamable HTTP on :4790 +# ceps-rust-api-mcp - Streamable HTTP on :4790 # Build context: mcp/ ARG RUST_IMAGE=rust:slim-bookworm diff --git a/mcp/README.md b/mcp/README.md index 800460e..d8ccd4a 100644 --- a/mcp/README.md +++ b/mcp/README.md @@ -1,6 +1,6 @@ # ceps-rust-api-mcp -Rust **mcpkit** server (`ceps-rust-api-mcp` **v1.0.0**) to drive Make/Docker lifecycle and call the HTTP API from Cursor. +Rust **rmcp** server (`ceps-rust-api-mcp` **v1.0.0**) to drive Make/Docker lifecycle and call the HTTP API from Cursor. This is a **separate Cargo package** under `mcp/` - it does **not** link the API library. Lifecycle shells out to `make`/`docker`; API tools use `reqwest`. @@ -8,11 +8,11 @@ Tool names use the `ceps_api_*` prefix (distinct from `ceps-client-mcp` `ceps18_ ## Transports -| Mode | How | Use | -| --- | --- | --- | -| **stdio (host)** | `make run-mcp` | MCP over stdin/stdout | -| **HTTP (host)** | `make run-mcp-http` | Streamable HTTP on **4790** | -| **HTTP (Docker)** | `make mcp-http` | Hub/local image on **4790** → `http://127.0.0.1:4790/mcp` | +| Mode | How | Use | +| ----------------- | ------------------- | --------------------------------------------------------- | +| **stdio (host)** | `make run-mcp` | MCP over stdin/stdout | +| **HTTP (host)** | `make run-mcp-http` | Streamable HTTP on **4790** | +| **HTTP (Docker)** | `make mcp-http` | Hub/local image on **4790** → `http://127.0.0.1:4790/mcp` | ```bash docker pull interchouette/ceps-rust-api-mcp:1.0.0 @@ -25,13 +25,13 @@ See [docs/mcp.md](../docs/mcp.md) for the host-bind / docker.sock notes and full ## Env -| Var | Default | Role | -| --- | --- | --- | -| `CEPS_API_ROOT` | parent of `mcp/` / cwd with Makefile | In-container or host repo root for Make/Docker | -| `CEPS_HOST_ROOT` | falls back to `CEPS_API_ROOT` | **Host** clone path for any Docker `-v` sources; **required** when `CEPS_API_ROOT=/workspace` | -| `CEPS_API_URL` | `http://127.0.0.1:8080` | HTTP tools base URL | -| `MCP_HTTP` | unset | Force HTTP transport | -| `CEPS_API_MCP_ADDR` | `127.0.0.1:4790` | HTTP listen address | +| Var | Default | Role | +| ------------------- | ------------------------------------ | --------------------------------------------------------------------------------------------- | +| `CEPS_API_ROOT` | parent of `mcp/` / cwd with Makefile | In-container or host repo root for Make/Docker | +| `CEPS_HOST_ROOT` | falls back to `CEPS_API_ROOT` | **Host** clone path for any Docker `-v` sources; **required** when `CEPS_API_ROOT=/workspace` | +| `CEPS_API_URL` | `http://127.0.0.1:8080` | HTTP tools base URL | +| `MCP_HTTP` | unset | Force HTTP transport | +| `CEPS_API_MCP_ADDR` | `127.0.0.1:4790` | HTTP listen address | Cursor example: [`mcp.json.example`](mcp.json.example). diff --git a/mcp/src/lib.rs b/mcp/src/lib.rs index dfcdef5..3030058 100644 --- a/mcp/src/lib.rs +++ b/mcp/src/lib.rs @@ -1,8 +1,9 @@ -//! ceps-rust-api MCP library (mcpkit tools + Make/Docker helpers + HTTP client). +//! ceps-rust-api MCP library (rmcp tools + Make/Docker helpers + HTTP client). pub mod client; pub mod ops; pub mod paths; pub mod server; +pub mod tool_args; pub use server::{run, run_http, DEFAULT_HTTP_LISTEN}; diff --git a/mcp/src/main.rs b/mcp/src/main.rs index f2f5927..d8ef340 100644 --- a/mcp/src/main.rs +++ b/mcp/src/main.rs @@ -1,4 +1,4 @@ -//! `ceps-rust-api-mcp` — MCP server (stdio by default, optional Streamable HTTP). +//! `ceps-rust-api-mcp` - MCP server (stdio by default, optional Streamable HTTP). use anyhow::Result; use ceps_rust_api_mcp::server::{run, run_http, DEFAULT_HTTP_LISTEN}; diff --git a/mcp/src/ops.rs b/mcp/src/ops.rs index f4c6034..9627bb0 100644 --- a/mcp/src/ops.rs +++ b/mcp/src/ops.rs @@ -228,7 +228,7 @@ pub fn api_start() -> String { pub fn api_stop() -> String { if !api_pid_path().is_file() { - return "no api.pid — nothing to stop".into(); + return "no api.pid - nothing to stop".into(); } let pid = fs::read_to_string(api_pid_path()) .unwrap_or_default() diff --git a/mcp/src/server.rs b/mcp/src/server.rs index 095cf75..5233af1 100644 --- a/mcp/src/server.rs +++ b/mcp/src/server.rs @@ -1,826 +1,1263 @@ -//! MCP server (`mcpkit`) for `ceps-rust-api-mcp` (stdio or Streamable HTTP). +//! MCP server (`rmcp`) for `ceps-rust-api-mcp` (stdio or Streamable HTTP). #![allow(clippy::unused_async)] -use mcpkit::prelude::*; -use mcpkit::transport::stdio::StdioTransport; -use mcpkit_axum::McpRouter; +use std::sync::Arc; +use rmcp::{ + handler::server::wrapper::Parameters, + model::{CallToolResult, ContentBlock, ServerCapabilities, ServerInfo}, + tool, tool_handler, tool_router, + transport::stdio, + ErrorData as McpError, ServerHandler, ServiceExt, +}; + +use crate::tool_args::*; use crate::{client, ops}; /// MCP server handle exposing ceps-rust-api Make/Docker + HTTP API tools. +#[derive(Clone, Default)] pub struct CepsApiMcp; -// Keep in sync with Cargo.toml `version`. -#[mcp_server(name = "ceps-rust-api", version = "1.0.0")] +/// Default HTTP bind address for Streamable MCP. +pub const DEFAULT_HTTP_LISTEN: &str = crate::paths::DEFAULT_HTTP_LISTEN; + +fn text_ok(text: impl Into) -> CallToolResult { + CallToolResult::success(vec![ContentBlock::text(text.into())]) +} + +#[tool_router] impl CepsApiMcp { #[tool(description = "make help + MCP Make↔tool parity map")] - async fn ceps_api_help(&self) -> ToolOutput { - ToolOutput::text(ops::help()) + async fn ceps_api_help(&self) -> Result { + Ok(text_ok(ops::help())) } #[tool(description = "make build [FEATURES=…]")] - async fn ceps_api_build(&self, features: Option) -> ToolOutput { - ToolOutput::text(ops::build(features.as_deref())) + async fn ceps_api_build( + &self, + Parameters(FeaturesArgs { features }): Parameters, + ) -> Result { + Ok(text_ok(ops::build(features.as_deref()))) } #[tool(description = "make build-release [FEATURES=…]")] - async fn ceps_api_build_release(&self, features: Option) -> ToolOutput { - ToolOutput::text(ops::build_release(features.as_deref())) + async fn ceps_api_build_release( + &self, + Parameters(FeaturesArgs { features }): Parameters, + ) -> Result { + Ok(text_ok(ops::build_release(features.as_deref()))) } #[tool(description = "make check [FEATURES=…]")] - async fn ceps_api_check(&self, features: Option) -> ToolOutput { - ToolOutput::text(ops::check(features.as_deref())) + async fn ceps_api_check( + &self, + Parameters(FeaturesArgs { features }): Parameters, + ) -> Result { + Ok(text_ok(ops::check(features.as_deref()))) } - #[tool(description = "make lint [FEATURES=…] — fmt check + clippy")] - async fn ceps_api_lint(&self, features: Option) -> ToolOutput { - ToolOutput::text(ops::lint(features.as_deref())) + #[tool(description = "make lint [FEATURES=…] - fmt check + clippy")] + async fn ceps_api_lint( + &self, + Parameters(FeaturesArgs { features }): Parameters, + ) -> Result { + Ok(text_ok(ops::lint(features.as_deref()))) } #[tool(description = "make test [FEATURES=…]")] - async fn ceps_api_test(&self, features: Option) -> ToolOutput { - ToolOutput::text(ops::test_suite(features.as_deref())) + async fn ceps_api_test( + &self, + Parameters(FeaturesArgs { features }): Parameters, + ) -> Result { + Ok(text_ok(ops::test_suite(features.as_deref()))) } - #[tool(description = "make verify [FEATURES=…] — lint + tests")] - async fn ceps_api_verify(&self, features: Option) -> ToolOutput { - ToolOutput::text(ops::verify(features.as_deref())) + #[tool(description = "make verify [FEATURES=…] - lint + tests")] + async fn ceps_api_verify( + &self, + Parameters(FeaturesArgs { features }): Parameters, + ) -> Result { + Ok(text_ok(ops::verify(features.as_deref()))) } - #[tool(description = "make docker-build — API image tags")] - async fn ceps_api_docker_build(&self) -> ToolOutput { - ToolOutput::text(ops::docker_build()) + #[tool(description = "make docker-build - API image tags")] + async fn ceps_api_docker_build(&self) -> Result { + Ok(text_ok(ops::docker_build())) } - #[tool(description = "make docker-run — compose up -d (port 8080)")] - async fn ceps_api_docker_run(&self) -> ToolOutput { - ToolOutput::text(ops::docker_run()) + #[tool(description = "make docker-run - compose up -d (port 8080)")] + async fn ceps_api_docker_run(&self) -> Result { + Ok(text_ok(ops::docker_run())) } - #[tool(description = "make docker-run-kms — compose with kms profile")] - async fn ceps_api_docker_run_kms(&self) -> ToolOutput { - ToolOutput::text(ops::docker_run_kms()) + #[tool(description = "make docker-run-kms - compose with kms profile")] + async fn ceps_api_docker_run_kms(&self) -> Result { + Ok(text_ok(ops::docker_run_kms())) } #[tool(description = "make docker-stop")] - async fn ceps_api_docker_stop(&self) -> ToolOutput { - ToolOutput::text(ops::docker_stop()) + async fn ceps_api_docker_stop(&self) -> Result { + Ok(text_ok(ops::docker_stop())) } #[tool(description = "make version-show")] - async fn ceps_api_version_show(&self) -> ToolOutput { - ToolOutput::text(ops::version_show()) + async fn ceps_api_version_show(&self) -> Result { + Ok(text_ok(ops::version_show())) } #[tool(description = "Host cargo API start (background)")] - async fn ceps_api_start(&self) -> ToolOutput { - ToolOutput::text(ops::api_start()) + async fn ceps_api_start(&self) -> Result { + Ok(text_ok(ops::api_start())) } #[tool(description = "Stop host cargo API")] - async fn ceps_api_stop(&self) -> ToolOutput { - ToolOutput::text(ops::api_stop()) + async fn ceps_api_stop(&self) -> Result { + Ok(text_ok(ops::api_stop())) } #[tool(description = "Status: containers + API /health probe")] - async fn ceps_api_status(&self) -> ToolOutput { - ToolOutput::text(ops::status()) + async fn ceps_api_status(&self) -> Result { + Ok(text_ok(ops::status())) } - #[tool(description = "GET / — hello")] - async fn ceps_api_hello(&self) -> ToolOutput { - ToolOutput::text(client::hello().await) + #[tool(description = "GET / - hello")] + async fn ceps_api_hello(&self) -> Result { + Ok(text_ok(client::hello().await)) } #[tool(description = "GET /health")] - async fn ceps_api_health(&self) -> ToolOutput { - ToolOutput::text(client::health().await) + async fn ceps_api_health(&self) -> Result { + Ok(text_ok(client::health().await)) } #[tool(description = "GET /docs/ceps-openapi.json")] - async fn ceps_api_openapi(&self) -> ToolOutput { - ToolOutput::text(client::openapi().await) + async fn ceps_api_openapi(&self) -> Result { + Ok(text_ok(client::openapi().await)) } #[tool(description = "POST CEP-18 install - query params as JSON object")] - async fn ceps_api_cep18_install(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep18_install(&body).await) + async fn ceps_api_cep18_install( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_install(&body).await)) } #[tool(description = "POST CEP-18 upgrade - query params as JSON object")] - async fn ceps_api_cep18_upgrade(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep18_upgrade(&body).await) + async fn ceps_api_cep18_upgrade( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_upgrade(&body).await)) } #[tool(description = "POST CEP-18 transfer - query params as JSON object")] - async fn ceps_api_cep18_transfer(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep18_transfer(&body).await) + async fn ceps_api_cep18_transfer( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_transfer(&body).await)) } #[tool(description = "POST CEP-18 transfer-from - query params as JSON object")] - async fn ceps_api_cep18_transfer_from(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep18_transfer_from(&body).await) + async fn ceps_api_cep18_transfer_from( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_transfer_from(&body).await)) } #[tool(description = "POST CEP-18 approve - query params as JSON object")] - async fn ceps_api_cep18_approve(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep18_approve(&body).await) + async fn ceps_api_cep18_approve( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_approve(&body).await)) } #[tool(description = "POST CEP-18 increase-allowance - query params as JSON object")] - async fn ceps_api_cep18_increase_allowance(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep18_increase_allowance(&body).await) + async fn ceps_api_cep18_increase_allowance( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_increase_allowance(&body).await)) } #[tool(description = "POST CEP-18 decrease-allowance - query params as JSON object")] - async fn ceps_api_cep18_decrease_allowance(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep18_decrease_allowance(&body).await) + async fn ceps_api_cep18_decrease_allowance( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_decrease_allowance(&body).await)) } #[tool(description = "POST CEP-18 mint - query params as JSON object")] - async fn ceps_api_cep18_mint(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep18_mint(&body).await) + async fn ceps_api_cep18_mint( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_mint(&body).await)) } #[tool(description = "POST CEP-18 burn - query params as JSON object")] - async fn ceps_api_cep18_burn(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep18_burn(&body).await) + async fn ceps_api_cep18_burn( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_burn(&body).await)) } #[tool(description = "POST CEP-18 change-events-mode - query params as JSON object")] - async fn ceps_api_cep18_change_events_mode(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep18_change_events_mode(&body).await) + async fn ceps_api_cep18_change_events_mode( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_change_events_mode(&body).await)) } #[tool(description = "POST CEP-18 change-security - query params as JSON object")] - async fn ceps_api_cep18_change_security(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep18_change_security(&body).await) + async fn ceps_api_cep18_change_security( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_change_security(&body).await)) } #[tool(description = "POST CEP-78 install - query params as JSON object")] - async fn ceps_api_cep78_install(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_install(&body).await) + async fn ceps_api_cep78_install( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_install(&body).await)) } #[tool(description = "POST CEP-78 upgrade - query params as JSON object")] - async fn ceps_api_cep78_upgrade(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_upgrade(&body).await) + async fn ceps_api_cep78_upgrade( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_upgrade(&body).await)) } #[tool(description = "POST CEP-78 mint - query params as JSON object")] - async fn ceps_api_cep78_mint(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_mint(&body).await) + async fn ceps_api_cep78_mint( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_mint(&body).await)) } #[tool(description = "POST CEP-78 transfer - query params as JSON object")] - async fn ceps_api_cep78_transfer(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_transfer(&body).await) + async fn ceps_api_cep78_transfer( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_transfer(&body).await)) } #[tool(description = "POST CEP-78 burn - query params as JSON object")] - async fn ceps_api_cep78_burn(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_burn(&body).await) + async fn ceps_api_cep78_burn( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_burn(&body).await)) } #[tool(description = "POST CEP-78 register-owner - query params as JSON object")] - async fn ceps_api_cep78_register_owner(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_register_owner(&body).await) + async fn ceps_api_cep78_register_owner( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_register_owner(&body).await)) } #[tool(description = "POST CEP-78 approve - query params as JSON object")] - async fn ceps_api_cep78_approve(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_approve(&body).await) + async fn ceps_api_cep78_approve( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_approve(&body).await)) } #[tool(description = "POST CEP-78 revoke - query params as JSON object")] - async fn ceps_api_cep78_revoke(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_revoke(&body).await) + async fn ceps_api_cep78_revoke( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_revoke(&body).await)) } #[tool(description = "POST CEP-78 set-approval-for-all - query params as JSON object")] - async fn ceps_api_cep78_set_approval_for_all(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_set_approval_for_all(&body).await) + async fn ceps_api_cep78_set_approval_for_all( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_set_approval_for_all(&body).await)) } #[tool(description = "POST CEP-78 set-token-metadata - query params as JSON object")] - async fn ceps_api_cep78_set_token_metadata(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_set_token_metadata(&body).await) + async fn ceps_api_cep78_set_token_metadata( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_set_token_metadata(&body).await)) } #[tool(description = "POST CEP-78 set-variables - query params as JSON object")] - async fn ceps_api_cep78_set_variables(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_set_variables(&body).await) + async fn ceps_api_cep78_set_variables( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_set_variables(&body).await)) } #[tool(description = "POST CEP-78 mint-session - query params as JSON object")] - async fn ceps_api_cep78_mint_session(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_mint_session(&body).await) + async fn ceps_api_cep78_mint_session( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_mint_session(&body).await)) } #[tool(description = "POST CEP-78 transfer-session - query params as JSON object")] - async fn ceps_api_cep78_transfer_session(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_transfer_session(&body).await) + async fn ceps_api_cep78_transfer_session( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_transfer_session(&body).await)) } #[tool(description = "POST CEP-78 updated-receipts - query params as JSON object")] - async fn ceps_api_cep78_updated_receipts(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_updated_receipts(&body).await) + async fn ceps_api_cep78_updated_receipts( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_updated_receipts(&body).await)) } #[tool(description = "POST CEP-78 owner-of-session - query params as JSON object")] - async fn ceps_api_cep78_owner_of_session(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_owner_of_session(&body).await) + async fn ceps_api_cep78_owner_of_session( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_owner_of_session(&body).await)) } #[tool(description = "POST CEP-78 balance-of-session - query params as JSON object")] - async fn ceps_api_cep78_balance_of_session(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_balance_of_session(&body).await) + async fn ceps_api_cep78_balance_of_session( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_balance_of_session(&body).await)) } #[tool(description = "POST CEP-78 get-approved-session - query params as JSON object")] - async fn ceps_api_cep78_get_approved_session(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_get_approved_session(&body).await) + async fn ceps_api_cep78_get_approved_session( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_get_approved_session(&body).await)) } #[tool(description = "POST CEP-78 is-approved-for-all-session - query params as JSON object")] - async fn ceps_api_cep78_is_approved_for_all_session(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep78_is_approved_for_all_session(&body).await) + async fn ceps_api_cep78_is_approved_for_all_session( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep78_is_approved_for_all_session(&body).await, + )) } #[tool(description = "POST CEP-85 install - query params as JSON object")] - async fn ceps_api_cep85_install(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_install(&body).await) + async fn ceps_api_cep85_install( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_install(&body).await)) } #[tool(description = "POST CEP-85 upgrade - query params as JSON object")] - async fn ceps_api_cep85_upgrade(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_upgrade(&body).await) + async fn ceps_api_cep85_upgrade( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_upgrade(&body).await)) } #[tool(description = "POST CEP-85 mint - query params as JSON object")] - async fn ceps_api_cep85_mint(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_mint(&body).await) + async fn ceps_api_cep85_mint( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_mint(&body).await)) } #[tool(description = "POST CEP-85 batch-mint - query params as JSON object")] - async fn ceps_api_cep85_batch_mint(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_batch_mint(&body).await) + async fn ceps_api_cep85_batch_mint( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_batch_mint(&body).await)) } #[tool(description = "POST CEP-85 transfer - query params as JSON object")] - async fn ceps_api_cep85_transfer(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_transfer(&body).await) + async fn ceps_api_cep85_transfer( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_transfer(&body).await)) } #[tool(description = "POST CEP-85 batch-transfer - query params as JSON object")] - async fn ceps_api_cep85_batch_transfer(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_batch_transfer(&body).await) + async fn ceps_api_cep85_batch_transfer( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_batch_transfer(&body).await)) } #[tool(description = "POST CEP-85 burn - query params as JSON object")] - async fn ceps_api_cep85_burn(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_burn(&body).await) + async fn ceps_api_cep85_burn( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_burn(&body).await)) } #[tool(description = "POST CEP-85 batch-burn - query params as JSON object")] - async fn ceps_api_cep85_batch_burn(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_batch_burn(&body).await) + async fn ceps_api_cep85_batch_burn( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_batch_burn(&body).await)) } #[tool(description = "POST CEP-85 set-approval-for-all - query params as JSON object")] - async fn ceps_api_cep85_set_approval_for_all(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_set_approval_for_all(&body).await) + async fn ceps_api_cep85_set_approval_for_all( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_set_approval_for_all(&body).await)) } #[tool(description = "POST CEP-85 set-uri - query params as JSON object")] - async fn ceps_api_cep85_set_uri(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_set_uri(&body).await) + async fn ceps_api_cep85_set_uri( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_set_uri(&body).await)) } #[tool(description = "POST CEP-85 set-total-supply-of - query params as JSON object")] - async fn ceps_api_cep85_set_total_supply_of(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_set_total_supply_of(&body).await) + async fn ceps_api_cep85_set_total_supply_of( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_set_total_supply_of(&body).await)) } #[tool(description = "POST CEP-85 set-total-supply-of-batch - query params as JSON object")] - async fn ceps_api_cep85_set_total_supply_of_batch(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_set_total_supply_of_batch(&body).await) + async fn ceps_api_cep85_set_total_supply_of_batch( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep85_set_total_supply_of_batch(&body).await, + )) } #[tool(description = "POST CEP-85 change-security - query params as JSON object")] - async fn ceps_api_cep85_change_security(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_change_security(&body).await) + async fn ceps_api_cep85_change_security( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_change_security(&body).await)) } #[tool(description = "POST CEP-85 set-modalities - query params as JSON object")] - async fn ceps_api_cep85_set_modalities(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_set_modalities(&body).await) + async fn ceps_api_cep85_set_modalities( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_set_modalities(&body).await)) } #[tool(description = "POST CEP-85 balance-of-batch - query params as JSON object")] - async fn ceps_api_cep85_balance_of_batch(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_balance_of_batch(&body).await) + async fn ceps_api_cep85_balance_of_batch( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_balance_of_batch(&body).await)) } #[tool(description = "POST CEP-85 supply-of-batch - query params as JSON object")] - async fn ceps_api_cep85_supply_of_batch(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_supply_of_batch(&body).await) + async fn ceps_api_cep85_supply_of_batch( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_supply_of_batch(&body).await)) } #[tool(description = "POST CEP-85 total-supply-of-batch - query params as JSON object")] - async fn ceps_api_cep85_total_supply_of_batch(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep85_total_supply_of_batch(&body).await) + async fn ceps_api_cep85_total_supply_of_batch( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_total_supply_of_batch(&body).await)) } #[tool(description = "POST CEP-95 install - query params as JSON object")] - async fn ceps_api_cep95_install(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep95_install(&body).await) + async fn ceps_api_cep95_install( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep95_install(&body).await)) } #[tool(description = "POST CEP-95 transfer-from - query params as JSON object")] - async fn ceps_api_cep95_transfer_from(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep95_transfer_from(&body).await) + async fn ceps_api_cep95_transfer_from( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep95_transfer_from(&body).await)) } #[tool(description = "POST CEP-95 safe-transfer-from - query params as JSON object")] - async fn ceps_api_cep95_safe_transfer_from(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep95_safe_transfer_from(&body).await) + async fn ceps_api_cep95_safe_transfer_from( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep95_safe_transfer_from(&body).await)) } #[tool(description = "POST CEP-95 approve - query params as JSON object")] - async fn ceps_api_cep95_approve(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep95_approve(&body).await) + async fn ceps_api_cep95_approve( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep95_approve(&body).await)) } #[tool(description = "POST CEP-95 revoke-approval - query params as JSON object")] - async fn ceps_api_cep95_revoke_approval(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep95_revoke_approval(&body).await) + async fn ceps_api_cep95_revoke_approval( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep95_revoke_approval(&body).await)) } #[tool(description = "POST CEP-95 approve-for-all - query params as JSON object")] - async fn ceps_api_cep95_approve_for_all(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep95_approve_for_all(&body).await) + async fn ceps_api_cep95_approve_for_all( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep95_approve_for_all(&body).await)) } #[tool(description = "POST CEP-95 revoke-approval-for-all - query params as JSON object")] - async fn ceps_api_cep95_revoke_approval_for_all(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep95_revoke_approval_for_all(&body).await) + async fn ceps_api_cep95_revoke_approval_for_all( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep95_revoke_approval_for_all(&body).await)) } #[tool(description = "POST CEP-95 mint - query params as JSON object")] - async fn ceps_api_cep95_mint(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep95_mint(&body).await) + async fn ceps_api_cep95_mint( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep95_mint(&body).await)) } #[tool(description = "POST CEP-95 burn - query params as JSON object")] - async fn ceps_api_cep95_burn(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep95_burn(&body).await) + async fn ceps_api_cep95_burn( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep95_burn(&body).await)) } #[tool(description = "POST CEP-95 transfer-ownership - query params as JSON object")] - async fn ceps_api_cep95_transfer_ownership(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep95_transfer_ownership(&body).await) + async fn ceps_api_cep95_transfer_ownership( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep95_transfer_ownership(&body).await)) } #[tool(description = "POST CEP-95 bind-odra-install - query params as JSON object")] - async fn ceps_api_cep95_bind_odra_install(&self, body: String) -> ToolOutput { - ToolOutput::text(client::cep95_bind_odra_install(&body).await) + async fn ceps_api_cep95_bind_odra_install( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::cep95_bind_odra_install(&body).await)) } #[tool(description = "POST /v1/chain/put-transaction - query params as JSON object")] - async fn ceps_api_put_transaction(&self, body: String) -> ToolOutput { - ToolOutput::text(client::put_transaction(&body).await) + async fn ceps_api_put_transaction( + &self, + Parameters(BodyArgs { body }): Parameters, + ) -> Result { + Ok(text_ok(client::put_transaction(&body).await)) } #[tool(description = "GET CEP-18 name")] - async fn ceps_api_cep18_name(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep18_name(&contract_hash).await) + async fn ceps_api_cep18_name( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_name(&contract_hash).await)) } #[tool(description = "GET CEP-18 symbol")] - async fn ceps_api_cep18_symbol(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep18_symbol(&contract_hash).await) + async fn ceps_api_cep18_symbol( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_symbol(&contract_hash).await)) } #[tool(description = "GET CEP-18 decimals")] - async fn ceps_api_cep18_decimals(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep18_decimals(&contract_hash).await) + async fn ceps_api_cep18_decimals( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_decimals(&contract_hash).await)) } #[tool(description = "GET CEP-18 total-supply")] - async fn ceps_api_cep18_total_supply(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep18_total_supply(&contract_hash).await) + async fn ceps_api_cep18_total_supply( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_total_supply(&contract_hash).await)) } #[tool(description = "GET CEP-18 events-mode")] - async fn ceps_api_cep18_events_mode(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep18_events_mode(&contract_hash).await) + async fn ceps_api_cep18_events_mode( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep18_events_mode(&contract_hash).await)) } #[tool(description = "GET CEP-18 is-mint-and-burn-enabled")] - async fn ceps_api_cep18_is_mint_and_burn_enabled(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep18_is_mint_and_burn_enabled(&contract_hash).await) + async fn ceps_api_cep18_is_mint_and_burn_enabled( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep18_is_mint_and_burn_enabled(&contract_hash).await, + )) } #[tool(description = "GET CEP-18 balance-of")] - async fn ceps_api_cep18_balance_of(&self, contract_hash: String, owner: String) -> ToolOutput { - ToolOutput::text(client::cep18_balance_of(&contract_hash, &owner).await) + async fn ceps_api_cep18_balance_of( + &self, + Parameters(ContractOwnerArgs { + contract_hash, + owner, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep18_balance_of(&contract_hash, &owner).await, + )) } #[tool(description = "GET CEP-18 allowances")] async fn ceps_api_cep18_allowances( &self, - contract_hash: String, - owner: String, - spender: String, - ) -> ToolOutput { - ToolOutput::text(client::cep18_allowances(&contract_hash, &owner, &spender).await) + Parameters(ContractOwnerSpenderArgs { + contract_hash, + owner, + spender, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep18_allowances(&contract_hash, &owner, &spender).await, + )) } #[tool(description = "GET CEP-18 security-badge")] async fn ceps_api_cep18_security_badge( &self, - contract_hash: String, - account: String, - ) -> ToolOutput { - ToolOutput::text(client::cep18_security_badge(&contract_hash, &account).await) + Parameters(ContractAccountArgs { + contract_hash, + account, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep18_security_badge(&contract_hash, &account).await, + )) } #[tool(description = "GET CEP-78 collection-name")] - async fn ceps_api_cep78_collection_name(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_collection_name(&contract_hash).await) + async fn ceps_api_cep78_collection_name( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_collection_name(&contract_hash).await)) } #[tool(description = "GET CEP-78 collection-symbol")] - async fn ceps_api_cep78_collection_symbol(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_collection_symbol(&contract_hash).await) + async fn ceps_api_cep78_collection_symbol( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep78_collection_symbol(&contract_hash).await, + )) } #[tool(description = "GET CEP-78 total-token-supply")] - async fn ceps_api_cep78_total_token_supply(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_total_token_supply(&contract_hash).await) + async fn ceps_api_cep78_total_token_supply( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep78_total_token_supply(&contract_hash).await, + )) } #[tool(description = "GET CEP-78 number-of-minted-tokens")] - async fn ceps_api_cep78_number_of_minted_tokens(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_number_of_minted_tokens(&contract_hash).await) + async fn ceps_api_cep78_number_of_minted_tokens( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep78_number_of_minted_tokens(&contract_hash).await, + )) } #[tool(description = "GET CEP-78 events-mode")] - async fn ceps_api_cep78_events_mode(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_events_mode(&contract_hash).await) + async fn ceps_api_cep78_events_mode( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_events_mode(&contract_hash).await)) } #[tool(description = "GET CEP-78 owner-of")] - async fn ceps_api_cep78_owner_of(&self, contract_hash: String, token: String) -> ToolOutput { - ToolOutput::text(client::cep78_owner_of(&contract_hash, &token).await) + async fn ceps_api_cep78_owner_of( + &self, + Parameters(ContractTokenArgs { + contract_hash, + token, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep78_owner_of(&contract_hash, &token).await, + )) } #[tool(description = "GET CEP-78 balance-of")] - async fn ceps_api_cep78_balance_of(&self, contract_hash: String, owner: String) -> ToolOutput { - ToolOutput::text(client::cep78_balance_of(&contract_hash, &owner).await) + async fn ceps_api_cep78_balance_of( + &self, + Parameters(ContractOwnerArgs { + contract_hash, + owner, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep78_balance_of(&contract_hash, &owner).await, + )) } #[tool(description = "GET CEP-78 is-approved-for-all")] async fn ceps_api_cep78_is_approved_for_all( &self, - contract_hash: String, - owner: String, - operator: String, - ) -> ToolOutput { - ToolOutput::text(client::cep78_is_approved_for_all(&contract_hash, &owner, &operator).await) + Parameters(ContractOwnerOperatorArgs { + contract_hash, + owner, + operator, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep78_is_approved_for_all(&contract_hash, &owner, &operator).await, + )) } #[tool(description = "GET CEP-78 get-approved")] async fn ceps_api_cep78_get_approved( &self, - contract_hash: String, - token: String, - ) -> ToolOutput { - ToolOutput::text(client::cep78_get_approved(&contract_hash, &token).await) + Parameters(ContractTokenArgs { + contract_hash, + token, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep78_get_approved(&contract_hash, &token).await, + )) } #[tool(description = "GET CEP-78 metadata")] - async fn ceps_api_cep78_metadata(&self, contract_hash: String, token: String) -> ToolOutput { - ToolOutput::text(client::cep78_metadata(&contract_hash, &token).await) + async fn ceps_api_cep78_metadata( + &self, + Parameters(ContractTokenArgs { + contract_hash, + token, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep78_metadata(&contract_hash, &token).await, + )) } #[tool(description = "GET CEP-78 allow-minting")] - async fn ceps_api_cep78_allow_minting(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_allow_minting(&contract_hash).await) + async fn ceps_api_cep78_allow_minting( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_allow_minting(&contract_hash).await)) } #[tool(description = "GET CEP-78 operator-burn-mode")] - async fn ceps_api_cep78_operator_burn_mode(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_operator_burn_mode(&contract_hash).await) + async fn ceps_api_cep78_operator_burn_mode( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep78_operator_burn_mode(&contract_hash).await, + )) } #[tool(description = "GET CEP-78 package-operator-mode")] - async fn ceps_api_cep78_package_operator_mode(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_package_operator_mode(&contract_hash).await) + async fn ceps_api_cep78_package_operator_mode( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep78_package_operator_mode(&contract_hash).await, + )) } #[tool(description = "GET CEP-78 acl-package-mode")] - async fn ceps_api_cep78_acl_package_mode(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_acl_package_mode(&contract_hash).await) + async fn ceps_api_cep78_acl_package_mode( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep78_acl_package_mode(&contract_hash).await, + )) } #[tool(description = "GET CEP-78 json-schema")] - async fn ceps_api_cep78_json_schema(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_json_schema(&contract_hash).await) + async fn ceps_api_cep78_json_schema( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_json_schema(&contract_hash).await)) } #[tool(description = "GET CEP-78 minting-mode")] - async fn ceps_api_cep78_minting_mode(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_minting_mode(&contract_hash).await) + async fn ceps_api_cep78_minting_mode( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_minting_mode(&contract_hash).await)) } #[tool(description = "GET CEP-78 whitelist-mode")] - async fn ceps_api_cep78_whitelist_mode(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_whitelist_mode(&contract_hash).await) + async fn ceps_api_cep78_whitelist_mode( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_whitelist_mode(&contract_hash).await)) } #[tool(description = "GET CEP-78 reporting-mode")] - async fn ceps_api_cep78_reporting_mode(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_reporting_mode(&contract_hash).await) + async fn ceps_api_cep78_reporting_mode( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_reporting_mode(&contract_hash).await)) } #[tool(description = "GET CEP-78 burn-mode")] - async fn ceps_api_cep78_burn_mode(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_burn_mode(&contract_hash).await) + async fn ceps_api_cep78_burn_mode( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_burn_mode(&contract_hash).await)) } #[tool(description = "GET CEP-78 holder-mode")] - async fn ceps_api_cep78_holder_mode(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_holder_mode(&contract_hash).await) + async fn ceps_api_cep78_holder_mode( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_holder_mode(&contract_hash).await)) } #[tool(description = "GET CEP-78 identifier-mode")] - async fn ceps_api_cep78_identifier_mode(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_identifier_mode(&contract_hash).await) + async fn ceps_api_cep78_identifier_mode( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_identifier_mode(&contract_hash).await)) } #[tool(description = "GET CEP-78 metadata-mutability")] - async fn ceps_api_cep78_metadata_mutability(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_metadata_mutability(&contract_hash).await) + async fn ceps_api_cep78_metadata_mutability( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep78_metadata_mutability(&contract_hash).await, + )) } #[tool(description = "GET CEP-78 nft-kind")] - async fn ceps_api_cep78_nft_kind(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_nft_kind(&contract_hash).await) + async fn ceps_api_cep78_nft_kind( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_nft_kind(&contract_hash).await)) } #[tool(description = "GET CEP-78 nft-metadata-kind")] - async fn ceps_api_cep78_nft_metadata_kind(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_nft_metadata_kind(&contract_hash).await) + async fn ceps_api_cep78_nft_metadata_kind( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep78_nft_metadata_kind(&contract_hash).await, + )) } #[tool(description = "GET CEP-78 ownership-mode")] - async fn ceps_api_cep78_ownership_mode(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep78_ownership_mode(&contract_hash).await) + async fn ceps_api_cep78_ownership_mode( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep78_ownership_mode(&contract_hash).await)) } #[tool(description = "GET CEP-78 is-acl-whitelisted")] async fn ceps_api_cep78_is_acl_whitelisted( &self, - contract_hash: String, - entity: String, - ) -> ToolOutput { - ToolOutput::text(client::cep78_is_acl_whitelisted(&contract_hash, &entity).await) + Parameters(ContractEntityArgs { + contract_hash, + entity, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep78_is_acl_whitelisted(&contract_hash, &entity).await, + )) } #[tool(description = "GET CEP-85 collection-name")] - async fn ceps_api_cep85_collection_name(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep85_collection_name(&contract_hash).await) + async fn ceps_api_cep85_collection_name( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_collection_name(&contract_hash).await)) } #[tool(description = "GET CEP-85 collection-uri")] - async fn ceps_api_cep85_collection_uri(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep85_collection_uri(&contract_hash).await) + async fn ceps_api_cep85_collection_uri( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_collection_uri(&contract_hash).await)) } #[tool(description = "GET CEP-85 balance-of")] async fn ceps_api_cep85_balance_of( &self, - contract_hash: String, - owner: String, - id: String, - ) -> ToolOutput { - ToolOutput::text(client::cep85_balance_of(&contract_hash, &owner, &id).await) + Parameters(ContractOwnerIdArgs { + contract_hash, + owner, + id, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep85_balance_of(&contract_hash, &owner, &id).await, + )) } #[tool(description = "GET CEP-85 supply-of")] - async fn ceps_api_cep85_supply_of(&self, contract_hash: String, id: String) -> ToolOutput { - ToolOutput::text(client::cep85_supply_of(&contract_hash, &id).await) + async fn ceps_api_cep85_supply_of( + &self, + Parameters(ContractIdArgs { contract_hash, id }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_supply_of(&contract_hash, &id).await)) } #[tool(description = "GET CEP-85 total-supply-of")] async fn ceps_api_cep85_total_supply_of( &self, - contract_hash: String, - id: String, - ) -> ToolOutput { - ToolOutput::text(client::cep85_total_supply_of(&contract_hash, &id).await) + Parameters(ContractIdArgs { contract_hash, id }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep85_total_supply_of(&contract_hash, &id).await, + )) } #[tool(description = "GET CEP-85 uri")] - async fn ceps_api_cep85_uri(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep85_uri(&contract_hash).await) + async fn ceps_api_cep85_uri( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_uri(&contract_hash).await)) } #[tool(description = "GET CEP-85 uri with token id query")] - async fn ceps_api_cep85_uri_with_id(&self, contract_hash: String, id: String) -> ToolOutput { - ToolOutput::text(client::cep85_uri_with_id(&contract_hash, &id).await) + async fn ceps_api_cep85_uri_with_id( + &self, + Parameters(ContractIdArgs { contract_hash, id }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep85_uri_with_id(&contract_hash, &id).await, + )) } #[tool(description = "GET CEP-85 total-fungible-supply")] async fn ceps_api_cep85_total_fungible_supply( &self, - contract_hash: String, - id: String, - ) -> ToolOutput { - ToolOutput::text(client::cep85_total_fungible_supply(&contract_hash, &id).await) + Parameters(ContractIdArgs { contract_hash, id }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep85_total_fungible_supply(&contract_hash, &id).await, + )) } #[tool(description = "GET CEP-85 enable-burn")] - async fn ceps_api_cep85_enable_burn(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep85_enable_burn(&contract_hash).await) + async fn ceps_api_cep85_enable_burn( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_enable_burn(&contract_hash).await)) } #[tool(description = "GET CEP-85 events-mode")] - async fn ceps_api_cep85_events_mode(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep85_events_mode(&contract_hash).await) + async fn ceps_api_cep85_events_mode( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep85_events_mode(&contract_hash).await)) } #[tool(description = "GET CEP-85 number-of-minted-tokens")] - async fn ceps_api_cep85_number_of_minted_tokens(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep85_number_of_minted_tokens(&contract_hash).await) + async fn ceps_api_cep85_number_of_minted_tokens( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep85_number_of_minted_tokens(&contract_hash).await, + )) } #[tool(description = "GET CEP-85 transfer-filter-contract")] - async fn ceps_api_cep85_transfer_filter_contract(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep85_transfer_filter_contract(&contract_hash).await) + async fn ceps_api_cep85_transfer_filter_contract( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep85_transfer_filter_contract(&contract_hash).await, + )) } #[tool(description = "GET CEP-85 transfer-filter-method")] - async fn ceps_api_cep85_transfer_filter_method(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep85_transfer_filter_method(&contract_hash).await) + async fn ceps_api_cep85_transfer_filter_method( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep85_transfer_filter_method(&contract_hash).await, + )) } #[tool(description = "GET CEP-85 security-badge")] async fn ceps_api_cep85_security_badge( &self, - contract_hash: String, - entity: String, - ) -> ToolOutput { - ToolOutput::text(client::cep85_security_badge(&contract_hash, &entity).await) + Parameters(ContractEntityArgs { + contract_hash, + entity, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep85_security_badge(&contract_hash, &entity).await, + )) } #[tool(description = "GET CEP-85 is-non-fungible")] async fn ceps_api_cep85_is_non_fungible( &self, - contract_hash: String, - id: String, - ) -> ToolOutput { - ToolOutput::text(client::cep85_is_non_fungible(&contract_hash, &id).await) + Parameters(ContractIdArgs { contract_hash, id }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep85_is_non_fungible(&contract_hash, &id).await, + )) } #[tool(description = "GET CEP-85 is-approved-for-all")] async fn ceps_api_cep85_is_approved_for_all( &self, - contract_hash: String, - owner: String, - operator: String, - ) -> ToolOutput { - ToolOutput::text(client::cep85_is_approved_for_all(&contract_hash, &owner, &operator).await) + Parameters(ContractOwnerOperatorArgs { + contract_hash, + owner, + operator, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep85_is_approved_for_all(&contract_hash, &owner, &operator).await, + )) } #[tool(description = "GET CEP-95 name")] - async fn ceps_api_cep95_name(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep95_name(&contract_hash).await) + async fn ceps_api_cep95_name( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep95_name(&contract_hash).await)) } #[tool(description = "GET CEP-95 symbol")] - async fn ceps_api_cep95_symbol(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep95_symbol(&contract_hash).await) + async fn ceps_api_cep95_symbol( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep95_symbol(&contract_hash).await)) } #[tool(description = "GET CEP-95 total-supply")] - async fn ceps_api_cep95_total_supply(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep95_total_supply(&contract_hash).await) + async fn ceps_api_cep95_total_supply( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep95_total_supply(&contract_hash).await)) } #[tool(description = "GET CEP-95 owner-of")] - async fn ceps_api_cep95_owner_of(&self, contract_hash: String, token_id: String) -> ToolOutput { - ToolOutput::text(client::cep95_owner_of(&contract_hash, &token_id).await) + async fn ceps_api_cep95_owner_of( + &self, + Parameters(ContractTokenIdArgs { + contract_hash, + token_id, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep95_owner_of(&contract_hash, &token_id).await, + )) } #[tool(description = "GET CEP-95 balance-of")] - async fn ceps_api_cep95_balance_of(&self, contract_hash: String, owner: String) -> ToolOutput { - ToolOutput::text(client::cep95_balance_of(&contract_hash, &owner).await) + async fn ceps_api_cep95_balance_of( + &self, + Parameters(ContractOwnerArgs { + contract_hash, + owner, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep95_balance_of(&contract_hash, &owner).await, + )) } #[tool(description = "GET CEP-95 get-approved")] async fn ceps_api_cep95_get_approved( &self, - contract_hash: String, - token_id: String, - ) -> ToolOutput { - ToolOutput::text(client::cep95_get_approved(&contract_hash, &token_id).await) + Parameters(ContractTokenIdArgs { + contract_hash, + token_id, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep95_get_approved(&contract_hash, &token_id).await, + )) } #[tool(description = "GET CEP-95 is-approved-for-all")] async fn ceps_api_cep95_is_approved_for_all( &self, - contract_hash: String, - owner: String, - operator: String, - ) -> ToolOutput { - ToolOutput::text(client::cep95_is_approved_for_all(&contract_hash, &owner, &operator).await) + Parameters(ContractOwnerOperatorArgs { + contract_hash, + owner, + operator, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep95_is_approved_for_all(&contract_hash, &owner, &operator).await, + )) } #[tool(description = "GET CEP-95 token-metadata")] async fn ceps_api_cep95_token_metadata( &self, - contract_hash: String, - token_id: String, - ) -> ToolOutput { - ToolOutput::text(client::cep95_token_metadata(&contract_hash, &token_id).await) + Parameters(ContractTokenIdArgs { + contract_hash, + token_id, + }): Parameters, + ) -> Result { + Ok(text_ok( + client::cep95_token_metadata(&contract_hash, &token_id).await, + )) } #[tool(description = "GET CEP-95 get-owner")] - async fn ceps_api_cep95_get_owner(&self, contract_hash: String) -> ToolOutput { - ToolOutput::text(client::cep95_get_owner(&contract_hash).await) + async fn ceps_api_cep95_get_owner( + &self, + Parameters(ContractHashArgs { contract_hash }): Parameters, + ) -> Result { + Ok(text_ok(client::cep95_get_owner(&contract_hash).await)) } } /// Serves MCP over stdio until the client disconnects. -pub async fn run() -> Result<(), McpError> { - let transport = StdioTransport::new(); - let server = ServerBuilder::new(CepsApiMcp) - .with_tools(CepsApiMcp) - .build(); - server.serve(transport).await +pub async fn run() -> Result<(), Box> { + let server = CepsApiMcp; + let service = server.serve(stdio()).await?; + service.waiting().await?; + Ok(()) } -/// Default HTTP bind address for Streamable MCP. -pub const DEFAULT_HTTP_LISTEN: &str = crate::paths::DEFAULT_HTTP_LISTEN; - /// Serves MCP over Streamable HTTP until the process is stopped. pub async fn run_http(addr: &str) -> std::io::Result<()> { - McpRouter::new(CepsApiMcp).serve(addr).await -} - -impl ResourceHandler for CepsApiMcp { - async fn list_resources(&self, _ctx: &Context<'_>) -> Result, McpError> { - Ok(Vec::new()) - } - - async fn read_resource( - &self, - uri: &str, - _ctx: &Context<'_>, - ) -> Result, McpError> { - Err(McpError::invalid_params( - "resources/read", - format!("unknown resource: {uri}"), - )) - } + let config = + rmcp::transport::streamable_http_server::tower::StreamableHttpServerConfig::default(); + let service = rmcp::transport::streamable_http_server::tower::StreamableHttpService::new( + || Ok(CepsApiMcp), + Arc::new( + rmcp::transport::streamable_http_server::session::local::LocalSessionManager::default(), + ), + config, + ); + let method_router = axum::routing::any_service(service); + let app = axum::Router::new() + .route("/mcp", method_router.clone()) + .route("/mcp/", method_router); + let listener = tokio::net::TcpListener::bind(addr).await?; + tracing::info!(%addr, "ceps-rust-api-mcp HTTP listening"); + axum::serve(listener, app).await?; + Ok(()) } -impl PromptHandler for CepsApiMcp { - async fn list_prompts(&self, _ctx: &Context<'_>) -> Result, McpError> { - Ok(Vec::new()) - } - - async fn get_prompt( - &self, - name: &str, - _args: Option>, - _ctx: &Context<'_>, - ) -> Result { - Err(McpError::invalid_params( - "prompts/get", - format!("unknown prompt: {name}"), - )) +#[tool_handler] +impl ServerHandler for CepsApiMcp { + fn get_info(&self) -> ServerInfo { + ServerInfo::new(ServerCapabilities::builder().enable_tools().build()) + .with_server_info(rmcp::model::Implementation::new( + "ceps-rust-api", + env!("CARGO_PKG_VERSION"), + )) + .with_instructions( + "MCP tools for ceps-rust-api: Make/Docker lifecycle and HTTP CEP API calls. Set CEPS_API_ROOT / CEPS_API_URL as needed.", + ) } } #[cfg(test)] mod tests { + use super::*; + #[test] fn mcp_server_version_matches_crate() { - let src = include_str!("server.rs"); - let needle = format!( - r#"#[mcp_server(name = "ceps-rust-api", version = "{}")]"#, - env!("CARGO_PKG_VERSION") - ); - assert!( - src.contains(&needle), - "bump #[mcp_server(version = …)] to {} when changing Cargo.toml version", - env!("CARGO_PKG_VERSION") - ); + let info = CepsApiMcp.get_info(); + assert_eq!(info.server_info.version, env!("CARGO_PKG_VERSION")); + assert_eq!(info.server_info.name.as_str(), "ceps-rust-api"); } } diff --git a/mcp/src/tool_args.rs b/mcp/src/tool_args.rs new file mode 100644 index 0000000..d5272f4 --- /dev/null +++ b/mcp/src/tool_args.rs @@ -0,0 +1,77 @@ +//! JSON-schema parameter structs for rmcp `Parameters` tool handlers. + +use schemars::JsonSchema; +use serde::Deserialize; + +#[derive(Debug, Default, Deserialize, JsonSchema)] +pub struct FeaturesArgs { + #[serde(default)] + pub features: Option, +} + +#[derive(Debug, Deserialize, JsonSchema)] +pub struct BodyArgs { + pub body: String, +} + +#[derive(Debug, Deserialize, JsonSchema)] +pub struct ContractHashArgs { + pub contract_hash: String, +} + +#[derive(Debug, Deserialize, JsonSchema)] +pub struct ContractOwnerArgs { + pub contract_hash: String, + pub owner: String, +} + +#[derive(Debug, Deserialize, JsonSchema)] +pub struct ContractAccountArgs { + pub contract_hash: String, + pub account: String, +} + +#[derive(Debug, Deserialize, JsonSchema)] +pub struct ContractTokenArgs { + pub contract_hash: String, + pub token: String, +} + +#[derive(Debug, Deserialize, JsonSchema)] +pub struct ContractOwnerSpenderArgs { + pub contract_hash: String, + pub owner: String, + pub spender: String, +} + +#[derive(Debug, Deserialize, JsonSchema)] +pub struct ContractOwnerOperatorArgs { + pub contract_hash: String, + pub owner: String, + pub operator: String, +} + +#[derive(Debug, Deserialize, JsonSchema)] +pub struct ContractEntityArgs { + pub contract_hash: String, + pub entity: String, +} + +#[derive(Debug, Deserialize, JsonSchema)] +pub struct ContractOwnerIdArgs { + pub contract_hash: String, + pub owner: String, + pub id: String, +} + +#[derive(Debug, Deserialize, JsonSchema)] +pub struct ContractIdArgs { + pub contract_hash: String, + pub id: String, +} + +#[derive(Debug, Deserialize, JsonSchema)] +pub struct ContractTokenIdArgs { + pub contract_hash: String, + pub token_id: String, +} diff --git a/mcp/tests/transport_smoke.rs b/mcp/tests/transport_smoke.rs index f698024..ad11c18 100644 --- a/mcp/tests/transport_smoke.rs +++ b/mcp/tests/transport_smoke.rs @@ -35,6 +35,29 @@ fn repo_root() -> String { .into_owned() } +/// Parse JSON-RPC from a plain JSON body or Streamable HTTP SSE (`data: {...}`). +fn json_rpc_from_body(body: &str) -> Value { + let trimmed = body.trim(); + if let Ok(v) = serde_json::from_str::(trimmed) { + return v; + } + let mut last = None; + for line in body.lines() { + let line = line.trim(); + let Some(data) = line.strip_prefix("data:") else { + continue; + }; + let data = data.trim(); + if data.is_empty() { + continue; + } + if let Ok(v) = serde_json::from_str::(data) { + last = Some(v); + } + } + last.unwrap_or_else(|| panic!("no JSON-RPC in body: {body}")) +} + #[tokio::test] async fn http_initialize_and_tools_list() { let bin = mcp_bin(); @@ -80,7 +103,8 @@ async fn http_initialize_and_tools_list() { .and_then(|v| v.to_str().ok()) .unwrap_or("") .to_string(); - let body: Value = resp.json().await.expect("init json"); + let init_text = resp.text().await.expect("init body"); + let body = json_rpc_from_body(&init_text); assert_eq!( body["result"]["serverInfo"]["name"], "ceps-rust-api", "{body}" @@ -116,7 +140,8 @@ async fn http_initialize_and_tools_list() { .send() .await .expect("tools/list"); - let tools_body: Value = tools_resp.json().await.expect("tools json"); + let tools_text = tools_resp.text().await.expect("tools body"); + let tools_body = json_rpc_from_body(&tools_text); let tools = tools_body["result"]["tools"] .as_array() .expect("tools array");