What You'll Learn
goose works beautifully for individual developers, but scaling it across a team requires thoughtful configuration management and workflow design. This comprehensive guide teaches you how to:
- Set up consistent goose configurations across team members
- Manage shared extensions and custom tooling
- Create team-wide workflows and best practices
- Handle API keys and secrets securely
- Version control configuration files
- Troubleshoot common team environment issues
- Establish governance and usage policies
- Monitor team usage and costs
Who This Is For: Engineering managers, DevOps engineers, team leads, and developers working in collaborative environments.
Table of Contents
- Introduction
- Understanding goose Configuration
- Team Configuration Strategies
- Managing API Keys and Secrets
- Version Control Best Practices
- Shared Extensions and Tooling
- Creating Team Workflows
- Onboarding New Team Members
- Troubleshooting Common Issues
- Governance and Policies
- Monitoring and Cost Management
- Case Studies
- Conclusion
Introduction
You've introduced goose to your team, and individual developers are seeing great productivity gains. But now you're facing challenges:
- "It works on my machine"
- syndrome with different configurations
- Inconsistent extension setups across the team
- Confusion about which LLM provider to use
- Security concerns about API key management
- Difficulty tracking costs across team members
- No standard workflows for common tasks
Sound familiar? You're not alone. While goose excels as a personal AI assistant, transforming it into a team productivity tool requires intentional configuration management and workflow design.
This guide walks you through battle-tested approaches for deploying goose across teams of any size, from small startups to enterprise organizations.
Understanding goose Configuration
Before diving into team setups, let's understand how goose configuration works.
Configuration File Locations
goose stores its configuration in different locations depending on your operating system:
Linux/macOS:
~/.config/block/goose/config.yaml
Windows:
%APPDATA%\Block\goose\config\config.yaml
For more details, see the official config file documentation.
Configuration Structure
A typical goose configuration file looks like this:
# Model provider configuration
providers:
openai:
model: gpt-4o
api_key_env: OPENAI_API_KEY
# Extension configuration
extensions:
developer:
enabled: true
filesystem:
type: stdio
command: "uvx"
args: ["mcp-filesystem"]
timeout: 300
github:
type: stdio
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_TOKEN: "${GITHUB_TOKEN}"
timeout: 300
# Session preferences (optional)
preferences:
default_model: gpt-4o
max_tokens: 4000
Key sections
- Providers: LLM configuration (OpenAI, Anthropic, etc.)
- Extensions: MCP servers and custom tools
- Preferences: User-specific settings
Team Configuration Strategies
There are several approaches to managing goose configurations across teams. Choose based on your team size, security requirements, and organizational structure.
Strategy 1: Shared Base Configuration
Best for: Small teams (5-15 people), startups, unified tech stacks
How it works: Maintain a single base configuration file in version control that all team members use as their starting point.
Implementation
- Create base configuration:
.goose/team-config.yaml(in your project repo):
# Team Base Configuration
# Last updated: 2025-01-15
# Maintained by: Platform Team
providers:
openai:
model: gpt-4o-mini # Cost-effective default
api_key_env: OPENAI_API_KEY
extensions:
# Built-in tools
developer:
enabled: true
# Team-specific extensions
company_api:
type: stdio
command: "uvx"
args: ["company-mcp-server"]
env:
COMPANY_API_KEY: "${COMPANY_API_KEY}"
timeout: 300
# GitHub integration
github:
type: stdio
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_TOKEN: "${GITHUB_TOKEN}"
timeout: 300
# Jira integration
jira:
type: stdio
command: "uvx"
args: ["mcp-jira"]
env:
JIRA_URL: "${JIRA_URL}"
JIRA_EMAIL: "${JIRA_EMAIL}"
JIRA_API_TOKEN: "${JIRA_API_TOKEN}"
timeout: 300
preferences:
# Team standards
default_model: gpt-4o-mini
max_tokens: 4000
# Documentation
# See: wiki/goose-setup.md for installation instructions
# See: wiki/goose-workflows.md for common workflows
2. Setup script for team members:
scripts/setup-goose.sh:
#!/bin/bash
# goose Team Setup Script
set -e
echo "🦢 Setting up goose for team use..."
# Detect OS and set config path
if [[ "$OSTYPE" == "darwin"* ]] || [[ "$OSTYPE" == "linux-gnu"* ]]; then
CONFIG_DIR="$HOME/.config/goose"
elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
CONFIG_DIR="$APPDATA/goose"
else
echo "Unsupported OS: $OSTYPE"
exit 1
fi
# Create config directory if it doesn't exist
mkdir -p "$CONFIG_DIR"
# Copy team configuration
echo "📋 Copying team configuration..."
cp .goose/team-config.yaml "$CONFIG_DIR/config.yaml"
# Check for required environment variables
echo "🔑 Checking environment variables..."
required_vars=("OPENAI_API_KEY" "GITHUB_TOKEN" "COMPANY_API_KEY")
missing_vars=()
for var in "${required_vars[@]}"; do
if [ -z "${!var}" ]; then
missing_vars+=("$var")
fi
done
if [ ${#missing_vars[@]} -gt 0 ]; then
echo "⚠️ Warning: Missing environment variables:"
for var in "${missing_vars[@]}"; do
echo " - $var"
done
echo ""
echo "Set these in your ~/.bashrc or ~/.zshrc:"
for var in "${missing_vars[@]}"; do
echo " export $var='your-key-here'"
done
fi
# Install required tools
echo "📦 Installing required tools..."
command -v uv >/dev/null 2>&1 || {
echo "Installing uv..."
curl -LsSf https://astral.sh/uv/install.sh | sh
}
command -v npx >/dev/null 2>&1 || {
echo "⚠️ npx not found. Please install Node.js."
}
# Verify goose installation
if command -v goose >/dev/null 2>&1; then
echo "✅ goose is installed: $(goose --version)"
else
echo "⚠️ goose is not installed. Install from: https://block.github.io/goose"
fi
echo ""
echo "✅ Team configuration setup complete!"
echo ""
echo "Next steps:"
echo "1. Ensure all environment variables are set"
echo "2. Run 'goose session' to verify setup"
echo "3. See wiki/goose-workflows.md for common workflows"
3. Documentation:
# goose Team Setup
## Quick Start
- Run the setup script:
./scripts/setup-goose.sh
- Set required environment variables in
~/.bashrcor~/.zshrc:
export OPENAI_API_KEY="sk-..."
export GITHUB_TOKEN="ghp_..."
export COMPANY_API_KEY="..."
export JIRA_URL="https://company.atlassian.net"
export JIRA_EMAIL="you@company.com"
export JIRA_API_TOKEN="..."
- Reload your shell:
source ~/.bashrc # or ~/.zshrc
- Test the setup:
goose session
Configuration Changes
The team configuration is stored in .goose/team-config.yaml.
To propose changes:
- Update
.goose/team-config.yaml - Test locally
- Submit PR with description of changes
- Tag
@platform-teamfor review
Getting API Keys
- OpenAI: Get from platform.openai.com
- GitHub: Generate at github.com/settings/tokens
- Company API: Request from #platform-team Slack channel
- Jira: Generate at company.atlassian.net/secure/ViewProfile.jspa
Troubleshooting
Pros
- Simple to implement
- Everyone uses same configuration
- Easy to update (just update file and re-run script)
- Good for small team
Cons
- No customization per user
- Harder to manage different roles/permissions
- All extensions enabled for everyone
Strategy 2: Per-Environment Configurations
Best for: Medium teams (15-50 people), multiple projects, different roles
How it works: Maintain separate configurations for different environments or roles (backend, frontend, DevOps, etc.).
Implementation
Configuration files:
.goose/
├── base-config.yaml # Common settings
├── backend-config.yaml # Backend developers
├── frontend-config.yaml # Frontend developers
├── devops-config.yaml # DevOps/SRE
└── qa-config.yaml # QA engineers
base-config.yaml
# Shared by all team members
providers:
openai:
model: gpt-4o-mini
api_key_env: OPENAI_API_KEY
extensions:
developer:
enabled: true
github:
type: stdio
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_TOKEN: "${GITHUB_TOKEN}"
timeout: 300
frontend-config.yaml
# Frontend-specific extensions
extends: base-config.yaml
extensions:
figma:
type: stdio
command: "npx"
args: ["-y", "mcp-figma"]
env:
FIGMA_TOKEN: "${FIGMA_TOKEN}"
timeout: 300
storybook:
type: stdio
command: "uvx"
args: ["mcp-storybook"]
timeout: 300
devops-config.yaml
# DevOps-specific extensions
extends: base-config.yaml
extensions:
aws:
type: stdio
command: "uvx"
args: ["mcp-aws"]
env:
AWS_REGION: "${AWS_REGION}"
AWS_PROFILE: "${AWS_PROFILE}"
timeout: 600
kubernetes:
type: stdio
command: "uvx"
args: ["mcp-kubernetes"]
env:
KUBECONFIG: "${KUBECONFIG}"
timeout: 300
datadog:
type: stdio
command: "uvx"
args: ["mcp-datadog"]
env:
DD_API_KEY: "${DD_API_KEY}"
DD_APP_KEY: "${DD_APP_KEY}"
timeout: 300
Setup script with role selection
scripts/setup-goose.sh
#!/bin/bash
echo "🦢 goose Team Setup"
echo ""
echo "Select your role:"
echo "1) Backend Developer"
echo "2) Frontend Developer"
echo "3) DevOps/SRE"
echo "4) QA Engineer"
echo ""
read -p "Enter choice [1-4]: " choice
case $choice in
1)
CONFIG_FILE=".goose/backend-config.yaml"
ROLE="Backend"
;;
2)
CONFIG_FILE=".goose/frontend-config.yaml"
ROLE="Frontend"
;;
3)
CONFIG_FILE=".goose/devops-config.yaml"
ROLE="DevOps"
;;
4)
CONFIG_FILE=".goose/qa-config.yaml"
ROLE="QA"
;;
*)
echo "Invalid choice"
exit 1
;;
esac
echo "📋 Setting up $ROLE configuration..."
# Detect OS and set config path
if [[ "$OSTYPE" == "darwin"* ]] || [[ "$OSTYPE" == "linux-gnu"* ]]; then
CONFIG_DIR="$HOME/.config/goose"
elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
CONFIG_DIR="$APPDATA/goose"
fi
mkdir -p "$CONFIG_DIR"
cp "$CONFIG_FILE" "$CONFIG_DIR/config.yaml"
echo "✅ Configuration installed!"
echo "📚 See docs/goose-$ROLE-guide.md for role-specific workflows"
Pros
- Customized per role
- Only install needed extensions
- Role-specific documentation
- Scales better than single config
Cons
- More maintenance overhead
- Configuration drift between roles
- Need to manage multiple files
Strategy 3: Team Templates
Best for: Large teams (50+ people), enterprises, strict compliance requirements
How it works: Use a configuration management tool to generate and distribute configurations dynamically.
Implementation
Using a configuration generator:
scripts/generate-config.py
#!/usr/bin/env python3
"""
Generate goose configuration based on user role and permissions
"""
import os
import yaml
import argparse
from pathlib import Path
# Base configuration template
BASE_CONFIG = {
'providers': {
'openai': {
'model': 'gpt-4o-mini',
'api_key_env': 'OPENAI_API_KEY'
}
},
'extensions': {
'developer': {
'enabled': True
}
}
}
# Role-specific extensions
ROLE_EXTENSIONS = {
'backend': {
'postgres': {
'type': 'stdio',
'command': 'uvx',
'args': ['mcp-postgres'],
'env': {'DATABASE_URL': '${DATABASE_URL}'},
'timeout': 300
},
'redis': {
'type': 'stdio',
'command': 'uvx',
'args': ['mcp-redis'],
'env': {'REDIS_URL': '${REDIS_URL}'},
'timeout': 300
}
},
'frontend': {
'figma': {
'type': 'stdio',
'command': 'npx',
'args': ['-y', 'mcp-figma'],
'env': {'FIGMA_TOKEN': '${FIGMA_TOKEN}'},
'timeout': 300
}
},
'devops': {
'aws': {
'type': 'stdio',
'command': 'uvx',
'args': ['mcp-aws'],
'env': {
'AWS_REGION': '${AWS_REGION}',
'AWS_PROFILE': '${AWS_PROFILE}'
},
'timeout': 600
},
'kubernetes': {
'type': 'stdio',
'command': 'uvx',
'args': ['mcp-kubernetes'],
'env': {'KUBECONFIG': '${KUBECONFIG}'},
'timeout': 300
}
}
}
# Team-wide extensions (everyone gets these)
TEAM_EXTENSIONS = {
'github': {
'type': 'stdio',
'command': 'npx',
'args': ['-y', '@modelcontextprotocol/server-github'],
'env': {'GITHUB_TOKEN': '${GITHUB_TOKEN}'},
'timeout': 300
},
'jira': {
'type': 'stdio',
'command': 'uvx',
'args': ['mcp-jira'],
'env': {
'JIRA_URL': '${JIRA_URL}',
'JIRA_EMAIL': '${JIRA_EMAIL}',
'JIRA_API_TOKEN': '${JIRA_API_TOKEN}'
},
'timeout': 300
}
}
def generate_config(role: str, custom_extensions: list = None) -> dict:
"""Generate configuration for a specific role"""
config = BASE_CONFIG.copy()
# Add team-wide extensions
config['extensions'].update(TEAM_EXTENSIONS)
# Add role-specific extensions
if role in ROLE_EXTENSIONS:
config['extensions'].update(ROLE_EXTENSIONS[role])
# Add custom extensions
if custom_extensions:
for ext in custom_extensions:
if ext in ROLE_EXTENSIONS:
config['extensions'].update({ext: ROLE_EXTENSIONS[ext]})
return config
def get_config_path() -> Path:
"""Get OS-specific config path"""
if os.name == 'nt': # Windows
return Path(os.getenv('APPDATA')) / 'goose' / 'config.yaml'
else: # Linux/macOS
return Path.home() / '.config' / 'goose' / 'config.yaml'
def main():
parser = argparse.ArgumentParser(description='Generate goose team configuration')
parser.add_argument('role', choices=['backend', 'frontend', 'devops', 'qa'],
help='Your role')
parser.add_argument('--output', '-o', help='Output file (default: install to config dir)')
parser.add_argument('--extensions', '-e', nargs='+',
help='Additional extensions to enable')
parser.add_argument('--dry-run', action='store_true',
help='Print configuration without installing')
args = parser.parse_args()
# Generate configuration
config = generate_config(args.role, args.extensions)
# Convert to YAML
yaml_config = yaml.dump(config, default_flow_style=False, sort_keys=False)
if args.dry_run:
print(yaml_config)
return
# Determine output path
if args.output:
output_path = Path(args.output)
else:
output_path = get_config_path()
# Create directory if needed
output_path.parent.mkdir(parents=True, exist_ok=True)
# Write configuration
output_path.write_text(yaml_config)
print(f"✅ Configuration generated for role: {args.role}")
print(f"📝 Written to: {output_path}")
print(f"\nNext steps:")
print(f"1. Set required environment variables")
print(f"2. Run 'goose session' to verify setup")
print(f"3. See docs/goose-{args.role}-guide.md for workflows")
if __name__ == '__main__':
main()
Usage
# Generate backend developer config
python scripts/generate-config.py backend
# Generate with additional extensions
python scripts/generate-config.py frontend --extensions postgres redis
# Preview without installing
python scripts/generate-config.py devops --dry-run
Pros
- Highly customizable
- Centralized control
- Audit trail of configurations
- Easy to enforce policies
- Can integrate with identity management
Cons
- Most complex to set up
- Requires maintenance
- Overkill for small teams
Managing API Keys and Secrets
Critical: Never commit API keys to version control!
Recommended Approach: Environment Variables
1. Create a template file
.env.template (safe to commit)
# goose Environment Variables
# Copy to .env and fill in your values
# OpenAI
OPENAI_API_KEY=sk-...
# GitHub
GITHUB_TOKEN=ghp_...
# Company API
COMPANY_API_KEY=...
# Jira
JIRA_URL=https://company.atlassian.net
JIRA_EMAIL=you@company.com
JIRA_API_TOKEN=...
# AWS (for DevOps)
AWS_REGION=us-east-1
AWS_PROFILE=default
# Database (for Backend)
DATABASE_URL=postgresql://localhost:5432/dev
REDIS_URL=redis://localhost:6379
-
Add to
.gitignore
# goose secrets
.env
*.key
-
Setup script to load environment
scripts/load-goose-env.sh
#!/bin/bash
# Source this file to load goose environment variables
if [ -f .env ]; then
export $(cat .env | grep -v '^#' | xargs)
echo "✅ Environment variables loaded from .env"
else
echo "⚠️ .env file not found"
echo "Copy .env.template to .env and fill in your values"
exit 1
fi
Usage
# Load environment before using goose
source scripts/load-goose-env.sh
goose session
Alternative: Secret Management Services
For enterprises, use a dedicated secret management service:
1. Using 1Password CLI
# Store secret
op item create --category=login \
--title="goose OpenAI Key" \
--vault="Engineering" \
"password=sk-..."
# Retrieve in script
export OPENAI_API_KEY=$(op read "op://Engineering/goose OpenAI Key/password")
2. Using AWS Secrets Manager
# Store secret
aws secretsmanager create-secret \
--name goose/openai-key \
--secret-string "sk-..."
# Retrieve in script
export OPENAI_API_KEY=$(aws secretsmanager get-secret-value \
--secret-id goose/openai-key \
--query SecretString \
--output text)
3. Using HashiCorp Vault
# Store secret
vault kv put secret/goose/openai key=sk-...
# Retrieve in script
export OPENAI_API_KEY=$(vault kv get -field=key secret/goose/openai)
Version Control Best Practices
What to Commit
DO commit
- Base configuration templates
- Setup scripts
- Documentation
.env.template files- Test configurations (with dummy values)
DON'T commit
- Personal API keys
-
.envfiles with real values - Individual user configurations
- Logs or session data
.gitignore Template
# goose
.env
.env.local
*.key
*.pem
# OS-specific
.DS_Store
Thumbs.db
# Editor
.vscode/
.idea/
*.swp
*.swo
# Logs
*.log
goose-*.log
Configuration Versioning
Track configuration changes with meaningful commit messages:
# Good commit messages
git commit -m "feat(goose): add PostgreSQL extension for backend team"
git commit -m "fix(goose): update GitHub token environment variable name"
git commit -m "docs(goose): add troubleshooting guide for extension timeouts"
# Bad commit messages
git commit -m "update config"
git commit -m "fix"
Shared Extensions and Tooling
Create custom extensions for team-specific needs.
Example: Company API Extension
Scenario: Your team frequently interacts with internal APIs. Create an MCP server for common operations.
company-api-mcp/src/company_api/server.py
from mcp.server.fastmcp import FastMCP
import os
import requests
mcp = FastMCP("company-api")
@mcp.tool()
def get_user(user_id: str) -> dict:
"""Get user details from company API"""
api_key = os.getenv("COMPANY_API_KEY")
response = requests.get(
f"https://api.company.com/users/{user_id}",
headers={"Authorization": f"Bearer {api_key}"}
)
return response.json()
@mcp.tool()
def create_deployment(service: str, version: str, environment: str) -> dict:
"""Create a new deployment"""
api_key = os.getenv("COMPANY_API_KEY")
response = requests.post(
"https://api.company.com/deployments",
headers={"Authorization": f"Bearer {api_key}"},
json={
"service": service,
"version": version,
"environment": environment
}
)
return response.json()
Publish internally
# Build and publish to internal PyPI
uv build
uv publish --repository internal-pypi
# Team members install with
uvx --from internal-pypi company-api-mcp
Add to team configuration
extensions:
company_api:
type: stdio
command: "uvx"
args: ["--from", "internal-pypi", "company-api-mcp"]
env:
COMPANY_API_KEY: "${COMPANY_API_KEY}"
timeout: 300
Creating Team Workflows
Document common workflows so everyone uses goose consistently.
Workflow Documentation Template
docs/workflows/code-review.md
# Workflow: Code Review with goose
## Objective
Use goose to perform initial code review before requesting human review.
## Steps
1. **Check out the PR branch**
git checkout feature/new-feature
2. **Start goose session**
cd project-root
goose session
3. **Request code review**
Review the changes in this branch compared to main. Focus on:
- Code quality and readability
- Potential bugs or edge cases
- Security vulnerabilities
- Performance issues
- Test coverage
Provide specific suggestions with file and line numbers.
4. **Address feedback**
- Fix identified issues
- Add suggested tests
- Improve code based on recommendations
5. **Re-review** (repeat step 3)
6. **Request human review** once goose review is clean
## Tips
- Use "explain this code" for complex logic
- Ask "what tests should I add?"
- Request "suggest performance improvements"
## Example Session
\`\`\`
You: Review the changes in src/api/users.py
goose: I've reviewed the file. Here are my findings:
1. Line 45: Missing input validation for email parameter
2. Line 67: SQL injection vulnerability - use parameterized query
3. Line 89: Consider adding error handling for database connection
...
\`\`\`
Common Workflow Library
Create a library of documented workflows:
docs/workflows/
├── code-review.md
├── debugging.md
├── refactoring.md
├── documentation.md
├── test-writing.md
└── deployment.md
Onboarding New Team Members
Create a smooth onboarding experience.
Onboarding Checklist
docs/onboarding-checklist.md
# goose Onboarding Checklist
Welcome! Follow these steps to get goose set up.
## Prerequisites
- [ ] Install goose ([instructions](https://block.github.io/goose/docs/getting-started/installation))
- [ ] Install uv: `curl -LsSf https://astral.sh/uv/install.sh | sh`
- [ ] Install Node.js (for npm extensions)
## Setup
- [ ] Clone the team repo
- [ ] Run setup script: `./scripts/setup-goose.sh`
- [ ] Copy `.env.template` to `.env`
- [ ] Get API keys:
- [ ] OpenAI: [Request from #platform-team]
- [ ] GitHub: [Generate personal token]
- [ ] Company API: [Request from #platform-team]
- [ ] Fill in `.env` with your keys
- [ ] Load environment: `source scripts/load-goose-env.sh`
- [ ] Test setup: `goose session`
## Learning Resources
- [ ] Read [goose Basics](./goose-basics.md)
- [ ] Review [Common Workflows](./workflows/)
- [ ] Watch [Team Demo Video](link-to-video)
- [ ] Join #goose-users Slack channel
## First Steps
- [ ] Complete [Tutorial: Code Review](./tutorials/code-review.md)
- [ ] Try workflow: Review your own recent PR
- [ ] Ask questions in #goose-users
## Getting Help
- **Technical issues**: #goose-support
- **API key issues**: #platform-team
- **Workflow questions**: #goose-users
- **Documentation**: [Team Wiki](wiki/goose)
---
**Need help?** Tag @goose-champions in Discord!
Onboarding Buddy System
Assign experienced goose users as "buddies" for new team members:
scripts/assign-buddy.sh
#!/bin/bash
# Assign a goose buddy to new team member
NEW_MEMBER=$1
BUDDIES=("alice@company.com" "bob@company.com" "charlie@company.com")
# Round-robin assignment
BUDDY=${BUDDIES[$((RANDOM % ${#BUDDIES[@]}))]}
echo "🦢 goose Buddy Assignment"
echo "New Member: $NEW_MEMBER"
echo "Assigned Buddy: $BUDDY"
echo ""
echo "Sending notification to Slack..."
# Send Slack notification (requires Slack webhook)
curl -X POST $SLACK_WEBHOOK_URL \
-H 'Content-Type: application/json' \
-d "{
\"text\": \"🦢 New goose user!\",
\"blocks\": [
{
\"type\": \"section\",
\"text\": {
\"type\": \"mrkdwn\",
\"text\": \"*$NEW_MEMBER* is learning goose!\n\nBuddy: *$BUDDY*\n\nPlease help them get started with:\n• Configuration setup\n• First workflow\n• Answering questions\"
}
}
]
}"
Troubleshooting Common Issues
Document solutions to problems teams frequently encounter.
Issue 1: Extension Not Loading
Problem: Extension shows in config but doesn't appear in goose
Why This Happens
- The extension executable is not in PATH or doesn't exist
- Environment variables required by the extension are not set
- The extension command has a typo
- Network issues preventing download of npm/uvx packages
Solutions
# 1. Test extension command manually
uvx mcp-postgres # Should start the server
# 2. Check environment variables
echo $DATABASE_URL # Should output your connection string
# 3. Verify goose can find the command
which uvx # Should show path to uvx
# 4. Check goose logs
tail -f ~/.config/goose/logs/goose.log
# 5. Test with MCP Inspector
mcp dev path/to/extension/server.py
Prevention
- Add extension verification to setup script
- Document all required environment variables
- Test extensions before adding to team config
Issue 2: API Rate Limits
Problem: goose stops working with "rate limit exceeded" errors
Why This Happens
- Too many requests in a short time period
- Using expensive models for simple tasks
- Multiple team members sharing one API key
- Automated processes making frequent calls
Solutions
# Use tiered model approach in config
providers:
openai:
model: gpt-4o-mini # Default to cheaper model
api_key_env: OPENAI_API_KEY
openai_premium:
model: gpt-4o # Premium model for complex tasks
api_key_env: OPENAI_API_KEY
# Tell users when to use premium model
preferences:
model_selection_guide: |
Use gpt-4o-mini (default) for:
- Code review
- Documentation
- Simple refactoring
Use gpt-4o (premium) for:
- Complex architecture decisions
- Large-scale refactoring
- Critical debugging
Prevention
- Use separate API keys per team member
- Set up billing alerts
- Monitor usage via OpenAI dashboard
- Educate team on model selection
Issue 3: Configuration Drift
Problem: Team members have different configurations causing inconsistent behavior.
Why This Happens
- Manual configuration changes not synced
- Different team members pulling from outdated sources
- Local modifications not documented
- No version control for configurations
Solutions
# 1. Create configuration validation script
#!/bin/bash
# scripts/validate-config.sh
CONFIG_FILE="$HOME/.config/goose/config.yaml"
TEAM_CONFIG=".goose/team-config.yaml"
echo "🔍 Validating goose configuration..."
# Compare with team config
if diff -q "$CONFIG_FILE" "$TEAM_CONFIG" > /dev/null; then
echo "✅ Configuration is up to date"
else
echo "⚠️ Configuration differs from team config"
echo ""
echo "Differences:"
diff "$CONFIG_FILE" "$TEAM_CONFIG"
echo ""
read -p "Update to team config? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
cp "$TEAM_CONFIG" "$CONFIG_FILE"
echo "✅ Configuration updated"
fi
fi
# 2. Add to pre-commit hook
# .git/hooks/pre-commit
#!/bin/bash
./scripts/validate-config.sh
Prevention
- Regular configuration audits
- Automated sync scripts
- Clear process for config changes
- Version config files in git
Issue 4: Slow Performance
Problem: goose takes a long time to respond
Why This Happens
- Extensions with long timeouts
- Expensive operations in tool implementations
- Network latency to remote services
- Large context windows
- Inefficient prompts
Solutions
# 1. Optimize extension timeouts
extensions:
slow_extension:
timeout: 300 # Reduce if possible
# 2. Use caching where appropriate
extensions:
api_extension:
env:
ENABLE_CACHE: "true"
CACHE_TTL: "3600" # 1 hour
# 3. Configure reasonable context limits
preferences:
max_tokens: 4000 # Don't go overboard
max_context_files: 10 # Limit files in context
Prevention
- Profile extensions before deploying
- Set reasonable timeout defaults
- Monitor response times
- Optimize custom extensions
Issue 5: Permission Errors
Problem: goose can't access files or resources
Why This Happens
- Insufficient file permissions
- Extensions trying to access restricted paths
- Environment variables pointing to restricted locations
- Security policies blocking access
Solutions
# 1. Check file permissions
ls -la ~/.config/goose/
# Ensure user has read/write access
# 2. Fix permissions
chmod 755 ~/.config/goose
chmod 644 ~/.config/goose/config.yaml
# 3. Check extension permissions
# Extensions should not require root/admin
# 4. Verify environment variables
echo $HOME # Should be your home directory
echo $GOOSE_CONFIG_DIR # Should be writable
Prevention
- Document required permissions
- Test on fresh user accounts
- Avoid requiring elevated permissions
- Use user-specific paths
Governance and Policies
Establish clear policies for team goose usage.
Usage Policy Template
docs/goose-usage-policy.md
# goose Usage Policy
## Acceptable Use
goose is provided to improve developer productivity. Acceptable uses include:
✅ **Allowed:**
- Code review and analysis
- Documentation generation
- Test writing
- Debugging assistance
- Learning new technologies
- Refactoring guidance
- Architecture discussions
❌ **Not Allowed:**
- Processing confidential customer data
- Generating production secrets or keys
- Making production deployments without review
- Sharing API keys or credentials
- Using goose to bypass code review processes
- Bulk automated operations without approval
## Data Privacy
- **Code**: goose processes code snippets to provide assistance
- **Sharing**: Code context is sent to LLM providers (OpenAI, Anthropic, etc.)
- **Retention**: Check your LLM provider's data retention policy
- **Sensitive Data**: Do not include PII, secrets, or confidential data in prompts
## Security Guidelines
- **API Keys**: Keep personal, never share
- **Extensions**: Only install approved extensions
- **Updates**: Keep goose and extensions updated
- **Incidents**: Report security concerns to #security-team
## Cost Management
- **Model Selection**: Use gpt-4o-mini by default
- **Usage Limits**: Stay within monthly budget (check dashboard)
- **Monitoring**: Review your usage weekly
- **Alerts**: Set up billing alerts in OpenAI dashboard
## Quality Standards
- **Always Review**: Never blindly accept AI-generated code
- **Test**: All code must pass tests before committing
- **Document**: Add comments explaining AI-assisted code
- **Responsibility**: You own all code you commit
## Reporting Issues
- **Bugs**: #goose-support
- **Policy Violations**: #engineering-leads
- **Security Concerns**: #security-team
---
**Acknowledgment**: By using goose, you agree to follow this policy.
Last Updated: 2025-10-25
Policy Owner: Engineering Leadership
Access Control
For enterprises, implement role-based access:
scripts/check-access.py
#!/usr/bin/env python3
"""
Check if user has access to requested goose configuration
"""
import sys
import requests
import os
# Integration with your identity provider
def check_user_access(email: str, role: str) -> bool:
"""Check if user has access to role configuration"""
# Example: Check against internal API
response = requests.get(
f"https://api.company.com/access/goose",
headers={"Authorization": f"Bearer {os.getenv('COMPANY_API_KEY')}"},
params={"email": email, "role": role}
)
return response.json().get("has_access", False)
def main():
email = os.getenv("USER_EMAIL")
requested_role = sys.argv[1] if len(sys.argv) > 1 else "developer"
if check_user_access(email, requested_role):
print(f"✅ Access granted: {requested_role}")
sys.exit(0)
else:
print(f"❌ Access denied: {requested_role}")
print("Contact #platform-team to request access")
sys.exit(1)
if __name__ == "__main__":
main()
Integrate into setup script
# In setup-goose.sh
python scripts/check-access.py $ROLE || exit 1
Monitoring and Cost Management
Track usage and costs across your team.
Cost Tracking Dashboard
Create a simple dashboard to monitor API usage:
scripts/cost-tracker.py
#!/usr/bin/env python3
"""
Track goose API costs across team
"""
import requests
import os
from datetime import datetime, timedelta
from collections import defaultdict
def get_openai_usage(api_key: str, days: int = 30):
"""Get OpenAI usage for last N days"""
end_date = datetime.now()
start_date = end_date - timedelta(days=days)
response = requests.get(
"https://api.openai.com/v1/usage",
headers={"Authorization": f"Bearer {api_key}"},
params={
"start_date": start_date.strftime("%Y-%m-%d"),
"end_date": end_date.strftime("%Y-%m-%d")
}
)
return response.json()
def calculate_costs(usage_data: dict) -> dict:
"""Calculate costs by model"""
# Pricing (as of 2025)
pricing = {
"gpt-4o": {"input": 0.0025, "output": 0.01}, # per 1K tokens
"gpt-4o-mini": {"input": 0.00015, "output": 0.0006},
"gpt-4": {"input": 0.03, "output": 0.06}
}
costs = defaultdict(float)
for entry in usage_data.get("data", []):
model = entry.get("model")
input_tokens = entry.get("input_tokens", 0)
output_tokens = entry.get("output_tokens", 0)
if model in pricing:
costs[model] += (
(input_tokens / 1000) * pricing[model]["input"] +
(output_tokens / 1000) * pricing[model]["output"]
)
return dict(costs)
def main():
# This should be a company-wide API key for monitoring
api_key = os.getenv("OPENAI_MONITOR_KEY")
usage = get_openai_usage(api_key, days=30)
costs = calculate_costs(usage)
total_cost = sum(costs.values())
print("📊 goose Cost Report (Last 30 Days)")
print("=" * 50)
print(f"Total: ${total_cost:.2f}")
print()
print("By Model:")
for model, cost in sorted(costs.items(), key=lambda x: x[1], reverse=True):
print(f" {model:20} ${cost:>10.2f}")
print()
# Alert if over budget
budget = float(os.getenv("MONTHLY_BUDGET", "1000"))
if total_cost > budget:
print(f"⚠️ WARNING: Over budget by ${total_cost - budget:.2f}")
print("Consider:")
print("- Using gpt-4o-mini more often")
print("- Reviewing high-usage team members")
print("- Optimizing prompts to reduce tokens")
if __name__ == "__main__":
main()
Run weekly
# Add to cron or CI/CD
0 9 * * 1 python scripts/cost-tracker.py | mail -s "goose Weekly Cost Report" team@company.com
Usage Analytics
Track which extensions and workflows are most popular:
scripts/usage-analytics.py
#!/usr/bin/env python3
"""
Analyze goose usage patterns across team
"""
import yaml
from pathlib import Path
from collections import Counter
import matplotlib.pyplot as plt
def analyze_configurations():
"""Analyze what extensions teams are using"""
# Scan team configurations
config_dir = Path(".goose")
extensions_used = Counter()
for config_file in config_dir.glob("*-config.yaml"):
with open(config_file) as f:
config = yaml.safe_load(f)
for ext_name in config.get("extensions", {}).keys():
extensions_used[ext_name] += 1
# Generate report
print("📊 Extension Usage Report")
print("=" * 50)
print(f"Most Popular Extensions:")
for ext, count in extensions_used.most_common(10):
print(f" {ext:30} {count:3} configs")
# Create visualization
plt.figure(figsize=(10, 6))
exts, counts = zip(*extensions_used.most_common(10))
plt.barh(exts, counts)
plt.xlabel("Number of Configurations")
plt.title("Top 10 goose Extensions by Usage")
plt.tight_layout()
plt.savefig("goose-usage-report.png")
print("\n📈 Chart saved: goose-usage-report.png")
if __name__ == "__main__":
analyze_configurations()
Budget Alerts
Set up automated alerts when approaching budget limits:
scripts/budget-alert.sh
#!/bin/bash
# Check if approaching monthly budget
CURRENT_SPEND=$(python scripts/cost-tracker.py --json | jq '.total_cost')
BUDGET=${MONTHLY_BUDGET:-1000}
THRESHOLD=0.8 # Alert at 80%
if (( $(echo "$CURRENT_SPEND > ($BUDGET * $THRESHOLD)" | bc -l) )); then
PERCENT=$(echo "scale=1; ($CURRENT_SPEND / $BUDGET) * 100" | bc)
# Send Slack alert
curl -X POST $SLACK_WEBHOOK_URL \
-H 'Content-Type: application/json' \
-d "{
\"text\": \"⚠️ goose Budget Alert\",
\"blocks\": [
{
\"type\": \"section\",
\"text\": {
\"type\": \"mrkdwn\",
\"text\": \"*goose Monthly Budget Alert*\n\nCurrent: \$CURRENT_SPEND\nBudget: \$BUDGET\nUsage: $PERCENT%\n\nReview usage at: [Dashboard Link]\"
}
}
]
}"
fi
Case Studies
Learn from teams who've successfully deployed goose.
Case Study 1: Startup (15 developers)
Challenge: Fast-moving startup needed consistent tooling across growing team
Solution
- Implemented Strategy 1 (Shared Base Configuration)
- Single setup script in repo
- Weekly sync meetings to discuss new workflows
- Slack channel for quick questions
Results
- 100% team adoption in 2 weeks
- Reduced onboarding time from 3 days to 4 hours
- Standardized code review process
- 30% faster PR turnaround
Key Learnings
- Keep it simple at first
- Document everything in README
- Have "office hours" for questions
- Start with one workflow everyone uses
Case Study 2: Mid-size Company (50 developers)
Challenge: Multiple teams with different tech stacks and needs
Solution
- Implemented Strategy 2 (Per-Environment Configurations)
- Separate configs for Backend, Frontend, DevOps, QA
- Central platform team maintains extensions
- Monthly training sessions
Results
- 85% team adoption in 3 months
- 4 custom internal extensions built
- Reduced repetitive tasks by 40%
- Improved documentation quality
Key Learnings
- Role-specific configs crucial
- Need dedicated "goose champion" per team
- Custom extensions provide huge value
- Regular training keeps engagement high
Case Study 3: Enterprise (200+ developers)
Challenge: Large organization with strict compliance and security requirements
Solution
- Implemented Strategy 3 (Team Templates)
- Configuration generator with access control
- Integration with identity management
- Centralized cost tracking and alerts
- Quarterly governance reviews
Results
- 70% adoption across engineering org
- Passed security audit
- $50K/month in productivity gains
- Reduced API costs by 30% with smart model selection
Key Learnings
- Security and compliance can't be afterthoughts
- Need executive sponsorship
- Cost monitoring essential at scale
- Change management takes time
Conclusion
Deploying goose across a team requires more than just installing the software. Success comes from:
- Clear Configuration Management: Choose a strategy that fits your team size and needs
- Security-First Approach: Never compromise on API key management
- Documentation: Write everything down—your future team members will thank you
- Workflows: Establish patterns everyone can follow
- Governance: Set policies and monitor compliance
- Continuous Improvement: Gather feedback and iterate
Quick Start Recommendations by Team Size
Small Teams (< 15):
- Use Strategy 1 (Shared Base Configuration)
- Keep configs simple
- Focus on 2-3 core workflows
- Use environment variables for secrets
Medium Teams (15-50):
- Use Strategy 2 (Per-Environment Configurations)
- Create role-specific setups
- Build 1-2 custom extensions
- Establish governance policies
Large Teams (50+):
- Use Strategy 3 (Team Templates)
- Implement access control
- Build comprehensive monitoring
- Create dedicated platform team
Next Steps
- Assess Your Team: Size, structure, needs
- Choose a Strategy: Based on recommendations above
- Start Small: One team or project first
- Document: Create setup guides and workflows
- Train: Run workshops and create resources
- Monitor: Track usage and costs
- Iterate: Gather feedback and improve
- Scale: Roll out to wider organization
Resources
Getting Help
Questions about team deployment?
- Join #goose-users on Discord
- Post in GitHub Discussions
- Reach out to platform team at your company
- Share your learnings with the community
This guide is part of the goose documentation series. See also:
- Getting Started with goose on Windows
- Best Practices for Prompt Engineering with goose
- Deep Dive into goose's Extension System and MCP
Happy team coding with goose! 🦢
Top comments (0)