Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions crates/goose-cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use goose::config::Config;
use goose::posthog::get_telemetry_choice;
use goose::recipe::Recipe;
use goose_mcp::mcp_server_runner::{serve, McpCommand};
#[cfg(target_os = "macos")]
use goose_mcp::PeekabooServer;
use goose_mcp::{
AutoVisualiserRouter, ComputerControllerServer, DeveloperServer, MemoryServer, TutorialServer,
};
Expand Down Expand Up @@ -979,6 +981,12 @@ async fn handle_mcp_command(server: McpCommand) -> Result<()> {
McpCommand::Memory => serve(MemoryServer::new()).await?,
McpCommand::Tutorial => serve(TutorialServer::new()).await?,
McpCommand::Developer => serve(DeveloperServer::new()).await?,
#[cfg(target_os = "macos")]
McpCommand::Peekaboo => serve(PeekabooServer::new()).await?,
#[cfg(not(target_os = "macos"))]
McpCommand::Peekaboo => {
anyhow::bail!("Peekaboo is only available on macOS");
}
}
Ok(())
}
Expand Down
5 changes: 5 additions & 0 deletions crates/goose-cli/src/commands/configure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,11 @@ fn configure_builtin_extension() -> anyhow::Result<()> {
"Tutorial",
"Access interactive tutorials and guides",
),
(
"peekaboo",
"Peekaboo",
"macOS UI automation via annotated screenshots (auto-installs via Homebrew)",
),
Comment thread
michaelneale marked this conversation as resolved.
Outdated
];

let mut select = cliclack::select("Which built-in extension would you like to enable?");
Expand Down
1 change: 1 addition & 0 deletions crates/goose-mcp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ libc = "0.2"
# ~1000 downloads). Pinned to exact version to prevent supply chain attacks.
mpatch = "=0.2.0"
tokio-util = { workspace = true }
shell-words = "1.1.1"

[dev-dependencies]
serial_test = { workspace = true }
Expand Down
373 changes: 329 additions & 44 deletions crates/goose-mcp/src/computercontroller/mod.rs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions crates/goose-mcp/src/computercontroller/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub use self::macos::MacOSAutomation;
#[cfg(any(target_os = "linux", target_os = "android"))]
pub use self::linux::LinuxAutomation;

#[allow(dead_code)]
pub trait SystemAutomation: Send + Sync {
fn execute_system_script(&self, script: &str) -> std::io::Result<String>;
fn get_shell_command(&self) -> (&'static str, &'static str); // (shell, arg)
Expand Down
18 changes: 16 additions & 2 deletions crates/goose-mcp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
pub mod developer;
pub mod mcp_server_runner;
mod memory;
#[cfg(target_os = "macos")]
pub mod peekaboo;
pub mod subprocess;
pub mod tutorial;

Expand All @@ -22,6 +24,8 @@
pub use developer::rmcp_developer::DeveloperServer;
pub use developer::rmcp_developer::WORKING_DIR_PLACEHOLDER;
pub use memory::MemoryServer;
#[cfg(target_os = "macos")]
pub use peekaboo::PeekabooServer;
pub use tutorial::TutorialServer;

/// Type definition for a function that spawns and serves a builtin extension server
Expand Down Expand Up @@ -54,11 +58,21 @@
}

pub static BUILTIN_EXTENSIONS: Lazy<HashMap<&'static str, SpawnServerFn>> = Lazy::new(|| {
HashMap::from([
let mut map = HashMap::from([

Check failure on line 61 in crates/goose-mcp/src/lib.rs

View workflow job for this annotation

GitHub Actions / Lint Rust Code

variable does not need to be mutable

Check failure on line 61 in crates/goose-mcp/src/lib.rs

View workflow job for this annotation

GitHub Actions / Check OpenAPI Schema is Up-to-Date

variable does not need to be mutable

Check failure on line 61 in crates/goose-mcp/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build and Test Rust Project

variable does not need to be mutable

Check failure on line 61 in crates/goose-mcp/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build Binary

variable does not need to be mutable
builtin!(developer, DeveloperServer),
builtin!(autovisualiser, AutoVisualiserRouter),
builtin!(computercontroller, ComputerControllerServer),
builtin!(memory, MemoryServer),
builtin!(tutorial, TutorialServer),
])
]);

#[cfg(target_os = "macos")]
{
map.insert(
builtin!(peekaboo, PeekabooServer).0,
builtin!(peekaboo, PeekabooServer).1,
);
}

Copilot AI Feb 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

builtin!(peekaboo, PeekabooServer) is invoked twice here and the key and value come from different macro expansions, which is easy to misread and makes future edits error-prone; bind the tuple once (e.g., let (k, v) = ...) and insert it.

Suggested change
map.insert(
builtin!(peekaboo, PeekabooServer).0,
builtin!(peekaboo, PeekabooServer).1,
);
}
let peekaboo = builtin!(peekaboo, PeekabooServer);
map.insert(peekaboo.0, peekaboo.1);
}

Copilot uses AI. Check for mistakes.
map
});
3 changes: 3 additions & 0 deletions crates/goose-mcp/src/mcp_server_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub enum McpCommand {
ComputerController,
Developer,
Memory,
Peekaboo,
Tutorial,
}

Expand All @@ -21,6 +22,7 @@ impl FromStr for McpCommand {
"computercontroller" => Ok(McpCommand::ComputerController),
"developer" => Ok(McpCommand::Developer),
"memory" => Ok(McpCommand::Memory),
"peekaboo" => Ok(McpCommand::Peekaboo),
"tutorial" => Ok(McpCommand::Tutorial),
_ => Err(format!("Invalid command: {}", s)),
}
Expand All @@ -34,6 +36,7 @@ impl McpCommand {
McpCommand::ComputerController => "computercontroller",
McpCommand::Developer => "developer",
McpCommand::Memory => "memory",
McpCommand::Peekaboo => "peekaboo",
McpCommand::Tutorial => "tutorial",
}
}
Expand Down
Loading
Loading