manifest.yaml Schema
A manifest.yaml file defines a capability’s interface, resource requirements, and credential needs. It tells Selu how to run the capability and what secrets it requires.
Schema
Section titled “Schema”| Field | Type | Required | Default | Description |
|---|---|---|---|---|
id | string | yes | Unique capability identifier (lowercase, alphanumeric, hyphens) | |
class | string | no | "tool" | Capability class: "tool" or "environment" |
image | string | yes | Docker image that implements the capability | |
tool_source | string | no | "manifest" | Tool discovery mode: "manifest" or "dynamic" |
discovery_tool_name | string | no | "list_tools" | Tool name for dynamic discovery (when tool_source is "dynamic") |
tools | array | no | [] | List of tools this capability provides (required for "manifest" mode) |
tools[].name | string | yes | Tool name (used by agents) | |
tools[].description | string | yes | What the tool does (shown to agents) | |
tools[].input_schema | object | yes | JSON Schema for tool parameters | |
tools[].requires_confirmation | boolean | no | false | Legacy field for backwards compatibility |
tools[].recommended_policy | string | no | derived | Recommended policy: "allow", "ask", or "block" |
tools[].terminal_on_success | boolean | no | false | When true, the tool loop exits immediately after a successful invocation instead of giving the LLM another iteration. Useful for “produce-and-done” tools like PDF generation where a follow-up call would create a duplicate artifact. |
network | object | no | {"mode": "none"} | Network access policy |
network.mode | string | no | "none" | Network mode: "none", "allowlist", or "any" |
network.hosts | array | no | [] | Allowed hosts for "allowlist" mode (format: "host:port") |
filesystem | string | no | "none" | Filesystem policy: "none", "temp", or "workspace" |
credentials | array | no | [] | List of credentials this capability needs |
credentials[].name | string | yes | Environment variable name for the credential | |
credentials[].scope | string | yes | Credential scope: "system" or "user" | |
credentials[].credential_type | string | no | "secret" | Type of credential (currently only "secret") |
credentials[].required | boolean | no | true | Whether the credential is required for the capability to function |
credentials[].description | string | no | "" | Human-readable description of what this credential is for |
resources | object | no | defaults | Resource limits for the container |
resources.max_memory_mb | integer | no | 128 | Maximum memory in megabytes |
resources.max_cpu_fraction | number | no | 0.5 | Maximum CPU cores (0.5 = half a core) |
resources.max_cpu_seconds | integer | no | 30 | Maximum CPU time per tool invocation |
resources.pids_limit | integer | no | 64 | Maximum number of processes/threads |
Tool discovery modes
Section titled “Tool discovery modes”Capabilities can provide tools in two ways:
Static tools (tool_source: manifest)
Section titled “Static tools (tool_source: manifest)”Tools are declared directly in the manifest (default behavior):
id: my-capabilitytool_source: manifest # explicit, but this is the defaulttools: - name: search_web description: Search the internet for information input_schema: type: object properties: query: {type: string} required: [query]Dynamic tools (tool_source: dynamic)
Section titled “Dynamic tools (tool_source: dynamic)”Tools are discovered at runtime by calling a special discovery tool:
id: my-capabilitytool_source: dynamicdiscovery_tool_name: list_tools # optional, defaults to "list_tools"tools: [] # must be empty for dynamic modeWith dynamic discovery, the capability container must implement a discovery tool (default name: list_tools) that returns the available tools in JSON format. This enables capabilities that generate tools based on runtime conditions, API introspection, or user configuration.
Credential scopes
Section titled “Credential scopes”Credentials can have different scopes:
system— Shared across all users. Set once by an admin and used by everyone.user— Personal to each user. Each person provides their own API keys.
Choose system for organizational API keys that should be shared, and user for personal accounts or when users prefer to manage their own credentials.
Tool policies
Section titled “Tool policies”Each tool can declare a recommended_policy that serves as the default when users install the agent:
"allow"— Tool runs automatically without asking"ask"— User is prompted before each tool execution"block"— Tool is blocked by default (users must explicitly enable)
If you don’t specify recommended_policy, it’s derived from the legacy requires_confirmation field, or defaults to "block" for security.
Network access
Section titled “Network access”Capabilities run in isolated containers with configurable network access:
No network access (mode: none)
Section titled “No network access (mode: none)”network: mode: noneThe capability cannot make any outbound network connections. Use this for tools that only process local data or use built-in datasets.
Allowlist mode (mode: allowlist)
Section titled “Allowlist mode (mode: allowlist)”network: mode: allowlist hosts: - "api.openweathermap.org:443" - "*.googleapis.com:443" # wildcard subdomains supported - "httpbin.org" # any port if not specifiedThe capability can only connect to explicitly listed hosts. Wildcard entries starting with *. match any subdomain. This is the recommended mode for most capabilities.
Any network access (mode: any)
Section titled “Any network access (mode: any)”network: mode: anyThe capability can connect to any host on the internet. Use sparingly and only for trusted capabilities that need unrestricted access.
Examples
Section titled “Examples”Basic tool capability
Section titled “Basic tool capability”id: web-searchclass: toolimage: ghcr.io/selu-bot/cap-web-search:2.1.0
tools: - name: search_web description: Search the web and return relevant results input_schema: type: object properties: query: type: string description: The search query max_results: type: integer description: Maximum results to return default: 5 required: [query] recommended_policy: allow
network: mode: allowlist hosts: - "duckduckgo.com:443" - "api.openai.com:443"
credentials: - name: SEARCH_API_KEY scope: system required: false description: > Optional API key for enhanced search results. Get one from https://serpapi.com if you want more reliable search data.
resources: max_memory_mb: 256 max_cpu_fraction: 0.5 pids_limit: 32Environment capability with workspace
Section titled “Environment capability with workspace”id: python-envclass: environmentimage: ghcr.io/selu-bot/cap-python-env:1.0.0
tools: - name: execute_python description: Execute Python code in an isolated environment input_schema: type: object properties: code: type: string description: Python code to execute required: [code] recommended_policy: ask
filesystem: workspace
credentials: - name: OPENAI_API_KEY scope: user required: true description: > Your OpenAI API key. Get one from https://platform.openai.com/api-keys. This is needed for AI-powered code analysis.
resources: max_memory_mb: 512 max_cpu_fraction: 1.0 max_cpu_seconds: 60 pids_limit: 128Dynamic tool capability
Section titled “Dynamic tool capability”id: github-integrationclass: toolimage: ghcr.io/selu-bot/cap-github:1.5.0tool_source: dynamicdiscovery_tool_name: discover_repositories
tools: [] # empty - populated by discovery at runtime
network: mode: allowlist hosts: - "api.github.com:443" - "github.com:443"
credentials: - name: GITHUB_TOKEN scope: user required: true description: > GitHub Personal Access Token. Create one at: https://github.com/settings/personal-access-tokens
Required scopes: 'repo' for private repositories, 'public_repo' for public repositories only.
resources: max_memory_mb: 256 max_cpu_fraction: 0.8Validation
Section titled “Validation”The Selu orchestrator validates manifests when loading capabilities. Common validation errors:
- Missing required fields — All capabilities must have
idandimage - Invalid network hosts — Must be in
"host:port"format or just"host" - Invalid tool schemas —
input_schemamust be valid JSON Schema - Invalid credential scopes — Must be
"system"or"user" - Invalid policy values — Must be
"allow","ask", or"block" - Dynamic mode conflicts —
tool_source: dynamicrequires emptytoolsarray - Filesystem restrictions —
filesystem: workspaceonly allowed forclass: environment
Next steps
Section titled “Next steps”See Container Guidelines for how to implement the capability server, or check out the gRPC Interface for the protocol details.