From 06a233633e2b8e8b10c11a8855a904279ced0dfd Mon Sep 17 00:00:00 2001 From: geoffsee <> Date: Wed, 4 Jun 2025 22:33:37 -0400 Subject: [PATCH] configure basic MCP server --- Cargo.lock | 496 +++++++++++++++++++++++++++++++--- Cargo.toml | 5 +- bun.lockb | Bin 510752 -> 506302 bytes killport.js | 0 package.json | 3 +- src/counter.rs | 211 +++++++++++++++ src/handlers/model_context.rs | 185 +++++++++++++ src/handlers/models.rs | 48 ++++ src/main.rs | 1 + src/routes.rs | 22 +- 10 files changed, 921 insertions(+), 50 deletions(-) mode change 100644 => 100755 killport.js create mode 100644 src/counter.rs create mode 100644 src/handlers/model_context.rs create mode 100644 src/handlers/models.rs diff --git a/Cargo.lock b/Cargo.lock index 2834070..ddf4aac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,23 +26,27 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anyhow" version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" -[[package]] -name = "async-trait" -version = "0.1.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "autocfg" version = "1.4.0" @@ -51,13 +55,13 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" -version = "0.7.9" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5" dependencies = [ - "async-trait", "axum-core", "bytes", + "form_urlencoded", "futures-util", "http", "http-body", @@ -76,7 +80,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper 1.0.2", + "sync_wrapper", "tokio", "tower", "tower-layer", @@ -86,20 +90,19 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.5" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" dependencies = [ - "async-trait", "bytes", - "futures-util", + "futures-core", "http", "http-body", "http-body-util", "mime", "pin-project-lite", "rustversion", - "sync_wrapper 1.0.2", + "sync_wrapper", "tower-layer", "tower-service", "tracing", @@ -147,6 +150,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + [[package]] name = "byteorder" version = "1.5.0" @@ -159,12 +168,42 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +[[package]] +name = "cc" +version = "1.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0fc897dc1e865cc67c0e05a836d9d3f1df3cbe442aa4a9473b18e12624a4951" +dependencies = [ + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "cpufeatures" version = "0.2.16" @@ -224,6 +263,12 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" +[[package]] +name = "dyn-clone" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" + [[package]] name = "encoding_rs" version = "0.8.35" @@ -239,7 +284,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9fb5a367b9846933e271a3c2a992930743f82ae5e8cb7faa780715a80fa0b15" dependencies = [ - "rand_core", + "rand_core 0.6.4", "sha2", "sha3", "zeroize", @@ -386,7 +431,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] @@ -482,6 +539,30 @@ dependencies = [ "tower-service", ] +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "instant" version = "0.1.13" @@ -497,6 +578,16 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + [[package]] name = "keccak" version = "0.1.5" @@ -545,9 +636,9 @@ dependencies = [ [[package]] name = "matchit" -version = "0.7.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "memchr" @@ -578,7 +669,7 @@ checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ "hermit-abi", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys", ] @@ -609,6 +700,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "object" version = "0.36.5" @@ -637,6 +737,7 @@ dependencies = [ "futures", "http", "lazy_static", + "rmcp", "rust-embed", "serde", "serde_json", @@ -705,6 +806,12 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "percent-encoding" version = "2.3.1" @@ -723,6 +830,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[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.92" @@ -741,13 +857,48 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha", + "rand_core 0.9.3", +] + +[[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.3", +] + [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", ] [[package]] @@ -812,6 +963,47 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rmcp" +version = "0.1.5" +source = "git+https://github.com/modelcontextprotocol/rust-sdk?branch=main#a66f66ae345a0fafde1e2ee496ec137d77aef82a" +dependencies = [ + "axum", + "base64", + "bytes", + "chrono", + "futures", + "http", + "http-body", + "http-body-util", + "paste", + "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 = "0.1.5" +source = "git+https://github.com/modelcontextprotocol/rust-sdk?branch=main#a66f66ae345a0fafde1e2ee496ec137d77aef82a" +dependencies = [ + "proc-macro2", + "quote", + "serde_json", + "syn", +] + [[package]] name = "rust-embed" version = "8.5.0" @@ -873,6 +1065,31 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "chrono", + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -899,6 +1116,17 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde_json" version = "1.0.133" @@ -969,6 +1197,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -1025,6 +1259,19 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "sse-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f649a9f9e91db2ed32f3724516eac2bc09fab77fc33be8f670f5619b9dc6c3f" +dependencies = [ + "bytes", + "futures-util", + "http-body", + "http-body-util", + "pin-project-lite", +] + [[package]] name = "syn" version = "2.0.89" @@ -1036,18 +1283,32 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - [[package]] name = "sync_wrapper" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "1.1.8" @@ -1060,9 +1321,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.41.1" +version = "1.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" dependencies = [ "backtrace", "bytes", @@ -1078,9 +1339,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", @@ -1113,14 +1374,14 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", "pin-project-lite", - "sync_wrapper 0.1.2", + "sync_wrapper", "tokio", "tower-layer", "tower-service", @@ -1235,7 +1496,7 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ - "getrandom", + "getrandom 0.2.15", ] [[package]] @@ -1266,6 +1527,73 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1297,6 +1625,65 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -1370,6 +1757,35 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "zerocopy" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zeroize" version = "1.8.1" diff --git a/Cargo.toml b/Cargo.toml index af79aab..803ef9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ name = "agent-server" path = "src/main.rs" [dependencies] -axum = { version = "0.7", features = ["multipart"] } +axum = { version = "0.8", features = ["multipart"] } serde = { version = "1.0", features = ["derive"] } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" @@ -30,4 +30,5 @@ sled = "0.34.7" tower-http = { version = "0.6.2", features = ["trace", "cors"] } anyhow = "1.0.97" base64 = "0.22.1" -fips204 = "0.4.6" \ No newline at end of file +fips204 = "0.4.6" +rmcp = { git = "https://github.com/modelcontextprotocol/rust-sdk", branch = "main", features = ["server", "transport-streamable-http-server", "transport-sse-server", "transport-io",] } \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index 97e3aa918028a4ea60172afc78d7eb4a6ac4f52d..5687103f8b61079c6a38b1dba83bf8469a29ad53 100755 GIT binary patch delta 111168 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 z zfH?_K1#G}_U9c(M&FdREISnd3y~SOCH==%j66{J=h*&yd2Oh=lFUlUnFm?V_r74kOLK3gre4c8;Lf`{@3% z2=dv3=lTd5um!rZBSNg-+eg>mGcsey8VrWqmm-$Zk}cM0x^j^;X)BPfky3rrhn}D7 z_{`Ph7^o9TaX=Ugb{|>=cLp+JfR^{iuZPE8YTvfqOA~GDNXlVaKOjm1@p43$B`$OB zCz%lW!zP{JdWQ9Ye*+__^ER|B2(K5>eLG7~!uH_Qf&CZRY)GlbC0H-Btr~ZW=Ud)n}7HR`x`g!&oUv(6ZryR^aSD~@TmTg)zvjI zL*t}l9SiG1l<;!#Lq|uS@^1ze)kdZv&+|y4HOzfI5H3LI%I!(7=z9JH5TN6u&_be% zF_^1Qmyv!u=6lvMv51CPfB7iQC;T;zjT~=_;|J&RW1Hqc{d;%qTNQ1A61Hi;1J16X z?Fa(*TS3X&p~51t)Wh(0g^=a7xz%&L`^_zeTBQ}_u#&uYV5{g1o#G|(?MTbGVAnQm z6Y$j%)}QEAv|tAuMKxDb$yoHD{%T>3jO!M;z}Vu!dDIT8l520Znp(x82P;<7xL9l| z)7Mb5^U&J`Yv?v8jlZlB8uiROX>E+rr z;1FGRC*1t$Yv|NYY|br)UMXOX+`6ZY2fyU>NH>!}Mramz4$7rL^01ErwcaBzcYXq`nXEq1srJ%;L~ zAb;9Gse8fU(gup#hv(f5G&KPf{Vj#KR!ymDdn;jQDNta^=KcM}1{xU;q-xgeXo|wS zacQ)e8s4W{>|7oAwgf16dV^x4EZMRD&M?cLex7YA*&9t6OnX8iMn(It?{e%4->9(7 z0@};6r0nj$V*5^P?Pa2U7){M~v*3Vmz##O^NblPHw0%hv!e%1{Gosu^aV}|mok}d& z@+t4uvSo$!zHoU}-bA)o)C@H@i7C_bQhL=1qwV{EC#+dkJh|){3p#fOc(BGbuqd26 zJb7WfWU6+_(a_c3L~a-zgAZ!u(lOZ5Hi2;@I?$ zft{C}1rk$@-G+f)Gyq8RQ%AGIL=Uw4n890UJA-#^5p(xK?`k(4UcMS zJ_S-u)~SXSR-XU&|CV22_2sWeiZs9C>uSZ2ixZ*>S0!SH3yq<~M9imz7)nos7+P-^ z%gvv5u6s-SL}ltM8_HkuvF8h`(p5BR7Sx0P%*jWt`{8E)D3%uNM@uTjicPFdskqH! z7pBbDmNTusy0MhBA8mdUOaI2xczUN8y5g(vUY}`mUwE3eyN330QiuK1-@OSRlm#6@ zI2+Hp_Hoqz0BWf#Yni0~d}Z?m8-q;xmK8_gKp30t678_+?a|}Bej9HLd|n2RFqH77 zQu~t**{}OK@d<%_a?sVH@pK!sIxNwz51^&u>Y%eaDHzJdi;eP4dQMPQ%n|ks^A$08 zy2Vp0Uotd~C-)!mY!grS4uXTYS1E0c)m#=CqF0HAeShg$kwZt`?cl3m4qwL}xSIlg z#F|`qHIfHC_z^nr+1|)Q)>93GF$37H82nY$<~}7#2`4kY1H$)S`)Ji6vvWi(vb*+C z3M0&V1hkIr+LB;(*m{JeE-Qh8lOWf331ZYn9p4bz;`UW|7DIVOYzUbqinYA%nak-r zQa*zB4rg4=*XfifS$;kBck8+;qQ2|%nCK8fUW z1P$yA1aGG!`hC*($4gdlF0eO_5xo;Bhj|AiQW%iNU?5o>GrJZIYBpmzK33uNfRU3? z!sb$(nuvB7LAy1P?2iJm9|$&8 zZnbWC^OoNm+@Qj#s@V{-FG@~2+2@4tqt;fIhAc>pb#Bj=dlO1EjQzK^Olc-YVX_hZ z3e?HAQRs0D`RxO=;yBbw4u+~k2{fVn3F}IhhR_%>M5lLp?+@tF%!L~X;{*G8{s9o; zElsOWS~vU$WWppUT^Xz%92SE;xX3>)36;hNIN~6rRn=;M==4ITzJ(6TC)b95Zp?b;R#=1?_i>E|@xEU7&E;ZR|K=hIQ&*+nk zJ~Ea&Bc|7yZA+e&DSdGkc*?7X>L}qBZ}~Q7v}aU>mg0jt7BJ3TtIndurzPU`n~B4Y z_Kw)7vy8_tWkG|DJp~Bg47{`S1Nt00x~5c=wa)Sye&Mr;8M6lVEceC!tY}gF;=ets z-OdT#v24&df#x3@6nuYSCWePk}rDA&ZwOn!!|cDBVOY9J{7zPq{Nx`)BJt>RRvvu0UMPJEedU zS4|yK;G}zdf#OoIniRVzv}@?aPxd{S<-i7})a7z0VI5kud5YIekBMno_qBmbzDPNs zm7B0LxnHn$EI#9sU?glwXT$e+FAj3M&$DWd4Y)8^l4Gn^U!tiO(A_hA#b_StHvE__ z=TbNj(mkLY3R^BwGLSmq9&&aw+azt`6+9Mx^$WRO#8;-hF4M(}I2PiTy~iaCQ2eiA zR6o9UbKSfh`sVWcRHK*0JCsyHiycaj3)nmSG-CGFQLT^uL{rIf=87< z-`c=sxe3wZDrEv;91jHZC{}ZLN2_&-$4rQ&D5;E+p6$1GX+8YsPfaCzu9EjJp#231 z0}x)(duF%m8DumeGG)CN7i3?Lui<{lRAP6H7Jyb)>K1MK1;guli?08Ib6~w&RP!?4 z8{MM*mr)LjYaHH<*yiB@;@2<_^`p0?FNxh-oWR>1FNP9RDO2)facj9|+?h_<-30u=^^kb@}@X z;6~79Kh_C<+-N(X#NTmFwb&&SW}<|r6g0^qm104wvr8rSUr|eiRIwEex^nlTe$rjO zot2ZXMk-}~?)iY>(NzTcEK#S-6uM+2-^=*#506!0t7g=P1IX4m}f z_KPuPGx;)yHyI#gExPsh=p47lVV+o(4rIqTwD5`^D%*oT?YtLx6`ei?RvZXF!?&30 zH*3bnNC5V$_78;r$8y`CW5X9U*o_i4Hc$zMvI}Sp&JV@(8C9#&;B66uyK=C$)(VTv zhcx{v27lQ-+J~nh>5&kNOQnD^9cM&@LFGM!$)Jw(DnMw=W6}9Gi!1(EyV){)SFfG= z(BMgrsoOOu*19x`LMV|g^Ca!RChEw*yYXO}P@j#FYtpS<{P9JIwts>0G)maSbgtB@ zpX;<*d$m4l>xk;fWr-Nq%cJ7LNnJQBi5Gs*-c6(6>!?j0lMPRSWF-mi`E&2by+WpF zyfoz7G&*!0?Q8dxY;Qn1v!03N{i{v4EXLI+Hw;L*uKkowK0vr#OBYI8bCbTpr=P_w zV>=3FH6(2FTr3fNGncj~<})@#XZa+ZX5X;xp&L4jZZh|dKscZssYgoZ%)C160Z&Lz z?e41YbF#k)c?1E$d*!sBbv3%r&`mZWrpuB~$6I#t`~9Z9sU-3_4Pe?BAb4*M-sGJ) zed4pVCPWfS%AjOo`ru648C%zzO0GPo?VvTJ1Hr5I)&u@eH%t#4XF?Ropj75wAw$?E zFM8ivTC&sLvL-|Wl<)%d)B2p0evckTTR|dPY=ebg22H&U?xTRwSOSx^Qsq7!&eg2E_qkw0i+u0Es+yf8X5f+ve{2XH z?CuR6!$QGU$6}PQ=`b_Z;eOXE)(^E3-0&koAxa!kvaI>1S#xH8{j<(83cv7{VfUIc zQ>}3bfLLA&P_iJAuweIz9yGc zh&LDrR?&CAKbk-HkJis+6To8{N_Y~bH5xLe){>X({AKQ-jd)E#OdAb^JrJE&%x~i3 zpT!2QMC_3zCB6)bK015u4O0o0l7p!bmgt7Fq3~J`Wl`0;K-S7m=zZ6^gJp|XIbwwf z7(MojpmF%nepmk`Qzl-{0CPl=bHj?f6RXS9^2Ii63!HUL96nj^?B7|?oqN{jb<$>N z=m#h-H_eBp1WcMU0w-Ed(SiRgK1T@;%Ff|2m(P84s0^0~{T>M>Z|_@|HRt4$+mteE z3K|;9|LkH(0T0kE6;_4d%XqvSD(WmXL+DM5Q(e9?%=rn`@^v2uBG4=HA;z-u39(DG zJvL;>`5M1txxtR3o%vdhBd>?pwF_}YKrk>PG{e64^#-4J?)e%=QuIk1%RW|=@(vSn zs1+T0j40dWhqw~`3UD6SuuYSlMzwCt5*Ei1Bv~S>M`-N=Ab8$J_CDKWThM2BfRGZ1 zv7&B3=nh-a>_?adigEfQ92Ph0>1G;gQ%_aMwNlVyAXIzuA@WiTc!G8oPeVHkp0v?U z%{l&;4f&uVw}J@eJum38TTql{r{R_%wJ2>#Ll5#bfl5AsV;wC<{T{jj#c0VBbZ;9z z`p3H=3%R9PWR*PI4N9A^)D;5ZRS~ieFF|fkF%vB| zN0vN}9Q$%zi>w2tl9MH95@-!qCBoSG+`e^7_DnD#p5j|3=KdB4o~`S*hK|T6TJ53< zVQ(u+=2~qZHqfC7KHE_Ber!uQOlt&!H=$EDzSJ&l)KL?nlPqz5^QL~cGsZ7WB?D}! z^E0$8L?Uj?2y9nB^7;`IVm8tf0AXAq5rfNQ7b{iSDa(Y2l_lRdP5*er!WDB(B}Z*3 znQ5;8!CTy#3hw(aJsHy1gm{LMGAQZhol?h8(P6Wx#L|uoa7Y-++6hEVyWyXQw5YMl zgs5jnzKm!s5grbc|8;kNx4|YvA3K_vj#19*n%LlEsco5;hK<}E@Z0^97-6;=8(|I3 z=K_%~52HJr8SElxpEQ6bmaZdatma1@gc9CL}6929~V46^d!e3y{%`8K$Uf_52E}wMt zg|(M)-DhIaJNw+acgyOBjhb7LlO0(km$lRu%4M5(OzbwU{B5b&IPUm6Q{7DXSw=bw z^*P(LT~nI45f)~sw4theDg;pF#wP=645;!LCDKUF`ix>TF~C+`#GKBmtBEu|3EFp3<6o|?W}VzXFFdpAxj&`2MC?3fr8%P>1l|3 ziAvjmfM??6&->2Z9Wxi}x?|BWu>7^u?kXh*4vqNU$h&DmP?RUmvC3RwjuJR_HUQDw}Pi`AE#N{kgL z_AP4Z2n6?kkipY#n7%ePGDX|JB1M6_E~Fw&eU0bjiZmcA&wElua(e|0mcwT#TwbcZ zc{r{4GY@6q!~2hi^#irbp62fdCH;X7Og3H>QpqfARI@9K{df53J=Novz0EesBu@`m z7RCr5dCl1WaJ08R^*Y;h(%Z3CmULR@QKm|~&sc5EfWhKnf$w;>XPJ7hs?L>fKDnxL zig<<4^Zf12er2W;on9CGQL(4^JcWkB_0){i@{XBm6|=?ffo8sALU@qo!B$QF`>|A0 zQ%c!TrK-?ti+{Isl=B0krz*>kk zZj^2UZ1}acI4Ml}EIlaF=Fgiz@O3@d$#_VkFL>C2hyC##KOcKbZ#5q5EVB4qmdu{B za@qHfMz2K)Z-AcoD+X>f0I`(D@j#RWZB&EBJNEo+8wvzYaLoNcJFz8q9bbEGg9|%z zv=UgaNVMoi+d*rH04=Yy6%N@ofBx@KgolH>ws}tZgi?#>19jr*O#W7oS?lc-X{Gnj z6?3OE{B(4u94klz@6OhEM|o#!yh|eWG#0d!Apq_0Fa;SXd9kYQdM`R@Q**f7q|IyL z=t0TMt7d;nW8RXd!5_8)@4NfvtV?V=dhRAcfi0UUeDy&3dD2XNiddi0l_5nl;XcyI zb<&g4_4=uKKf9Z2qn~PA+DMor8)^<(JEQSgjvL{Yp`NWM;j!}Q=fA1x^zpmI{N{7t zzDDF-6jD6}1UGT){#xG_ZB{oC2$m}3jsty2QAicH%GdEUIN}dmG168Se>J4vrZ`hA zZ5vbnV(7$?#uU!a!%gToKZQ%6G}#r`SJbHrdo&e|4ZJ_OclG&;8-tBJ`PFYm{>7mr z=5tZ<>B762rREu&b1x~Rh+*s~t+8T$HKSP28q$DZ1)IL=-Lk+Uy*VHSLGi4e;GSZO zG5VxAWizr>bFuWHZ;1(NTUpo-m^lY0pu2RDyog0yDTg`eLvr%?QCoCiWa zKNLH*H}*#V2OLu(4})X8g$=&M@{`UZGM`jJ31VGXy(JIBz!t);IaxEghC{CzENyw+ zAu2PPZ$GPFA=P4#74yOosz-l=MBk;93Y8;bx}+SHSQ@pYC_BirJ|xeoR%Bm09XmqMJpG2|fRPg_O@yvc@d|50Q3s~K@tti6|tDQ*G>5+S>kC2r4 zC81*Ye)|y8cN%SEaMS9bdCxCp4SoR*d|ZJVKa_z{XT5H?^}DDahZ4CcEsZAIQfT=` z8C;boFiX-RsLKZk<6epQ=?KM*u3Gb3@L)3q+|2}4N!qMv3S-(6k~U9Jm!vfl)Fo-* zHp+28%L@Pa41qRN9ifyQ=VOm2LZo~@!c)Z!skk1=iNn;GW1)Bz&}AklOP+32P?qxf zn7JdBpdpJp1d7-$E$N2xA*tsYZHouy+3VW*rzWC|atejoEBa_1LM_)3kn z9&686NZ5(bI*k>8WPf@_pRj#<()O&>W}BxMR)o7%3naN=?L<@!lH6p2*6<1&G;?q1 z=-+Hz-ICKyGZmj&x;ulrE%q=*WcT{P^U2mtyzcY<4li_=jqs;l3mMX`+AF^lt%Sb^ zv_Sg4P|(UGPg>HacxP;lVKx+19<|!ytjeazh$s{k%YMBBG<8`!?ohEjkFKc&Qp~-nXc|GzNT-d{Fh?;?JNk_pG|Z3K z(d(k}IA_lIPYI zPqZ?{6Hk@Q6V6DH?~Ri}X}!sPVkV?E1oZuK1OaL}W6MyC;{>||eIZ>TC-)EE;-Z7V=7>BIA zQH&E=dm*_JoU<2ZFI?_*@Dv$)p~dbNNZnb|9X}l_!AX0aInkyjY$QDmu8DU{rm5}l zMCLtr4?Klba)poltSTR>%Jvy(O4;jE3lzvJ8_KDCk)JY*Q~4r^n~xDsk;IKNyoyQY zQD`uJkN&kJJX~{{orB4Y( zP7LbN01{Uwiq7u zqiUw=li7h*;13JLB%u7bf4=+t2fI%GIpOhv4O6Y>^=&AQsVn-@<0qp=8nR3)3 zqkZ)!Iv*3lY!r{iHN=)ig4SR*5=TRnwWBEJ-Uo3f?8vyV&c5RDnoqi#xX+gL)^@Dv zY5Cp#b*2);tYk2)*=QP#yV)ort;8*Wnsr6X%tiufh}L!#4202aM2?0yDM#eU!^K-Z zD%<{*sbz@OImEOdqwVa*DC*!{C($zEoC#qzdP(Ez8cDXkP%StNIk%YZ(3j+ccVqIG z;zr>@wF|GiXP(>d$}vlB4I1)C&myEmWw&&NI|AM+6ywi=g)y&tU(yy|I0>G8NjLe4 zbgA}!_#FXhwf*#+J4_j6sU0x8e_L{gi|;Qw+?v5>;O6OJK`7y%wt5G)j2#!1<{(S( zw}lGkp4~T!4*BU_3q>P&WiBIS8taKKOW&^ zxg?0fy6IhXH-adxn|`YKICM|G%d9e*I`iK$sxw;LU%K>IalBpTr#0c=kWOd$*N$`z zM$?M!`p(6Rw%4OB{B6t*l-XV1!6P_Od$o8K`XJSRbJ;JfiwIZA&}sD_Z_UVd&(?_` z?<1{eju>CYf2(y7+SWr~X-en_fjc!nKKq!j-=;9U^9}0#vD1g!2Xwr#4DYN58^7%L zU10l`hP$%-+w(iKr+@Rf!85$GBW&WRD{WGTdX)GY?>O^MP0Xlv>ige{4$sEBJ>E+V z^ebC)S-Xp4#~`pD|C0W4+87cMPVIZ>t4z68OkBOqY}DYK{By_+=f0@T&g+havu|-sYbANmEc6Mgj66UwgE-?6j)Iw)ZH5b`A(*93zpuVJbr_~M(D`(Iv4p`%`i6Go z-bde%+|KEXCagcNFIm2XV5n&b?R=~+XQTaZy#QJ~R9}(od+EzsBVU?ZeX83_Uo)Xn zn*L*(VyM2JMwig?g+6u++4j~4B$OCp^STkaB=O*DY>YJ% P1|7G#YDHT|7YYA=;+f^~ delta 113268 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 G;{OA!$LUl6 diff --git a/killport.js b/killport.js old mode 100644 new mode 100755 diff --git a/package.json b/package.json index d43a638..3b13dd7 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "private": true, "scripts": { "clean": "rm -rf .genaiscript && rm -rf dist && rm -rf node_modules && rm -rf open-web-agent-rs && rm -rf target && rm -rf packages/genaiscript-rust-shim/dist", - "dev": "./killport.js 3006 && bun run build && cargo watch -x 'run src/main.rs'", + "dev": "bun i && ./killport.js 3006 && bun run build && cargo watch -x 'run src/main.rs'", "start": "docker compose up --build", "ai:search": "genaiscript run packages/genaiscript/genaisrc/web-search.genai.mts --vars USER_INPUT='who won the 2024 election?'", "shim:ai:search": "pnpm build && ./packages/genaiscript-rust-shim/dist/genaiscript-rust-shim.js --file=packages/genaiscript/genaisrc/web-search.genai.mts USER_INPUT=\"Who won the 2024 presidential election?\"\n", @@ -16,6 +16,7 @@ "ai:url:scrape": "npx genaiscript run packages/genaiscript/genaisrc/web-scrape.genai.mts --vars USER_INPUT='{\"url\":\"https://www.time4learning.com/homeschool-curriculum/high-school/eleventh-grade/math.html\",\"query\":\"What is on this page?\", \"action\": \"scrape\"}'", "prod:logs": "fly logs", "test-http": "test/test-search.ts", + "mcp-inspector": "bunx @modelcontextprotocol/inspector", "build": "(cd packages/genaiscript-rust-shim && bun run buildShim && bun run setupDev && cargo build)" } } diff --git a/src/counter.rs b/src/counter.rs new file mode 100644 index 0000000..0d08cfc --- /dev/null +++ b/src/counter.rs @@ -0,0 +1,211 @@ +use std::sync::Arc; + +use rmcp::{ + Error as McpError, RoleServer, ServerHandler, const_string, model::*, schemars, + service::RequestContext, tool, +}; +use serde_json::json; +use tokio::sync::Mutex; + +#[derive(Debug, serde::Deserialize, schemars::JsonSchema)] +pub struct StructRequest { + pub a: i32, + pub b: i32, +} + +#[derive(Clone)] +pub struct Counter { + counter: Arc>, +} + +#[tool(tool_box)] +impl Counter { + #[allow(dead_code)] + pub fn new() -> Self { + Self { + counter: Arc::new(Mutex::new(0)), + } + } + + fn _create_resource_text(&self, uri: &str, name: &str) -> Resource { + RawResource::new(uri, name.to_string()).no_annotation() + } + + #[tool(description = "Increment the counter by 1")] + async fn increment(&self) -> Result { + let mut counter = self.counter.lock().await; + *counter += 1; + Ok(CallToolResult::success(vec![Content::text( + counter.to_string(), + )])) + } + + #[tool(description = "Decrement the counter by 1")] + async fn decrement(&self) -> Result { + let mut counter = self.counter.lock().await; + *counter -= 1; + Ok(CallToolResult::success(vec![Content::text( + counter.to_string(), + )])) + } + + #[tool(description = "Get the current counter value")] + async fn get_value(&self) -> Result { + let counter = self.counter.lock().await; + Ok(CallToolResult::success(vec![Content::text( + counter.to_string(), + )])) + } + + #[tool(description = "Say hello to the client")] + fn say_hello(&self) -> Result { + Ok(CallToolResult::success(vec![Content::text("hello")])) + } + + #[tool(description = "Repeat what you say")] + fn echo( + &self, + #[tool(param)] + #[schemars(description = "Repeat what you say")] + saying: String, + ) -> Result { + Ok(CallToolResult::success(vec![Content::text(saying)])) + } + + #[tool(description = "Calculate the sum of two numbers")] + fn sum( + &self, + #[tool(aggr)] StructRequest { a, b }: StructRequest, + ) -> Result { + Ok(CallToolResult::success(vec![Content::text( + (a + b).to_string(), + )])) + } +} +const_string!(Echo = "echo"); +#[tool(tool_box)] +impl ServerHandler for Counter { + fn get_info(&self) -> ServerInfo { + ServerInfo { + protocol_version: ProtocolVersion::V_2024_11_05, + capabilities: ServerCapabilities::builder() + .enable_prompts() + .enable_resources() + .enable_tools() + .build(), + server_info: Implementation::from_build_env(), + instructions: Some("This server provides a counter tool that can increment and decrement values. The counter starts at 0 and can be modified using the 'increment' and 'decrement' tools. Use 'get_value' to check the current count.".to_string()), + } + } + + async fn list_resources( + &self, + _request: Option, + _: RequestContext, + ) -> Result { + Ok(ListResourcesResult { + resources: vec![ + self._create_resource_text("str:////Users/to/some/path/", "cwd"), + self._create_resource_text("memo://insights", "memo-name"), + ], + next_cursor: None, + }) + } + + async fn read_resource( + &self, + ReadResourceRequestParam { uri }: ReadResourceRequestParam, + _: RequestContext, + ) -> Result { + match uri.as_str() { + "str:////Users/to/some/path/" => { + let cwd = "/Users/to/some/path/"; + Ok(ReadResourceResult { + contents: vec![ResourceContents::text(cwd, uri)], + }) + } + "memo://insights" => { + let memo = "Business Intelligence Memo\n\nAnalysis has revealed 5 key insights ..."; + Ok(ReadResourceResult { + contents: vec![ResourceContents::text(memo, uri)], + }) + } + _ => Err(McpError::resource_not_found( + "resource_not_found", + Some(json!({ + "uri": uri + })), + )), + } + } + + async fn list_prompts( + &self, + _request: Option, + _: RequestContext, + ) -> Result { + Ok(ListPromptsResult { + next_cursor: None, + prompts: vec![Prompt::new( + "example_prompt", + Some("This is an example prompt that takes one required argument, message"), + Some(vec![PromptArgument { + name: "message".to_string(), + description: Some("A message to put in the prompt".to_string()), + required: Some(true), + }]), + )], + }) + } + + async fn get_prompt( + &self, + GetPromptRequestParam { name, arguments }: GetPromptRequestParam, + _: RequestContext, + ) -> Result { + match name.as_str() { + "example_prompt" => { + let message = arguments + .and_then(|json| json.get("message")?.as_str().map(|s| s.to_string())) + .ok_or_else(|| { + McpError::invalid_params("No message provided to example_prompt", None) + })?; + + let prompt = + format!("This is an example prompt with your message here: '{message}'"); + Ok(GetPromptResult { + description: None, + messages: vec![PromptMessage { + role: PromptMessageRole::User, + content: PromptMessageContent::text(prompt), + }], + }) + } + _ => Err(McpError::invalid_params("prompt not found", None)), + } + } + + async fn list_resource_templates( + &self, + _request: Option, + _: RequestContext, + ) -> Result { + Ok(ListResourceTemplatesResult { + next_cursor: None, + resource_templates: Vec::new(), + }) + } + + async fn initialize( + &self, + _request: InitializeRequestParam, + context: RequestContext, + ) -> Result { + if let Some(http_request_part) = context.extensions.get::() { + let initialize_headers = &http_request_part.headers; + let initialize_uri = &http_request_part.uri; + tracing::info!(?initialize_headers, %initialize_uri, "initialize from http server"); + } + Ok(self.get_info()) + } +} \ No newline at end of file diff --git a/src/handlers/model_context.rs b/src/handlers/model_context.rs new file mode 100644 index 0000000..305ec09 --- /dev/null +++ b/src/handlers/model_context.rs @@ -0,0 +1,185 @@ +use axum::response::Response; +use axum::{ + body::Body, extract::Json, http::StatusCode, response::IntoResponse, +}; +use bytes::Bytes; +use futures::stream::{Stream, StreamExt}; +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use std::pin::Pin; +use tokio::io::{AsyncBufReadExt, BufReader}; +use tokio::process::Command; + +use crate::utils::utils::run_agent; + +// Custom function to format streaming responses according to OpenAI API format +pub fn openai_stream_format( + reader: BufReader, + request_id: String, + model: String, +) -> Pin> + Send>> +where + R: tokio::io::AsyncRead + Unpin + Send + 'static, +{ + let stream = futures::stream::unfold((reader, 0), move |(mut reader, index)| { + let request_id = request_id.clone(); + let model = model.clone(); + async move { + let mut line = String::new(); + match reader.read_line(&mut line).await { + Ok(0) => None, + Ok(_) => { + let content = line.trim(); + // Skip empty lines + if content.is_empty() { + return Some((Ok(Bytes::from("")), (reader, index))); + } + + // Format as OpenAI API streaming response + let chunk = serde_json::json!({ + "id": format!("chatcmpl-{}", request_id), + "object": "chat.completion.chunk", + "created": std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs(), + "model": model, + "choices": [{ + "index": index, + "delta": { + "content": content + }, + "finish_reason": null + }] + }); + + Some(( + Ok(Bytes::from(format!("data: {}\n\n", chunk.to_string()))), + (reader, index), + )) + } + Err(e) => Some((Err(e), (reader, index))), + } + } + }); + + // Add the [DONE] message at the end + let stream_with_done = stream.filter(|result| { + futures::future::ready(match result { + Ok(bytes) => !bytes.is_empty(), + Err(_) => true, + }) + }).chain(futures::stream::once(async { + Ok(Bytes::from("data: [DONE]\n\n")) + })); + + Box::pin(stream_with_done) +} + +#[derive(Deserialize, Debug)] +pub struct ModelContextRequest { + messages: Vec, + model: Option, + stream: Option, + temperature: Option, + max_tokens: Option, +} + +#[derive(Deserialize, Serialize, Debug)] +pub struct Message { + role: String, + content: String, +} + +#[derive(Serialize, Debug)] +pub struct ModelContextResponse { + id: String, + object: String, + created: u64, + model: String, + choices: Vec, +} + +#[derive(Serialize, Debug)] +pub struct Choice { + index: u32, + message: Message, + finish_reason: String, +} + +pub async fn model_context( + headers: axum::http::HeaderMap, + Json(payload): Json +) -> impl IntoResponse { + // Generate a unique ID for this request + let request_id = uuid::Uuid::new_v4().to_string(); + + // Convert messages to a format that can be passed to the agent + let input = serde_json::to_string(&payload.messages).unwrap_or_default(); + + // Use the web-search agent for now, but this could be customized based on the model parameter + let agent_file = "./packages/genaiscript/genaisrc/web-search.genai.mts"; + + tracing::debug!( + "Executing model context request - Id: {}", + request_id + ); + + // Default timeout of 60 seconds + let mut cmd = match run_agent(&request_id, &input, agent_file, 60).await { + Ok(cmd) => cmd, + Err(e) => { + tracing::error!("Model context execution failed: {}", e); + return StatusCode::INTERNAL_SERVER_ERROR.into_response(); + } + }; + + // Check if streaming is requested either via the stream parameter or Accept header + let accept_header = headers.get("accept").and_then(|h| h.to_str().ok()).unwrap_or(""); + let is_streaming = payload.stream.unwrap_or(false) || accept_header.contains("text/event-stream"); + + // If streaming is requested, return a streaming response + if is_streaming { + let stdout = match cmd.stdout.take() { + Some(stdout) => stdout, + None => { + tracing::error!("No stdout available for the command."); + return StatusCode::INTERNAL_SERVER_ERROR.into_response(); + } + }; + + let reader = BufReader::new(stdout); + let model = payload.model.clone().unwrap_or_else(|| "default-model".to_string()); + let sse_stream = openai_stream_format(reader, request_id.clone(), model); + + return Response::builder() + .header("Content-Type", "text/event-stream") + .header("Cache-Control", "no-cache, no-transform") + .header("Connection", "keep-alive") + .header("X-Accel-Buffering", "yes") + .body(Body::from_stream(sse_stream)) + .unwrap(); + } else { + // For non-streaming responses, we need to collect all output and return it as a single response + // This is a simplified implementation and might need to be adjusted based on actual requirements + let response = ModelContextResponse { + id: format!("chatcmpl-{}", request_id), + object: "chat.completion".to_string(), + created: std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs(), + model: payload.model.unwrap_or_else(|| "default-model".to_string()), + choices: vec![Choice { + index: 0, + message: Message { + role: "assistant".to_string(), + content: "This is a placeholder response. The actual implementation would process the agent's output.".to_string(), + }, + finish_reason: "stop".to_string(), + }], + }; + + return Json(response).into_response(); + } +} diff --git a/src/handlers/models.rs b/src/handlers/models.rs new file mode 100644 index 0000000..06a46b5 --- /dev/null +++ b/src/handlers/models.rs @@ -0,0 +1,48 @@ +use axum::{ + extract::Json, + response::IntoResponse, +}; +use serde::{Deserialize, Serialize}; +use std::time::{SystemTime, UNIX_EPOCH}; + +#[derive(Serialize, Debug)] +pub struct ModelsResponse { + object: String, + data: Vec, +} + +#[derive(Serialize, Debug)] +pub struct Model { + id: String, + object: String, + created: u64, + owned_by: String, +} + +pub async fn list_models() -> impl IntoResponse { + let current_time = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs(); + + // Create a response with a default model + let response = ModelsResponse { + object: "list".to_string(), + data: vec![ + Model { + id: "gpt-3.5-turbo".to_string(), + object: "model".to_string(), + created: current_time, + owned_by: "open-web-agent-rs".to_string(), + }, + Model { + id: "gpt-4".to_string(), + object: "model".to_string(), + created: current_time, + owned_by: "open-web-agent-rs".to_string(), + }, + ], + }; + + Json(response) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index b3316f4..f695551 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ mod setup; mod handlers; mod agents; mod utils; +mod counter; #[tokio::main] async fn main() { diff --git a/src/routes.rs b/src/routes.rs index 000a700..a2b7259 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -1,17 +1,25 @@ -use crate::handlers::agents::create_agent; -use crate::handlers::{not_found::handle_not_found, ui::serve_ui, agents::use_agent}; -use axum::routing::post; +use crate::handlers::{not_found::handle_not_found, ui::serve_ui}; use axum::routing::{get, Router}; use tower_http::trace::{self, TraceLayer}; use tracing::Level; +use rmcp::transport::streamable_http_server::{ + StreamableHttpService, session::local::LocalSessionManager, +}; +use crate::counter::Counter; + pub fn create_router() -> Router { + + let service = StreamableHttpService::new( + Counter::new, + LocalSessionManager::default().into(), + Default::default(), + ); + + Router::new() + .nest_service("/mcp", service) .route("/", get(serve_ui)) - // create an agent - .route("/api/agents", post(create_agent)) - // connect the agent - .route("/agents/:agent_id", get(use_agent)) .route("/health", get(health)) .layer( TraceLayer::new_for_http()