Repository navigation
Expand file tree
/
Copy pathCargo.toml
More file actions
143 lines (136 loc) · 5.72 KB
/
Copy pathCargo.toml
File metadata and controls
143 lines (136 loc) · 5.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
[package]
name = "imcp2"
version = "0.6.1"
edition = "2021"
description = "Minimal MCP server that bridges an LLM to the Internet Computer, speaking textual Candid."
license = "Apache-2.0"
readme = "README.md"
repository = "https://github.com/dfinity/imcp2"
# The hosted deployment of this crate, not the repository: crates.io renders
# `homepage` and `repository` as separate links, so pointing both at GitHub
# wastes one. This is where a reader can actually connect an MCP client.
homepage = "https://mcp.internetcomputer.org"
keywords = ["mcp", "internet-computer", "icp", "candid", "axum"]
categories = [
"network-programming",
"web-programming::http-server",
"api-bindings",
]
# Everything the library and the bundled binary compile from ships; the
# deployment scaffolding (container, systemd/native deploy, dashboards, CI,
# submission docs) is repository-only and would just inflate the .crate.
# `src/assets` is NOT optional: it is pulled in at compile time with
# `include_str!`. `crates/` holds the other workspace members (each packaged
# on its own), so it is excluded from THIS package.
exclude = [
".github/",
".dockerignore",
"Dockerfile",
"crates/",
"deploy/",
"docs/",
"monitoring/",
]
[workspace]
members = [".", "crates/imcp2-core", "crates/imcp2-local"]
# The hosted server releases to crates.io (publish-crate.yml), never as dist
# binaries — dist releases only imcp2-local (see dist-workspace.toml).
[package.metadata.dist]
dist = false
# Single source of truth for the version pins the crates share, so the agent,
# codec, and candid lines can never drift between imcp2-core, imcp2, and
# imcp2-local.
[workspace.dependencies]
httpdate = "1.0.3"
imcp2-core = { path = "crates/imcp2-core", version = "0.6.1" }
rmcp = "2.1"
axum = "0.8"
anyhow = "1"
uuid = { version = "1", features = ["v4"] }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
# The Agent is INJECTED by the embedding application (see McpServer::new), so a
# host shares one boundary-node client and one ic-agent across the process.
# Deliberately a direct dependency for now: sourcing ic-agent through ic-bn-lib
# (the shared boundary-node/gateway crate, the eventual goal so the version is
# pinned by the same crate the hosts use) is deferred until ic-bn-lib releases
# against this ic-agent line — its current release pins an older one, which
# would revert the read-only delegation-permissions support this depends on.
ic-agent = "0.49"
# Floor at 0.10.31: earlier 0.10.x decode/encode large `Nat`/`Int` in O(n²), which
# a caller-influenced textual `Nat` under the 1 MiB guard turns into seconds of
# worker-blocking CPU (ICPBB-382); 0.10.31 made it O(n).
candid = { version = "0.10.31", features = ["value"] }
candid_parser = "0.3.2"
tokio = "1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tracing = "0.1"
sha2 = "0.11.0"
base64 = "0.22.1"
hex = "0.4.3"
crc32fast = "1"
regex = "1.12.4"
reqwest = { version = "0.13", default-features = false, features = ["rustls"] }
getrandom = "0.3.4"
urlencoding = "2.1.3"
url = "2"
http = "1"
[dependencies]
# The transport/OAuth-agnostic components (the tool surface, the II session
# engine, the connect-handshake primitives) live in imcp2-core; this crate adds
# the hosted composition: the OAuth 2.1 authorization server, the
# streamable-HTTP transport, and the axum routers.
imcp2-core = { workspace = true }
rmcp = { workspace = true, features = [
"server",
"macros",
"transport-streamable-http-server",
] }
ic-agent = { workspace = true }
candid = { workspace = true }
tokio = { workspace = true, features = ["macros", "rt-multi-thread", "signal", "time"] }
axum = { workspace = true }
anyhow = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
tokio-util = "0.7"
uuid = { workspace = true }
tower-http = { version = "0.7", features = ["cors"] }
# Metrics exposition at /metrics. Pinned to the version dfinity/ic uses: these
# series are destined for the same Prometheus / Victoria Metrics clusters that
# scrape the IC, so matching the org's client keeps one exposition dialect in the
# estate. The `process` feature adds CPU / RSS / file-descriptor collectors on
# Linux, which is the deploy target.
prometheus = { version = "0.14", features = ["process"] }
sha2 = { workspace = true }
base64 = { workspace = true }
hex = { workspace = true }
getrandom = { workspace = true }
urlencoding = { workspace = true }
url = { workspace = true }
# Only for the PocketIC-backed end-to-end test (src/e2e_handshake.rs), behind
# the `e2e` feature so the default build never compiles it. Client library for a
# local Internet Identity canister; version tracks the `pocket-ic` server binary.
pocket-ic = { version = "15", optional = true }
[features]
# Compiles + enables the real II<>MCP handshake test against a live Internet
# Identity canister in PocketIC (needs II_WASM + POCKET_IC_BIN at runtime; see
# src/e2e_handshake.rs). Off by default: the standard `cargo test` neither
# builds `pocket-ic` nor touches the network.
e2e = ["dep:pocket-ic"]
[dev-dependencies]
# Router-level contract tests (tests/routers.rs) drive the composed app with
# tower::ServiceExt::oneshot and read bodies via http-body-util.
tower = { version = "0.5", features = ["util"] }
http-body-util = "0.1"
# `test-util` is what `#[tokio::test(start_paused = true)]` needs: the pending
# connect tests in `auth.rs` walk a connect past its TTL and retention on a
# paused clock instead of waiting them out. A feature on a dependency the crate
# already has, so the lockfile does not change.
tokio = { workspace = true, features = ["test-util"] }
# The profile that 'dist' will build with
[profile.dist]
inherits = "release"
lto = "thin"