-
Notifications
You must be signed in to change notification settings - Fork 17
vscode & Roo Code support -- sessionId= is required #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 4 commits
05c1878
1e287a7
30545c1
d92a961
faa44e7
304ff1d
4afe1e7
9042d01
f891b41
04aeafd
e98ed75
96442c1
34f5e7a
f37981e
ae1fc42
fd18fe7
fc3f2f9
b2df171
579f0c1
58b7680
a13d2be
948a515
ac46dde
5e5ba5a
c48014e
a9b7fb2
78da690
df250b4
c2ce396
e01c38e
9e780c6
9eb42c1
c7fc89c
344dfe4
9584b65
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| install: | ||
| cargo install --git https://github.com/PromptExecution/cratedocs-mcp --locked | ||
|
|
||
| run: | ||
| cargo run --bin cratedocs http --address 0.0.0.0:3000 --debug | ||
|
|
||
| debug-mcp-remote: | ||
| # use bunx or npx to see how the mcp-remote proxy connects | ||
| bunx mcp-remote@latest "http://127.0.0.1:3000/sse" --allow-http --transport sse-only --debug | ||
|
|
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -52,47 +52,112 @@ fn session_id() -> SessionId { | |||||||||||
| #[derive(Debug, serde::Deserialize)] | ||||||||||||
| #[serde(rename_all = "camelCase")] | ||||||||||||
| pub struct PostEventQuery { | ||||||||||||
| pub session_id: String, | ||||||||||||
| #[serde(default)] // Use None if session_id is not present in query | ||||||||||||
| pub session_id: Option<String>, | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| async fn post_event_handler( | ||||||||||||
| State(app): State<App>, | ||||||||||||
| Query(PostEventQuery { session_id }): Query<PostEventQuery>, | ||||||||||||
| Query(query_params): Query<PostEventQuery>, | ||||||||||||
| body: Body, | ||||||||||||
| ) -> Result<StatusCode, StatusCode> { | ||||||||||||
| tracing::debug!(?query_params, "Received POST request"); | ||||||||||||
| const BODY_BYTES_LIMIT: usize = 1 << 22; | ||||||||||||
| let write_stream = { | ||||||||||||
| let rg = app.txs.read().await; | ||||||||||||
| rg.get(session_id.as_str()) | ||||||||||||
| .ok_or(StatusCode::NOT_FOUND)? | ||||||||||||
| .clone() | ||||||||||||
| }; | ||||||||||||
| let mut write_stream = write_stream.lock().await; | ||||||||||||
| let mut body = body.into_data_stream(); | ||||||||||||
| if let (_, Some(size)) = body.size_hint() { | ||||||||||||
| if size > BODY_BYTES_LIMIT { | ||||||||||||
| const BUFFER_SIZE: usize = 1 << 12; // For new sessions | ||||||||||||
|
|
||||||||||||
| let (session_id_arc, c2s_writer_for_body): (SessionId, C2SWriter) = | ||||||||||||
| match query_params.session_id { | ||||||||||||
| Some(id_str) => { | ||||||||||||
| tracing::debug!(session_id = %id_str, "sessionId provided in query"); | ||||||||||||
| // Convert String to Arc<str> for map lookup | ||||||||||||
| let session_arc: SessionId = Arc::from(id_str.as_str()); | ||||||||||||
| let rg = app.txs.read().await; | ||||||||||||
| match rg.get(&session_arc) { | ||||||||||||
| Some(writer) => { | ||||||||||||
| tracing::debug!(session_id = %session_arc, "Found existing session writer"); | ||||||||||||
| (session_arc, writer.clone()) | ||||||||||||
| } | ||||||||||||
| None => { | ||||||||||||
| tracing::warn!(session_id = %session_arc, "sessionId provided but not found in active sessions"); | ||||||||||||
| return Err(StatusCode::NOT_FOUND); | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| None => { | ||||||||||||
| tracing::info!("sessionId not provided, creating new session for POST request"); | ||||||||||||
| let new_session_id_arc = session_id(); // fn session_id() -> Arc<str> | ||||||||||||
| tracing::info!(new_session_id = %new_session_id_arc, "Generated new session ID"); | ||||||||||||
|
|
||||||||||||
| let (c2s_read, c2s_write_half) = tokio::io::simplex(BUFFER_SIZE); | ||||||||||||
| // s2c_read/write are also needed for the ByteTransport and Server::run | ||||||||||||
| // _s2c_read is not directly used by this POST handler but needed for the spawned server task. | ||||||||||||
| let (_s2c_read, s2c_write_half) = tokio::io::simplex(BUFFER_SIZE); | ||||||||||||
|
|
||||||||||||
| let new_c2s_writer_for_map = Arc::new(Mutex::new(c2s_write_half)); | ||||||||||||
| app.txs | ||||||||||||
| .write() | ||||||||||||
| .await | ||||||||||||
| .insert(new_session_id_arc.clone(), new_c2s_writer_for_map.clone()); | ||||||||||||
| tracing::info!(session_id = %new_session_id_arc, "Inserted new session writer into app.txs"); | ||||||||||||
|
|
||||||||||||
| // Spawn the server task for the new session | ||||||||||||
| let app_clone = app.clone(); | ||||||||||||
| let task_session_id = new_session_id_arc.clone(); | ||||||||||||
| tokio::spawn(async move { | ||||||||||||
| let router = RouterService(DocRouter::new()); | ||||||||||||
|
||||||||||||
| let router = RouterService(DocRouter::new()); | |
| // Retrieve tldr and max_tokens from app_clone or config | |
| let tldr = app_clone.tldr; | |
| let max_tokens = app_clone.max_tokens; | |
| let router = RouterService(DocRouter::with_config(tldr, max_tokens)); |
Copilot
AI
Nov 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The automatic session creation feature (when sessionId is not provided) could be exploited for resource exhaustion. Each POST without a sessionId spawns a new server task and allocates buffers. Consider implementing rate limiting, maximum concurrent sessions per IP, or requiring authentication for session creation to prevent abuse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The URL parameter in the example shows
sessionId=with no value. According to the code changes, sessionId is now optional and should either be omitted entirely or have a value. The empty valuesessionId=may cause parsing issues. Update the example to either removesessionId=or provide a placeholder value likesessionId=abc123.