Details of all options available in config.json
When adding a new app to the Companion App Store, you need to create a config.json file in the appβs folder. This file contains all the information needed to run the app. Below you can find all the options available in the config.json file.
| Option | Description | Example value | Required |
|---|---|---|---|
| name | Name of the app | Nextcloud | yes |
| id | This should be the same name as the folder | nextcloud | yes |
| available | If set to false, the app will not be available in the app store | true | yes |
| short_desc | Short description of the app | Nextcloud is a suite of client-server software for creating and using file hosting services. | yes |
| author | The GitHub name of the author | https://nextcloud.comΒ | yes |
| port | Port used by the app. This port will be exposed to the host. | 8100 | yes |
| categories | One or more categories for the app | [βutilitiesβ, βnetworkβ] | yes |
| description | Long description of the app | Nextcloud is a suite of client-server software for creating and using file hosting services. Nextcloud is free and open-source, which means that anyone is allowed to install and operate it on their own private server devices. | yes |
| cihub_app_version | App manifest version. Start at 1 for new apps; increment when you change compose or config | 10 | yes |
| tipi_version | Legacy alias for cihub_app_version β still accepted but prefer cihub_app_version | 1 | no |
| version | The actual version of the app (not the Companion Hub version) | 1.25.1 | yes |
| source | Link for git repository | https://github.com/nextcloud/dockerΒ | yes |
| website | Link to the official website | https://nextcloud.comΒ | no |
| exposable | If set to true, the app will allow the user to expose it via a domain name. | true | yes |
| force_expose | If set to true, the app will require a domain name. | true | no |
| generate_vapid_keys | If set to true, the app will generate VAPID keys for web push notifications. VAPID_PUBLIC_KEY and VAPID_PRIVATE_KEY will be available as environment variables | true | no |
| url_suffix | If set, the app will be accessible at https://<your-domain>/<url_suffix> | my-app | no |
| https | If set to true, the app will be accessible via https only. | true | no |
| no_gui | Set to true for apps with no GUI. Open button will be hidden | true | no |
| supported_architectures | If the app is only available for a specific architecture, you can specify it here. If not given, app will be available for all architectures | [βarm64β, βamd64β] | yes |
| uid, gid | These parameters allow you to give a specific set of permission for the appβs data folder. Companion Hub will automatically chown the data directory with the provided gid and uid. Both options need to be specified in order to apply | 1000 | no |
| form_fields | Form fields allow you to promt the user for input during the install, like a username or a password | See below | yes |
| dynamic | Use the new docker-compose.json to dynamically generate a compose file. See Dynamic Compose | true | no |
| deprecated | If the app is deprecated it wonβt exist in the app store and it will notify users that is no longer maintained. | false | no |
| min_hub_version | Minimum Companion Hub version required for this app | v4.5.0 | no |
| min_tipi_version | Legacy alias for min_hub_version | v3.0.0 | no |
| dynamic_config | Use docker-compose.json dynamic compose (recommended for new apps) | true | no |
| hub_integration | Opt-in Hub features: MCP client, inference variable mapping β see below | { "mcp_client": true } | no |
| created_at | The date the app was created. You can use new Date().getTime() in your browser console to get the current timestamp | 1724134938430 | no |
| updated_at | The date the app was last updated. You can use new Date().getTime() in your browser console to get the current timestamp | 1724134938430 | no |
Sometimes an app requires additional information to run, such as a username or a password. You can leverage the form_fields property in the config.json file to request that information. Hereβs an example:
{
"form_fields": [
{
"type": "text",
"label": "Username",
"max": 50,
"min": 3,
"required": true,
"env_variable": "NEXTCLOUD_ADMIN_USER"
},
{
"type": "password",
"label": "Password",
"max": 50,
"min": 3,
"required": true,
"env_variable": "NEXTCLOUD_ADMIN_PASSWORD"
}
]
}You can choose between different types of fields. The app will automatically validate the user input before submitting.
| Type | Description | Example value |
|---|---|---|
| text | Just a string of text | username |
| password | Will be hidden on typing | password |
| An email address | test@example.org | |
| number | Any number | 123 |
| fqdn | Fully qualified domain name | example.org |
| ip | Any valid IPv4 address | 192.168.2.100 |
| fqdnip | Combination between IPv4 and FQDN | 192.168.2.100 or example.org |
| random | Generate a random value for the user | 2e318419a49b70ad93766a5d6eb54d9ebbcceaeadd57c5f6897dbbe10afbc880 |
| boolean | A checkbox | true or false |
Here is a table of the available form_field properties:
| Name | Description | Example value | Required |
|---|---|---|---|
| type | The type of the form field to use, see above. | text | β |
| label | The label to show the user. | Nextcloud Username | β |
| hint | A small hint to show the user. | The username you want to use for nextcloud | β |
| placeholder | A placeholder for the form field | user | β |
| default | Add a default value, used only if the required option is set to false | user | β |
| regex | Use a regex pattern to verify the user input | ^[0-9]+\.[0-9]+\.[0-9]+$ | β |
| pattern_error | The error to show when the regex pattern validation fails | Invalid username | β |
| min | The minimum length for a text or password input | 5 | β |
| max | The maximum length for a text or password input | 100 | β |
| required | Whether the form field is required or not | true | β |
| env_variable | The name of the variable youβll use in your docker-compose.yml file. | NEXTCLOUD_USERNAME | β |
| options | Options for multi-select | See below | β |
| encoding | Used only in addition to random type. Specify the random value encoding (base64 or hex) | base64 | β |
When you use the random field type for a password or secret, the min value determines the generated string length. If min is omitted, a default length of 32 characters is used.
Using options in form fields
You can create a form field with options like this in your config.json. It will be rendered as a multi-select dropdown in the UI.
label is what will be shown to the user and value is the actual value the environment variable will be set to when the corresponding option is selected.
Use options only when there are only specific pre-defined values for the field. If a user might want to use a custom value, use a normal text field and provide common examples in the label.
Hub integration (hub_integration)
Apps can opt in to Hub-provided environment variables and services.
MCP client
Agent apps that connect to Hub MCP set:
{
"hub_integration": {
"mcp_client": true,
"wake_endpoint": "/hooks/hub-wake",
"wake_port": 3000,
"sse_events": false
}
}When enabled, Hub injects HUB_URL, HUB_MCP_URL, HUB_MCP_MESSAGES_URL, HUB_MCP_API_KEY, and HUB_WAKE_SECRET into the appβs environment.
Inference variables
AI apps map standardized Hub inference keys to their own env variable names:
{
"hub_integration": {
"inference": {
"llm_base_url": "LLM_API_BASE",
"llm_api_key": "LLM_API_KEY",
"chat_model": "LLM_DEFAULT_CHAT_MODEL",
"embedding_model": "LLM_DEFAULT_EMBEDDING_MODEL",
"vision_model": "LLM_DEFAULT_VISION_MODEL",
"ollama_host": "OLLAMA_HOST"
}
}
}| Hub key | Hub resolves to | Description |
|---|---|---|
llm_base_url | OpenAI-compatible base URL | Ollama /v1 or cloud provider |
llm_api_key | API key | "ollama" for local Ollama |
chat_model | Chat model ID | From preferences or hardware recommendations |
embedding_model | Embedding model ID | From preferences or recommendations |
vision_model | Vision model ID | From preferences or recommendations |
ollama_host | Native Ollama URL | Direct Ollama API (not OpenAI-compatible) |
See AI & Inference for resolution order and setup.
{
"label": "Select your favorite fruits",
"type": "text",
"required": true,
"options": [
{ "label": "Apple", "value": "apple" },
{ "label": "Banana", "value": "banana" },
{ "label": "Orange", "value": "orange" }
],
"env_variable": "fruits"
}