Use this file to discover all available pages before exploring further.
Extensions bring external capabilities to Goose through the Model Context Protocol (MCP). They provide tools, resources, and prompts that the AI agent can use to interact with files, APIs, databases, and more.
# payment-recipe.yamltitle: Payment Processorextensions: - type: stdio name: payment-tools cmd: python args: ["example_server.py"] env: PAYMENT_API_KEY: "${PAYMENT_API_KEY}"instructions: | You can process payments using the payment-tools extension. Always confirm amounts and customer IDs before processing.
Extensions can provide resources that the agent reads:
# Resource example@server.resource("file:///{path}")async def read_file_resource(path: str) -> str: """Read a file as a resource.""" with open(path, 'r') as f: return f.read()@server.resource("docs://api-reference")async def get_api_docs() -> str: """Return API documentation.""" return load_api_documentation()
The agent can access resources:
// Agent requests resourcelet resource = extension_manager .read_resource("docs://api-reference") .await?;// Include in contextsystem_prompt += format!("\n\nAPI Documentation:\n{}", resource.contents);
// Get all available toolslet tools = extension_manager.get_tools().await?;// Tools are cached and versioned for performance// Cache invalidated when extensions change
@server.tool()async def search_code(query: str, language: str = "all") -> list[TextContent]: """Search code files for a pattern. Use this tool to find specific code patterns, function definitions, or variable usages across the codebase. Supports regex patterns. Args: query: Regex pattern to search for language: Filter by language (python, rust, javascript, or 'all') Returns: List of file paths and matching lines """
Handle errors gracefully
Return useful error messages:
@server.tool()async def deploy_service(service_name: str) -> list[TextContent]: try: result = await deployer.deploy(service_name) return [TextContent(type="text", text=f"Deployed {service_name}: {result}")] except ServiceNotFound: return [TextContent( type="text", text=f"Error: Service '{service_name}' not found. Available services: {list_services()}" )] except DeploymentError as e: return [TextContent( type="text", text=f"Deployment failed: {e}. Check logs at /var/log/deploy/{service_name}.log" )]
Use resources for static context
Resources are more efficient than tools for static data:
# Good: Use resource for API docs@server.resource("docs://api")async def api_docs() -> str: return STATIC_API_DOCUMENTATION# Bad: Tool for static data@server.tool()async def get_api_docs() -> list[TextContent]: return [TextContent(type="text", text=STATIC_API_DOCUMENTATION)]
Validate inputs thoroughly
Don’t trust AI-generated arguments:
@server.tool()async def delete_files(pattern: str) -> list[TextContent]: # Validate dangerous operations if pattern in ["/", "/*", "*"]: raise ValueError("Refusing to delete all files") # Validate paths are within allowed directories if not is_safe_path(pattern): raise ValueError(f"Path {pattern} is outside allowed directories") # Proceed with operation deleted = delete_matching_files(pattern) return [TextContent(type="text", text=f"Deleted {len(deleted)} files")]