Skip to content

Commit 2d8a2bd

Browse files
feat(mcp): logs on stderr, improve args (#2083)
* wip: improve mcp server * typo Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * nit --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
1 parent 9bac83c commit 2d8a2bd

File tree

9 files changed

+29
-23
lines changed

9 files changed

+29
-23
lines changed

Cargo.lock

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

cargo-shuttle/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ pub fn parse_args() -> (ShuttleArgs, bool) {
103103

104104
pub fn setup_tracing(debug: bool) {
105105
registry()
106-
.with(fmt::layer())
106+
.with(fmt::layer().with_writer(std::io::stderr))
107107
.with(
108108
// let user set RUST_LOG if they want to
109109
EnvFilter::try_from_default_env().unwrap_or_else(|_| {

mcp/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ rmcp = { workspace = true, features = ["server", "transport-io", "macros"] }
1313
schemars = { workspace = true }
1414
serde = { workspace = true }
1515
tokio = { workspace = true, features = ["full"] }
16+
tracing = { workspace = true }
1617
urlencoding = { workspace = true }

mcp/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ mod tools;
88
mod utils;
99

1010
pub async fn run_mcp_server() -> Result<(), anyhow::Error> {
11+
tracing::info!("Starting Shuttle MCP server...");
1112
let service = ShuttleMcpServer::new().serve(stdio()).await?;
13+
tracing::info!("Started Shuttle MCP server!");
1214
service.waiting().await?;
1315
Ok(())
1416
}

mcp/src/mcp.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
use crate::tools::{deployment::*, docs::*, logs::*, project::*};
2-
use crate::utils::run_tool;
31
use rmcp::{
42
handler::server::{tool::ToolRouter, wrapper::Parameters},
53
model::{ServerCapabilities, ServerInfo},
64
tool, tool_handler, tool_router, ServerHandler,
75
};
6+
use tracing::instrument;
87

9-
#[derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
8+
use crate::tools::{deployment::*, docs::*, logs::*, project::*};
9+
use crate::utils::run_tool;
10+
11+
#[derive(Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
1012
struct SearchDocsArgs {
1113
#[schemars(description = "Search query for documentation")]
1214
query: String,
@@ -27,11 +29,13 @@ impl ShuttleMcpServer {
2729

2830
#[tool_router]
2931
impl ShuttleMcpServer {
32+
#[instrument(skip(self))]
3033
#[tool(description = "Deploy a project")]
3134
async fn deploy(&self, Parameters(args): Parameters<DeployArgs>) -> Result<String, String> {
3235
run_tool(deploy(args)).await
3336
}
3437

38+
#[instrument(skip(self))]
3539
#[tool(description = "List the deployments for a service")]
3640
async fn deployment_list(
3741
&self,
@@ -40,6 +44,7 @@ impl ShuttleMcpServer {
4044
run_tool(deployment_list(args)).await
4145
}
4246

47+
#[instrument(skip(self))]
4348
#[tool(description = "View status of a deployment")]
4449
async fn deployment_status(
4550
&self,
@@ -48,11 +53,13 @@ impl ShuttleMcpServer {
4853
run_tool(deployment_status(args)).await
4954
}
5055

56+
#[instrument(skip(self))]
5157
#[tool(description = "View build and deployment logs")]
5258
async fn logs(&self, Parameters(args): Parameters<LogsArgs>) -> Result<String, String> {
5359
run_tool(logs(args)).await
5460
}
5561

62+
#[instrument(skip(self))]
5663
#[tool(description = "Get the status of this project on Shuttle")]
5764
async fn project_status(
5865
&self,
@@ -61,14 +68,13 @@ impl ShuttleMcpServer {
6168
run_tool(project_status(args)).await
6269
}
6370

71+
#[instrument(skip(self))]
6472
#[tool(description = "List all projects you have access to")]
65-
async fn project_list(
66-
&self,
67-
Parameters(args): Parameters<ProjectListArgs>,
68-
) -> Result<String, String> {
69-
run_tool(project_list(args)).await
73+
async fn project_list(&self) -> Result<String, String> {
74+
run_tool(project_list()).await
7075
}
7176

77+
#[instrument(skip(self))]
7278
#[tool(description = "Search Shuttle documentation")]
7379
async fn search_docs(
7480
&self,
@@ -80,6 +86,7 @@ impl ShuttleMcpServer {
8086

8187
#[tool_handler]
8288
impl ServerHandler for ShuttleMcpServer {
89+
#[instrument(skip(self))]
8390
fn get_info(&self) -> ServerInfo {
8491
ServerInfo {
8592
instructions: Some(

mcp/src/tools/deployment.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::utils::execute_command;
22

3-
#[derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
3+
#[derive(Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
44
pub struct DeployArgs {
55
#[schemars(description = "Specify the working directory")]
66
cwd: String,
@@ -12,7 +12,7 @@ pub struct DeployArgs {
1212
project_id: Option<String>,
1313
}
1414

15-
#[derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
15+
#[derive(Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
1616
pub struct DeploymentListArgs {
1717
#[schemars(description = "Specify the working directory")]
1818
cwd: String,
@@ -26,7 +26,7 @@ pub struct DeploymentListArgs {
2626
project_id: Option<String>,
2727
}
2828

29-
#[derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
29+
#[derive(Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
3030
pub struct DeploymentStatusArgs {
3131
#[schemars(description = "Specify the working directory")]
3232
cwd: String,

mcp/src/tools/logs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::utils::execute_command;
22

3-
#[derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
3+
#[derive(Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
44
pub struct LogsArgs {
55
#[schemars(description = "Specify the working directory")]
66
cwd: String,

mcp/src/tools/project.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::utils::execute_command;
22

3-
#[derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
3+
#[derive(Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
44
pub struct ProjectStatusArgs {
55
#[schemars(description = "Specify the working directory")]
66
cwd: String,
@@ -10,12 +10,6 @@ pub struct ProjectStatusArgs {
1010
project_id: Option<String>,
1111
}
1212

13-
#[derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
14-
pub struct ProjectListArgs {
15-
#[schemars(description = "Specify the working directory")]
16-
cwd: String,
17-
}
18-
1913
pub async fn project_status(params: ProjectStatusArgs) -> Result<String, String> {
2014
let mut args = vec!["project".to_string(), "status".to_string()];
2115

@@ -32,8 +26,8 @@ pub async fn project_status(params: ProjectStatusArgs) -> Result<String, String>
3226
execute_command("shuttle", args, &params.cwd).await
3327
}
3428

35-
pub async fn project_list(params: ProjectListArgs) -> Result<String, String> {
29+
pub async fn project_list() -> Result<String, String> {
3630
let args = vec!["project".to_string(), "list".to_string()];
3731

38-
execute_command("shuttle", args, &params.cwd).await
32+
execute_command("shuttle", args, ".").await
3933
}

mcp/src/utils.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::future::Future;
22

33
use reqwest::header::{HeaderMap, ORIGIN, USER_AGENT};
44
use tokio::process::Command;
5+
use tracing::debug;
56

67
pub async fn execute_command(
78
command: &str,
@@ -33,7 +34,7 @@ pub async fn run_tool<F>(tool: F) -> Result<String, String>
3334
where
3435
F: Future<Output = Result<String, String>>,
3536
{
36-
// Placeholder for running logic before/after every tool
37+
debug!("Running tool"); // Instrument span wraps the event to display the tool name
3738
tool.await
3839
}
3940

0 commit comments

Comments
 (0)