Skip to content

Commit a3d1040

Browse files
committed
refactor: split streaming, remove some features to decrease size
1 parent bb6f121 commit a3d1040

11 files changed

Lines changed: 51 additions & 90 deletions

File tree

CONTRIBUTING.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ cd perplexity-web-api-mcp
2525
cargo build --workspace --all-targets
2626
```
2727

28+
To build the optimized MCP binary directly:
29+
30+
- `cargo build --profile dist --bin perplexity-web-api-mcp` builds the smaller `stdio`-only binary.
31+
- `cargo build --profile dist --bin perplexity-web-api-mcp --features streamable-http` enables the optional Streamable HTTP transport.
32+
2833
#### Windows
2934

3035
Building on Windows requires additional tools because this project depends on BoringSSL (via the `rquest` crate).

Cargo.lock

Lines changed: 0 additions & 63 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ license = "MIT"
1515
[workspace.dependencies]
1616
perplexity-web-api = { path = "crates/perplexity-web-api" }
1717

18-
tokio = { version = "1.51.0", features = ["rt-multi-thread", "macros", "net"] }
19-
rquest = { version = "5.1.0", features = [
18+
tokio = { version = "1.51.0", features = ["rt", "macros", "net"] }
19+
rquest = { version = "5.1.0", default-features = false, features = [
20+
"webpki-roots",
2021
"cookies",
2122
"json",
2223
"stream",
2324
"multipart",
2425
] }
25-
rquest-util = "2.2.1"
26+
rquest-util = { version = "2.2.1", default-features = false, features = ["emulation"] }
2627
serde = { version = "1.0.228", features = ["derive"] }
2728
serde_json = "1.0.149"
2829
uuid = { version = "1.23.0", features = ["v4"] }
@@ -34,16 +35,16 @@ regex-lite = "0.1.9"
3435
base64 = "0.22"
3536
thiserror = "2.0.18"
3637
pin-project-lite = "0.2.17"
37-
rmcp = { version = "1.3.0", features = [
38+
rmcp = { version = "1.3.0", default-features = false, features = [
3839
"server",
3940
"macros",
4041
"transport-io",
4142
"schemars",
4243
] }
43-
axum = "0.8.8"
44+
axum = { version = "0.8.8", default-features = false, features = ["tokio", "http1"] }
4445
schemars = "1.2.1"
4546
tracing = "0.1.44"
46-
tracing-subscriber = { version = "0.3.23", features = ["env-filter"] }
47+
tracing-subscriber = { version = "0.3.23", default-features = false, features = ["fmt"] }
4748

4849
[workspace.lints.rust]
4950
unreachable_pub = "warn"

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ RUN apt-get update && apt-get install -y cmake clang && rm -rf /var/lib/apt/list
55
WORKDIR /app
66
COPY . .
77

8-
RUN cargo build --profile dist --bin perplexity-web-api-mcp
8+
RUN cargo build --profile dist --bin perplexity-web-api-mcp --features streamable-http
99

1010
FROM gcr.io/distroless/cc-debian12
1111

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ I recommend using the one-click install badge at the top of this README for VS C
153153
codex mcp add perplexity --env PERPLEXITY_SESSION_TOKEN="your-session-token" --env PERPLEXITY_CSRF_TOKEN="your-csrf-token" -- npx -y perplexity-web-api-mcp
154154
```
155155

156+
### Building from Source
157+
158+
Source build instructions, including optional cargo features, are documented in [CONTRIBUTING.md](CONTRIBUTING.md).
159+
156160
### Other MCP Clients
157161

158162
Most clients can be manually configured to use the `mcpServers` wrapper in their configuration file (like Cursor). If your client doesn't work, check its documentation for the correct wrapper format.
@@ -170,6 +174,7 @@ docker run -d \
170174
```
171175

172176
The container exposes the MCP server via Streamable HTTP at `http://localhost:8080/mcp`.
177+
The Docker image is built with `--features streamable-http`; local/source builds need the same feature if you want HTTP transport.
173178

174179
Configure your MCP client to connect:
175180

@@ -187,7 +192,7 @@ Configure your MCP client to connect:
187192

188193
| Variable | Default | Description |
189194
|----------|---------|-------------|
190-
| `MCP_TRANSPORT` | `streamable-http` | Transport mode. `stdio` or `streamable-http` |
195+
| `MCP_TRANSPORT` | `streamable-http` | Transport mode. `stdio` or `streamable-http` (requires the `streamable-http` cargo feature) |
191196
| `MCP_HOST` | `0.0.0.0` | Host address to bind |
192197
| `MCP_PORT` | `8080` | Port to listen on |
193198

crates/perplexity-web-api-mcp/Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@ keywords = { workspace = true }
1212
name = "perplexity-web-api-mcp"
1313
path = "src/main.rs"
1414

15+
[features]
16+
default = []
17+
streamable-http = ["dep:axum", "rmcp/transport-streamable-http-server"]
18+
1519
[dependencies]
1620
perplexity-web-api = { workspace = true, features = ["schemars"] }
1721

1822
tokio = { workspace = true, features = ["signal"] }
19-
rmcp = { workspace = true, features = ["transport-streamable-http-server"] }
20-
axum = { workspace = true }
23+
rmcp = { workspace = true }
24+
axum = { workspace = true, optional = true }
2125
serde = { workspace = true }
2226
serde_json = { workspace = true }
2327
base64 = { workspace = true }

crates/perplexity-web-api-mcp/src/main.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@
33
mod server;
44

55
use perplexity_web_api::{AuthCookies, Client, ReasonModel, SearchModel};
6-
use rmcp::{
7-
ServiceExt,
8-
transport::{
9-
stdio,
10-
streamable_http_server::{StreamableHttpService, session::local::LocalSessionManager},
11-
},
12-
};
6+
use rmcp::{ServiceExt, transport::stdio};
137
use std::{env, env::VarError};
14-
use tracing_subscriber::{EnvFilter, fmt};
8+
use tracing_subscriber::fmt;
159

1610
use crate::server::PerplexityServer;
1711

12+
#[cfg(feature = "streamable-http")]
13+
use rmcp::transport::streamable_http_server::{
14+
StreamableHttpService, session::local::LocalSessionManager,
15+
};
16+
1817
#[cfg(unix)]
1918
async fn shutdown_signal() {
2019
use tokio::signal::unix::{SignalKind, signal};
@@ -80,13 +79,11 @@ where
8079
}
8180
}
8281

83-
#[tokio::main]
82+
#[tokio::main(flavor = "current_thread")]
8483
async fn main() -> Result<(), Box<dyn std::error::Error>> {
8584
// Initialize tracing (logs to stderr to not interfere with stdio transport)
8685
fmt()
87-
.with_env_filter(
88-
EnvFilter::from_default_env().add_directive(tracing::Level::INFO.into()),
89-
)
86+
.with_max_level(tracing::Level::INFO)
9087
.with_writer(std::io::stderr)
9188
.with_ansi(false)
9289
.init();
@@ -166,6 +163,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
166163
}
167164
}
168165
}
166+
#[cfg(feature = "streamable-http")]
169167
"streamable-http" => {
170168
let host = optional_env("MCP_HOST")?.unwrap_or_else(|| "0.0.0.0".to_owned());
171169
let port = optional_env("MCP_PORT")?.unwrap_or_else(|| "8080".to_owned());
@@ -182,9 +180,20 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
182180
tracing::info!("MCP server listening on http://{addr}/mcp");
183181
axum::serve(listener, app).with_graceful_shutdown(shutdown_signal()).await?;
184182
}
183+
#[cfg(not(feature = "streamable-http"))]
184+
"streamable-http" => {
185+
return Err(std::io::Error::other(
186+
"MCP_TRANSPORT=streamable-http requires building with the `streamable-http` cargo feature",
187+
)
188+
.into());
189+
}
185190
other => {
191+
#[cfg(feature = "streamable-http")]
192+
let valid_values = "'stdio', 'streamable-http'";
193+
#[cfg(not(feature = "streamable-http"))]
194+
let valid_values = "'stdio'";
186195
return Err(std::io::Error::other(format!(
187-
"Unknown MCP_TRANSPORT value: '{other}'. Valid values: 'stdio', 'streamable-http'"
196+
"Unknown MCP_TRANSPORT value: '{other}'. Valid values: {valid_values}"
188197
))
189198
.into());
190199
}

crates/perplexity-web-api/examples/basic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
use perplexity_web_api::{Client, SearchRequest, Source};
66

7-
#[tokio::main]
7+
#[tokio::main(flavor = "current_thread")]
88
async fn main() -> perplexity_web_api::Result<()> {
99
println!("Creating Perplexity client...");
1010

crates/perplexity-web-api/examples/streaming.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use futures_util::StreamExt;
66
use perplexity_web_api::{Client, SearchRequest};
77

8-
#[tokio::main]
8+
#[tokio::main(flavor = "current_thread")]
99
async fn main() -> perplexity_web_api::Result<()> {
1010
println!("Creating Perplexity client...");
1111

crates/perplexity-web-api/examples/with_cookies.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
use perplexity_web_api::{AuthCookies, Client, SearchMode, SearchModel, SearchRequest};
66

7-
#[tokio::main]
7+
#[tokio::main(flavor = "current_thread")]
88
async fn main() -> perplexity_web_api::Result<()> {
99
println!("=== Authenticated Usage Example ===\n");
1010

0 commit comments

Comments
 (0)