feat(goose): auto add mcp server to goose configuration when starting a session

This commit is contained in:
2025-03-25 23:48:08 +01:00
parent 16f59b1c40
commit 7805aa720e
3 changed files with 158 additions and 1 deletions

View File

@@ -37,11 +37,12 @@ COPY mc-init.sh /mc-init.sh
COPY entrypoint.sh /entrypoint.sh
COPY mc-driver.yaml /mc-driver.yaml
COPY init-status.sh /init-status.sh
COPY update-goose-config.sh /usr/local/bin/update-goose-config.sh
# Extend env via bashrc
# Make scripts executable
RUN chmod +x /mc-init.sh /entrypoint.sh /init-status.sh
RUN chmod +x /mc-init.sh /entrypoint.sh /init-status.sh /usr/local/bin/update-goose-config.sh
# Set up initialization status check on login
RUN echo 'export PATH=/root/.local/bin:$PATH' >> /etc/bash.bashrc

View File

@@ -54,6 +54,17 @@ if [ -n "$LANGFUSE_INIT_PROJECT_SECRET_KEY" ] && [ -n "$LANGFUSE_INIT_PROJECT_PU
export LANGFUSE_URL="${LANGFUSE_URL:-https://cloud.langfuse.com}"
fi
# Update Goose configuration with available MCP servers
if [ -f "/usr/local/bin/update-goose-config.sh" ]; then
echo "Updating Goose configuration with MCP servers..."
bash /usr/local/bin/update-goose-config.sh
elif [ -f "$(dirname "$0")/update-goose-config.sh" ]; then
echo "Updating Goose configuration with MCP servers..."
bash "$(dirname "$0")/update-goose-config.sh"
else
echo "Warning: update-goose-config.sh script not found. Goose configuration will not be updated."
fi
echo "MC driver initialization complete"
# Mark initialization as complete

View File

@@ -0,0 +1,145 @@
#!/bin/bash
# Script to update Goose configuration with MCP servers using Python standard library
# Define config path
GOOSE_CONFIG="$HOME/.config/goose/config.yaml"
CONFIG_DIR="$(dirname "$GOOSE_CONFIG")"
# Create config directory if it doesn't exist
mkdir -p "$CONFIG_DIR"
# Function to update config using Python without yaml module
update_config() {
python3 - << 'EOF'
import os
import json
import re
# Path to goose config
config_path = os.path.expanduser('~/.config/goose/config.yaml')
# Check if file exists, create if not
if not os.path.exists(config_path):
with open(config_path, 'w') as f:
f.write("extensions:\n")
# Read the entire file
with open(config_path, 'r') as f:
content = f.read()
# Get MCP information from environment variables
mcp_count = int(os.environ.get('MCP_COUNT', '0'))
mcp_names_str = os.environ.get('MCP_NAMES', '[]')
try:
mcp_names = json.loads(mcp_names_str)
print(f"Found {mcp_count} MCP servers: {', '.join(mcp_names)}")
except:
mcp_names = []
print("Error parsing MCP_NAMES environment variable")
# Check if extensions key exists, add if not
if 'extensions:' not in content:
content = "extensions:\n" + content
# Process each MCP - we'll collect the mcp configs to add or update
mcp_configs = []
for idx in range(mcp_count):
mcp_name = os.environ.get(f'MCP_{idx}_NAME')
mcp_type = os.environ.get(f'MCP_{idx}_TYPE')
mcp_host = os.environ.get(f'MCP_{idx}_HOST')
# Always use container's SSE port (8080) not the host-bound port
if mcp_name and mcp_host:
# Use standard MCP SSE port (8080)
mcp_url = f"http://{mcp_host}:8080/sse"
print(f"Processing MCP extension: {mcp_name} ({mcp_type}) - {mcp_url}")
mcp_configs.append((mcp_name, mcp_url))
elif mcp_name and os.environ.get(f'MCP_{idx}_URL'):
# For remote MCPs, use the URL provided in environment
mcp_url = os.environ.get(f'MCP_{idx}_URL')
print(f"Processing remote MCP extension: {mcp_name} ({mcp_type}) - {mcp_url}")
mcp_configs.append((mcp_name, mcp_url))
# Now we'll update the config file line by line, preserving all content
lines = content.split('\n')
output_lines = []
in_extensions = False
current_ext = None
extension_added = set() # Track which extensions we've processed
# First pass - update existing extensions and track them
for line in lines:
# Check if we're entering extensions section
if line.strip() == 'extensions:':
in_extensions = True
output_lines.append(line)
continue
# Look for extension definition (2-space indentation)
if in_extensions and re.match(r'^ (\w+):', line):
match = re.match(r'^ (\w+):', line)
current_ext = match.group(1)
output_lines.append(line)
# Mark as seen if this is one of our MCPs
for mcp_name, _ in mcp_configs:
if mcp_name == current_ext:
extension_added.add(mcp_name)
continue
# If we're in an MCP extension that we need to update
if in_extensions and current_ext and current_ext in [n for n, _ in mcp_configs]:
# If this is a URI line, replace it with our URL
if line.strip().startswith('uri:'):
for mcp_name, mcp_url in mcp_configs:
if mcp_name == current_ext:
output_lines.append(f' uri: {mcp_url}')
break
# If this is a type line, ensure it's SSE
elif line.strip().startswith('type:'):
output_lines.append(' type: sse')
# If this is enabled line, ensure it's true
elif line.strip().startswith('enabled:'):
output_lines.append(' enabled: true')
# Otherwise keep the line
else:
output_lines.append(line)
continue
# If we're moving to a non-2-space indented line, we're out of the current extension
if in_extensions and current_ext and not line.startswith(' ') and line.strip():
current_ext = None
# For any other line, just add it
output_lines.append(line)
# Add any MCP extensions that weren't found in the existing config
if in_extensions:
for mcp_name, mcp_url in mcp_configs:
if mcp_name not in extension_added:
print(f"Adding new MCP extension: {mcp_name}")
output_lines.append(f' {mcp_name}:')
output_lines.append(f' enabled: true')
output_lines.append(f' name: {mcp_name}')
output_lines.append(f' timeout: 60')
output_lines.append(f' type: sse')
output_lines.append(f' uri: {mcp_url}')
output_lines.append(f' envs: {{}}')
# Write the updated content back
with open(config_path, 'w') as f:
f.write('\n'.join(output_lines))
print(f"Updated Goose configuration at {config_path}")
EOF
}
# Check if MCP servers are defined
if [ -n "$MCP_COUNT" ] && [ "$MCP_COUNT" -gt 0 ]; then
echo "Updating Goose configuration with MCP servers..."
update_config
echo "Goose configuration updated successfully!"
else
echo "No MCP servers found, using default Goose configuration."
fi