diff --git a/webservice/update_mdc.py b/webservice/update_mdc.py
index fd68354adaeb3ed3565b032709acf6c3ccb119ed..cb1a9dfccdd468cbbe1ffd46893de714dbd65fee 100644
--- a/webservice/update_mdc.py
+++ b/webservice/update_mdc.py
@@ -5,6 +5,15 @@ from metadata_client.metadata_client import MetadataClient
 
 from .config import webservice as config
 
+def parse_int_range(s):
+    try:
+        return [int(s)]
+    except ValueError:
+        parts = s.split('-')
+        if len(parts) != 2:
+            raise ValueError(f"Range ({s!r}) not like '6' or '5-10'")
+        return list(range(int(parts[0]), int(parts[1]) + 1))
+
 parser = argparse.ArgumentParser(
     description='Update run status at MDC for a given run id.')
 #  TODO: unify configuration argument names across the project
@@ -12,18 +21,17 @@ parser.add_argument('--conf-file', type=str, help='Path to webservice config',
                     default=None)
 parser.add_argument('--flg', type=str, choices=["NA", "R", "A"], required=True,
                     help='Status flag for MDC request: NA - not available, R - running, A - available.')  # noqa
+parser.add_argument('--proposal', type=int, help="Proposal number")
+parser.add_argument('--runs', type=parse_int_range,
+                    help="Run number or inclusive range, e.g. '90-96'")
 parser.add_argument('--rid', type=int, help='Run id from MDC')
 parser.add_argument('--msg', type=str, help='Message string to MDC',
                     default='Error while job submission')
-args = vars(parser.parse_args())
-
-conf_file = args['conf_file']
-rid = args['rid']
-flg = args['flg']
-msg = args['msg']
+parser.add_argument('--really', help="Actually make changes (otherwise dry-run)")
+args = parser.parse_args()
 
-if conf_file is not None:
-    config.configure(includes_for_dynaconf=[Path(conf_file).absolute()])
+if args.conf_file is not None:
+    config.configure(includes_for_dynaconf=[Path(args.conf_file).absolute()])
 
 mdconf = config['metadata-client']
 client_conn = MetadataClient(client_id=mdconf['user-id'],
@@ -35,11 +43,27 @@ client_conn = MetadataClient(client_id=mdconf['user-id'],
                              scope=mdconf['scope'],
                              base_api_url=mdconf['base-api-url'])
 
-print(f"Updating run {rid} to status {flg} at {mdconf['base-api-url']}")
-response = client_conn.update_run_api(rid, {'flg_cal_data_status': flg,
-                                            'cal_pipeline_reply': msg})
-
-if response.status_code == 200:
-    print('Run is updated')
+if args.rid:
+    rids = [args.rid]
 else:
-    print(f'Update failed {response}')
+    assert args.proposal and args.runs, "Specify --proposal and --runs, or --rid"
+    resp = client_conn.get_runs_by_proposal_number_api(args.proposal)
+    run_no_to_run_id = {r['run_number']: r['id'] for r in resp.json()['runs']}
+    rids = [run_no_to_run_id[n] for n in args.runs if n in run_no_to_run_id]
+
+for rid in rids:
+    print(f"Updating run {rid} to status {args.flg} at {mdconf['base-api-url']}")
+    if args.really:
+        response = client_conn.update_run_api(rid, {
+            'flg_cal_data_status': args.flg, 'cal_pipeline_reply': args.msg
+        })
+
+        if response.status_code == 200:
+            print('Run is updated')
+        else:
+            print(f'Update failed {response}')
+
+if not rids:
+    print("No runs selected")
+elif not args.really:
+    print("Add --really to actually make these changes")