The self-hosted recipe manager Mealie startet to support sending a recipe to a Bring shopping list with this PR. However, this requires the Mealie instance to be publicly available (from the internet). Since many users want their self-hosted services to not be available from the internet, I chose to create this integration.
This project provides a simple webserver which offers two main actions:
- Adding ingredients from a Mealie recipe to a specified Bring shopping list
- Moving all ingredients from a Mealie shopping list to a specified Bring shopping list (optional)
If you like the project, please consider giving it a star on GitHub, thank you very much! â
- The
Mealie instancesends aGETrequest to the recipe toAPI of bring(See Bring API docs).- The link looks like
this
https://api.getbring.com/rest/bringrecipes/deeplink?url=<mealieinstance>g/home/r/<recipe>&source=web.
- The link looks like
this
Bringthen does aGETrequest to theMealie instanceand pulls the ingredients.- In order for this to work the
Mealie instancehas to be reachable from the public internet. - This opens an attack vector as anyone can access the
Mealie instance.
- In order for this to work the
- The
client(e.g. your phone or PC) sends aPOSTrequest to theMealie instanceinstructing it to trigger the adding of the ingredients. - The
Mealie instancesends aPOSTrequest to thiswebserverat the endpoint/with the ingredients in its body. An example for such a request can be found in the tests. - The
webserverextracts the ingredients from the request and adds them directly to a list of the users choice via theBring API.
- The
client(e.g. your phone or PC) sends aPOSTrequest to thiswebserverat the endpoint/move-ingredients-from-shopping-list. - The
webserverconnects to theMealie instanceusing the provided API key, retrieves all items from the specified shopping list, and removes them from the Mealie shopping list. - The
webserveradds these items to the specified Bring shopping list via theBring APIand removes them from shopping list in Mealie.
This integration runs entirely local and does not require any service to be exposed to the Internet.
Deployment can be done in three simple steps:
- Figure out the environment variables you want/need to set
- Choose a deployment option
- Configure Mealie
No matter which deployment option you chose, you must set up some environment variables:
| Variable name | Description | Required | Default | Example | Required for Action |
|---|---|---|---|---|---|
BRING_USERNAME |
The email address of your bring account | Yes | - | [email protected] |
1, 2 |
BRING_PASSWORD |
The password of your bring account | Yes | - | my super secret password |
1, 2 |
BRING_LIST_NAME |
The exact name of the list you want to add the ingredients to, supports special characters | Yes | - | My shopping list with spaces |
1, 2 |
MEALIE_BASE_URL |
The base URL of your Mealie instance (e.g. http://mealie:9000 or https://mealie.yourdomain.com) |
No | - | http://mealie:9000 |
2 |
MEALIE_API_KEY |
The API key for your Mealie instance. Can be generated in Mealie under https://mealie.yourdomain.com/user/profile/api-tokens |
No | - | mealie_api_key_123456 |
2 |
MEALIE_SHOPPING_LIST_UUID |
The UUID of the shopping list you want to pull items from. If not specified, items from all shopping lists will be pulled | No | - | 12345678-1234-1234-1234-12345678 |
2 |
LOG_LEVEL |
The loglevel the application logs at | No | INFO |
DEBUG |
1, 2 |
HTTP_HOST |
The address the application tries to attach to, leave this empty to listen on all interfaces, leave this empty if you are using Docker | No | 0.0.0.0 |
192.168.1.5 |
1, 2 |
HTTP_PORT |
The port the application listens on, change this if needed if you run the application locally, leave this empty if you are using Docker | No | 8742 |
1234 |
1, 2 |
HTTP_BASE_PATH |
The path the application listens on. Use this if you use the app behind a reverse proxy and have setup a path (e.g. set this to /bring if the application shall listen on <mealie>.<yourdomain>.tld/bring) |
No | "" |
/bring |
1, 2 |
Ensure to quote your environment variables. Without quotes your password might not be read properly if it contains symbols such as <, & or ;.
It is possible to define ingredients that shall never be added to the shopping list. These are ingredients you always have at home (e.g., salt and pepper).
To do so
-
Open the
Data Management(under<your mealie domain>/group/data/foods/). -
Search for the ingredient you don't want to be added to the shopping list.
-
Click on the edit button.
-
Enable the checkbox
On Hand.
You can run this app in three simple ways. I prefer the third option. Depending on the deployment option you chose
you can ignore some environment variables (e.g. HTTP_HOST and HTTP_PORT).
- Copy the contents
./assets/env.exampleto./.envand adjust the environment variables to your needs. - Install the requirements with
poetry install. - Run
python source/main.py.
- Run
docker run mealie-apiand pass in your environment variables with-e.- You can (not must) specify a different port than the default (
8742) with-p 1234:8742. - Example:
docker run \ -e BRING_USERNAME="[email protected]" \ -e BRING_PASSWORD="my super secret password" \ -e BRING_LIST_NAME="My shopping list with spaces" \ -p 1234:8742 \ ghcr.io/felixschndr/mealie-bring-api:latest
- You can (not must) specify a different port than the default (
- Add this container to your existing docker-compose next to your Mealie instance or create a new docker-compose and adjust the environment variables to your needs. Take a look at the example docker-compose.
- Run
docker-compose up.
After deploying the container, you need to set up the actions you want to use.
-
Head over to
http(s)://<your-mealie-instance>/group/data/recipe-actions(e.g.,http://localhost:1234/group/data/recipe-actions) while being logged in as an administrator. -
Click on
Createto create a newaction. -
Give it any title (e.g.
BringorAdd ingredients to Bring). This will be visible for the users. -
For the
URLinput the address where this project is running on followed by a/(e.g.http://<ip-of-server>:8742/orhttps://mealie-bring-api.yourlocaldomain.com/if you are using a reverse proxy) -
Change the
TypetoPOST -
Save
-
Try it out đ
If you don't want to use this action, you can skip this entirely. If you want to use this action, you need to:
- Generate an API key in Mealie:
- Go to your profile in Mealie
- Navigate to the "API Keys" section (e.g.
https://mealie.yourdomain.com/user/profile/api-tokens) - Create a new API key with an appropriate name (e.g., "Bring Integration")
- Copy the generated key
- Set the required environment variables:
MEALIE_BASE_URL: The base URL of your Mealie instanceMEALIE_API_KEY: The API key you just generatedMEALIE_SHOPPING_LIST_UUID(optional): If you want to pull items from a specific shopping list only. The items of all shopping lists will be pulled if this is empty.
- Add a new action the same way as
Action 1is added, but set the path to/move-ingredients-from-shopping-list( e.g.http://<ip-of-server>:8742/move-ingredients-from-shopping-listorhttps://mealie-bring-api.yourlocaldomain.com/move-ingredients-from-shopping-listif you are using a reverse proxy) - Try it out đ
-
Head over to a recipe of your choice in Mealie.
-
Click on the three little dots.
-
Click on
Recipe Actions -
Choose your new action (e.g.
Bring) -
That's it!
- You should now see the ingredients in your list
- You should see some output in the logfile
[2025-07-28 15:23:11,785] [BringHandler] [INFO] Attempting the login into Bring [2025-07-28 15:23:12,589] [BringHandler] [INFO] Login successful [2025-07-28 15:23:12,729] [BringHandler] [INFO] Found the list with the name "My List" (UUID: 12345678-1234-1234-1234-12345678) [2025-07-28 15:24:33,872] [Main] [INFO] Received recipe "Apfelstrudel" from "1.2.3.4" [2025-07-28 15:24:33,873] [Main] [INFO] Adding ingredients to Bring: [Ingredient(name='Butter', specification='60 Gramm'), Ingredient(name='Semmelbrösel', specification='80 Gramm (oder Mandelsplitter)'), Ingredient(name='Mandelsplitter', specification='80 Gramm'), Ingredient(name='Zitronensaft', specification='30 Milliliter'), Ingredient(name='Zucker', specification='80 Gramm'), Ingredient(name='Zimt', specification='1 Teelöffel'), Ingredient(name='Apfel', specification='1 Kilogramm'), Ingredient(name='Rosinen', specification='150 Gramm')]
-
Add the items of your recipes to your Mealie shopping list or add items manually.
-
After you add all the items, you want to move to Bring open any recipe
-
Click on
Recipe Actions -
Choose your new action (e.g.
Move items to Bring) -
That's it!
- The items will be removed from your Mealie shopping list and added to your Bring shopping list.
- You should see some output in the logfile
[2025-07-28 16:45:21,123] [MealieHandler] [INFO] Connection to Mealie successful [2025-07-28 16:45:23,012] [Main] [INFO] Moving ingredients from shopping list to Bring [2025-07-28 16:45:23,345] [MealieHandler] [INFO] Filtering for shopping list with UUID aa3632b1-b51e-4a3c-914e-5c703fa5c15a [2025-07-28 16:45:24,012] [MealieHandler] [DEBUG] Deleting 3 items from shopping list [2025-07-28 16:45:24,345] [[Main] [INFO] Adding ingredients to Bring: [Ingredient(name='Butter', specification='60 Gramm'), Ingredient(name='Semmelbrösel', specification='80 Gramm (oder Mandelsplitter)'), Ingredient(name='Mandelsplitter', specification='80 Gramm'), Ingredient(name='Zitronensaft', specification='30 Milliliter'), Ingredient(name='Zucker', specification='80 Gramm'), Ingredient(name='Zimt', specification='1 Teelöffel'), Ingredient(name='Apfel', specification='1 Kilogramm'), Ingredient(name='Rosinen', specification='150 Gramm')]
You can check whether the webserver is still alive by sending a GET request to /status and check if you get a 200
status code:
$ curl -I https://mealie-bring-api.yourlocaldomain.com/status
HTTP/2 200
server: openresty
date: Mon, 20 May 2024 12:27:56 GMT
content-type: text/html; charset=utf-8
content-length: 2
strict-transport-security: max-age=63072000; preloador
$ curl -s -o /dev/null -w "%{http_code}" https://mealie-bring-api.yourlocaldomain.com/status
200





