Skip to content
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

feat: allow for multiple values in cli options for adding extensions #1070

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
12 changes: 6 additions & 6 deletions crates/goose-cli/src/commands/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use mcp_client::transport::Error as McpClientError;
pub async fn build_session(
name: Option<String>,
resume: bool,
extension: Option<String>,
builtin: Option<String>,
extensions: Vec<String>,
builtins: Vec<String>,
) -> Session<'static> {
// Load config and get provider/model
let config = Config::global();
Expand Down Expand Up @@ -64,8 +64,8 @@ pub async fn build_session(
}
}

// Add extension if provided
if let Some(extension_str) = extension {
// Add extensions if provided
for extension_str in extensions {
let mut parts: Vec<&str> = extension_str.split_whitespace().collect();
let mut envs = std::collections::HashMap::new();

Expand Down Expand Up @@ -104,8 +104,8 @@ pub async fn build_session(
});
}

// Add builtin extension if provided
if let Some(name) = builtin {
// Add builtin extensions
for name in builtins {
let config = ExtensionConfig::Builtin { name };
agent.add_extension(config).await.unwrap_or_else(|e| {
eprintln!("Failed to start builtin extension: {}", e);
Expand Down
36 changes: 20 additions & 16 deletions crates/goose-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,25 @@ enum Command {
)]
resume: bool,

/// Add a stdio extension with environment variables and command
/// Add stdio extensions with environment variables and commands
#[arg(
long = "with-extension",
value_name = "COMMAND",
help = "Add a stdio extension (e.g., 'GITHUB_TOKEN=xyz npx -y @modelcontextprotocol/server-github')",
long_help = "Add a stdio extension from a full command with environment variables. Format: 'ENV1=val1 ENV2=val2 command args...'"
help = "Add stdio extensions (can be specified multiple times)",
long_help = "Add stdio extensions from full commands with environment variables. Can be specified multiple times. Format: 'ENV1=val1 ENV2=val2 command args...'",
action = clap::ArgAction::Append
)]
extension: Option<String>,
extension: Vec<String>,

/// Add a builtin extension by name
/// Add builtin extensions by name
#[arg(
long = "with-builtin",
value_name = "NAME",
help = "Add a builtin extension by name (e.g., 'developer')",
long_help = "Add a builtin extension that is bundled with goose by specifying its name"
help = "Add builtin extensions by name (e.g., 'developer' or multiple: 'developer,github')",
long_help = "Add one or more builtin extensions that are bundled with goose by specifying their names, comma-separated",
value_delimiter = ','
)]
builtin: Option<String>,
builtin: Vec<String>,
},

/// Execute commands from an instruction file
Expand Down Expand Up @@ -125,23 +127,25 @@ enum Command {
)]
resume: bool,

/// Add a stdio extension with environment variables and command
/// Add stdio extensions with environment variables and commands
#[arg(
long = "with-extension",
value_name = "COMMAND",
help = "Add a stdio extension with environment variables and command (e.g., 'GITHUB_TOKEN=xyz npx -y @modelcontextprotocol/server-github')",
long_help = "Add a stdio extension with environment variables and command. Format: 'ENV1=val1 ENV2=val2 command args...'"
help = "Add stdio extensions (can be specified multiple times)",
long_help = "Add stdio extensions from full commands with environment variables. Can be specified multiple times. Format: 'ENV1=val1 ENV2=val2 command args...'",
action = clap::ArgAction::Append
)]
extension: Option<String>,
extension: Vec<String>,

/// Add a builtin extension by name
/// Add builtin extensions by name
#[arg(
long = "with-builtin",
value_name = "NAME",
help = "Add a builtin extension by name (e.g., 'developer')",
long_help = "Add a builtin extension that is compiled into goose by specifying its name"
help = "Add builtin extensions by name (e.g., 'developer' or multiple: 'developer,github')",
long_help = "Add one or more builtin extensions that are bundled with goose by specifying their names, comma-separated",
value_delimiter = ','
)]
builtin: Option<String>,
builtin: Vec<String>,
},

/// List available agent versions
Expand Down
10 changes: 9 additions & 1 deletion documentation/docs/getting-started/using-extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ You can remove installed extensions.
You can start a tailored goose session with specific extensions directly from the CLI. To do this, run the following command:

```bash
goose session --with-extension "{extension command}"
goose session --with-extension "{extension command}" --with-extension "{antoher extension command}"
```

:::info
Expand All @@ -261,6 +261,14 @@ goose session --with-extension "VAR=value command arg1 arg2"
```
:::

:::tip
You can also start a session with built-in extensions by using the `--with-builtin` flag.
```bash
goose session --with-builtin "developer,memory"
goose session --with-builtin developer --with-builtin memory
```
:::

## Developing Extensions
Goose extensions are implemented with MCP, a standard protocol that allows AI models and agents to securely connect with local or remote resources. Learn how to build your own [extension as an MCP server](https://modelcontextprotocol.io/quickstart/server).

Expand Down
Loading