diff --git a/crates/goose/src/acp/mcp_app_proxy.rs b/crates/goose/src/acp/mcp_app_proxy.rs index f1791e2566..cda7b56e32 100644 --- a/crates/goose/src/acp/mcp_app_proxy.rs +++ b/crates/goose/src/acp/mcp_app_proxy.rs @@ -1,5 +1,5 @@ use axum::{ - extract::{ConnectInfo, Query, State}, + extract::{ConnectInfo, DefaultBodyLimit, Query, State}, http::{header, HeaderValue, StatusCode}, response::{Html, IntoResponse, Response}, routing::{get, post}, @@ -16,6 +16,7 @@ use uuid::Uuid; const GUEST_HTML_TTL_SECS: u64 = 300; const GUEST_HTML_MAX_ENTRIES: usize = 64; +const GUEST_HTML_MAX_BYTES: usize = 8 * 1024 * 1024; const MCP_APP_PROXY_HTML: &str = include_str!("templates/mcp_app_proxy.html"); type GuestHtmlStore = Arc>>; @@ -382,14 +383,23 @@ pub(crate) fn routes(secret_key: String) -> Router { Router::new() .route("/mcp-app-proxy", get(mcp_app_proxy)) - .route("/mcp-app-guest", post(store_guest_html)) + .route( + "/mcp-app-guest", + post(store_guest_html).layer(DefaultBodyLimit::max(GUEST_HTML_MAX_BYTES)), + ) .with_state(state) } #[cfg(test)] mod tests { use super::{normalize_csp_source, parse_domains, peer_addr_is_loopback}; + use axum::{ + body::Body, + extract::ConnectInfo, + http::{header, Request, StatusCode}, + }; use std::net::SocketAddr; + use tower::ServiceExt; #[test] fn normalizes_url_sources_to_origins() { @@ -456,4 +466,29 @@ mod tests { &"192.168.1.10:12345".parse::().unwrap() )); } + + #[tokio::test] + async fn stores_guest_html_larger_than_default_body_limit() { + let app = super::routes("test-secret".to_string()); + let large_html = "x".repeat(3 * 1024 * 1024); + let body = serde_json::json!({ + "secret": "test-secret", + "html": large_html, + }) + .to_string(); + + let mut request = Request::builder() + .method("POST") + .uri("/mcp-app-guest") + .header(header::CONTENT_TYPE, "application/json") + .body(Body::from(body)) + .unwrap(); + request.extensions_mut().insert(ConnectInfo( + "127.0.0.1:12345".parse::().unwrap(), + )); + + let response = app.oneshot(request).await.unwrap(); + + assert_eq!(response.status(), StatusCode::OK); + } }