Assignment(nameof(QuestStep.ContentFinderConditionId),
                                     step.ContentFinderConditionId, emptyStep.ContentFinderConditionId)
                                 .AsSyntaxNodeOrToken(),
+                            Assignment(nameof(QuestStep.AutoDutyEnabled),
+                                    step.AutoDutyEnabled, emptyStep.AutoDutyEnabled)
+                                .AsSyntaxNodeOrToken(),
                             Assignment(nameof(QuestStep.SkipConditions), step.SkipConditions,
                                     emptyStep.SkipConditions)
                                 .AsSyntaxNodeOrToken(),
 
         {
           "TerritoryId": 138,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 4
+          "ContentFinderConditionId": 4,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 146,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 56
+          "ContentFinderConditionId": 56,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 140,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 3
+          "ContentFinderConditionId": 3,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 148,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 2
+          "ContentFinderConditionId": 2,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 153,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 1
+          "ContentFinderConditionId": 1,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 148,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 6
+          "ContentFinderConditionId": 6,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 137,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 8
+          "ContentFinderConditionId": 8,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 139,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 57
+          "ContentFinderConditionId": 57,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 155,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 11
+          "ContentFinderConditionId": 11,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 331,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 58
+          "ContentFinderConditionId": 58,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 147,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 15
+          "ContentFinderConditionId": 15,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 147,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 16
+          "ContentFinderConditionId": 16,
+          "AutoDutyEnabled": true
         }
       ]
     },
         {
           "TerritoryId": 1053,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 830
+          "ContentFinderConditionId": 830,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 155,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 27
+          "ContentFinderConditionId": 27,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 156,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 32
+          "ContentFinderConditionId": 32,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 155,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 5
+          "ContentFinderConditionId": 5,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 155,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 5
+          "ContentFinderConditionId": 5,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 155,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 5
+          "ContentFinderConditionId": 5,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 397,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 36
+          "ContentFinderConditionId": 36,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 398,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 37
+          "ContentFinderConditionId": 37,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 418,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 39
+          "ContentFinderConditionId": 39,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 419,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 34
+          "ContentFinderConditionId": 34,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 399,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 31
+          "ContentFinderConditionId": 31,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 402,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 38
+          "ContentFinderConditionId": 38,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 463,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 141
+          "ContentFinderConditionId": 141,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 155,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 182
+          "ContentFinderConditionId": 182,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 152,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 219
+          "ContentFinderConditionId": 219,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 680,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 238
+          "ContentFinderConditionId": 238,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 614,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 241
+          "ContentFinderConditionId": 241,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 620,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 242
+          "ContentFinderConditionId": 242,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {\r
           "TerritoryId": 621,\r
           "InteractionType": "Duty",\r
-          "ContentFinderConditionId": 279\r
+          "ContentFinderConditionId": 279,\r
+          "AutoDutyEnabled": true\r
         }\r
       ]\r
     },\r
 
         {
           "TerritoryId": 614,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 585
+          "ContentFinderConditionId": 585,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 829,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 611
+          "ContentFinderConditionId": 611,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 813,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 676
+          "ContentFinderConditionId": 676,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 816,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 649
+          "ContentFinderConditionId": 649,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 817,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 651
+          "ContentFinderConditionId": 651,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 814,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 659
+          "ContentFinderConditionId": 659,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 814,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 714
+          "ContentFinderConditionId": 714,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 957,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 783
+          "ContentFinderConditionId": 783,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 957,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 789
+          "ContentFinderConditionId": 789,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 961,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 787
+          "ContentFinderConditionId": 787,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 956,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 786
+          "ContentFinderConditionId": 786,
+          "AutoDutyEnabled": true
         }
       ]
     },
         {
           "TerritoryId": 1030,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 790
+          "ContentFinderConditionId": 790,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 957,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 844
+          "ContentFinderConditionId": 844,
+          "AutoDutyEnabled": false
         }
       ]
     },
 
         {
           "TerritoryId": 1056,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 869
+          "ContentFinderConditionId": 869,
+          "AutoDutyEnabled": false
         }
       ]
     },
 
           "TerritoryId": 958,
           "InteractionType": "Duty",
           "Comment": "Lapis Manalis",
-          "ContentFinderConditionId": 896
+          "ContentFinderConditionId": 896,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 962,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 822
+          "ContentFinderConditionId": 822,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 1162,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 823
+          "ContentFinderConditionId": 823,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 1185,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 826
+          "ContentFinderConditionId": 826,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 1187,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 824
+          "ContentFinderConditionId": 824,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 1189,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 829
+          "ContentFinderConditionId": 829,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 1219,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 831
+          "ContentFinderConditionId": 831,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 1191,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 825
+          "ContentFinderConditionId": 825,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 1192,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 827
+          "ContentFinderConditionId": 827,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
         {
           "TerritoryId": 1191,
           "InteractionType": "Duty",
-          "ContentFinderConditionId": 1008
+          "ContentFinderConditionId": 1008,
+          "AutoDutyEnabled": true
         }
       ]
     },
 
                 "exclusiveMinimum": 0,
                 "exclusiveMaximum": 3000
               },
+              "AutoDutyEnabled": {
+                "type": "boolean"
+              },
               "DataId": {
                 "type": "null"
               },
 
 
     public JumpDestination? JumpDestination { get; set; }
     public uint? ContentFinderConditionId { get; set; }
+    public bool AutoDutyEnabled { get; set; }
     public SkipConditions? SkipConditions { get; set; }
 
     public List<List<QuestWorkValue>?> RequiredQuestVariables { get; set; } = new();
 
-using Dalamud.Configuration;
+using System.Collections.Generic;
+using Dalamud.Configuration;
 using Dalamud.Game.Text;
 using FFXIVClientStructs.FFXIV.Client.UI.Agent;
 using LLib.ImGui;
     public int Version { get; set; } = 1;
     public int PluginSetupCompleteVersion { get; set; }
     public GeneralConfiguration General { get; } = new();
+    public DutyConfiguration Duties { get; } = new();
     public NotificationConfiguration Notifications { get; } = new();
     public AdvancedConfiguration Advanced { get; } = new();
     public WindowConfig DebugWindowConfig { get; } = new();
         public bool ConfigureTextAdvance { get; set; } = true;
     }
 
+    internal sealed class DutyConfiguration
+    {
+        public bool RunInstancedContentWithAutoDuty { get; set; }
+        public HashSet<uint> WhitelistedDutyCfcIds { get; set; } = [];
+        public HashSet<uint> BlacklistedDutyCfcIds { get; set; } = [];
+    }
+
     internal sealed class NotificationConfiguration
     {
         public bool Enabled { get; set; } = true;
 
     private readonly LeveData _leveData;
 
     private readonly ICallGateProvider<object> _reloadDataIpc;
-    private readonly Dictionary<ElementId, Quest> _quests = new();
+    private readonly Dictionary<ElementId, Quest> _quests = [];
+    private readonly Dictionary<uint, (ElementId QuestId, QuestStep Step)> _contentFinderConditionIds = [];
 
     public QuestRegistry(IDalamudPluginInterface pluginInterface, QuestData questData,
         QuestValidator questValidator, JsonSchemaValidator jsonSchemaValidator,
     {
         _questValidator.Reset();
         _quests.Clear();
+        _contentFinderConditionIds.Clear();
 
         LoadQuestsFromAssembly();
         LoadQuestsFromProjectDirectory();
                 "Failed to load all quests from user directory (some may have been successfully loaded)");
         }
 
+        LoadCfcIds();
         ValidateQuests();
         Reloaded?.Invoke(this, EventArgs.Empty);
         try
         }
     }
 
+    private void LoadCfcIds()
+    {
+        foreach (var quest in _quests.Values)
+        {
+            foreach (var dutyStep in quest.AllSteps().Where(x =>
+                         x.Step.InteractionType == EInteractionType.Duty && x.Step.ContentFinderConditionId != null))
+            {
+                _contentFinderConditionIds[dutyStep.Step.ContentFinderConditionId!.Value] = (quest.Id, dutyStep.Step);
+            }
+        }
+    }
+
     private void ValidateQuests()
     {
         _questValidator.Validate(_quests.Values.Where(x => x.Source != Quest.ESource.Assembly).ToList());
             .Where(x => IsKnownQuest(x.QuestId))
             .ToList();
     }
+
+    public bool TryGetDutyByContentFinderConditionId(uint cfcId, out bool autoDutyEnabledByDefault)
+    {
+        if (_contentFinderConditionIds.TryGetValue(cfcId, out var value))
+        {
+            autoDutyEnabledByDefault = value.Step.AutoDutyEnabled;
+            return true;
+        }
+
+        autoDutyEnabledByDefault = false;
+        return false;
+    }
 }
 
 {
     internal sealed class Factory(
         AutomatonIpc automatonIpc,
+        AutoDutyIpc autoDutyIpc,
         TerritoryData territoryData) : SimpleTaskFactory
     {
         public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
             {
                 EInteractionType.Snipe when !automatonIpc.IsAutoSnipeEnabled =>
                     new Task(step.InteractionType, step.Comment),
-                EInteractionType.Duty =>
+                EInteractionType.Duty when !autoDutyIpc.IsConfiguredToRunContent(step.ContentFinderConditionId, step.AutoDutyEnabled) =>
                     new Task(step.InteractionType, step.ContentFinderConditionId.HasValue
                         ? territoryData.GetContentFinderConditionName(step.ContentFinderConditionId.Value)
                         : step.Comment),
 
 using System;
+using System.Collections.Generic;
 using Dalamud.Game.ClientState.Conditions;
 using Dalamud.Plugin.Services;
+using Questionable.Controller.Steps.Shared;
+using Questionable.Data;
+using Questionable.External;
 using Questionable.Functions;
 using Questionable.Model;
 using Questionable.Model.Questing;
 
 internal static class Duty
 {
-    internal sealed class Factory : SimpleTaskFactory
+    internal sealed class Factory(AutoDutyIpc autoDutyIpc) : ITaskFactory
     {
-        public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step)
+        public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
         {
             if (step.InteractionType != EInteractionType.Duty)
-                return null;
+                yield break;
 
             ArgumentNullException.ThrowIfNull(step.ContentFinderConditionId);
-            return new Task(step.ContentFinderConditionId.Value);
+
+            if (autoDutyIpc.IsConfiguredToRunContent(step.ContentFinderConditionId, step.AutoDutyEnabled))
+            {
+                yield return new StartAutoDutyTask(step.ContentFinderConditionId.Value);
+                yield return new WaitAutoDutyTask(step.ContentFinderConditionId.Value);
+                yield return new WaitAtEnd.WaitNextStepOrSequence();
+            }
+            else
+            {
+                yield return new OpenDutyFinderTask(step.ContentFinderConditionId.Value);
+            }
+        }
+    }
+
+    internal sealed record StartAutoDutyTask(uint ContentFinderConditionId) : ITask
+    {
+        public override string ToString() => $"StartAutoDuty({ContentFinderConditionId})";
+    }
+
+    internal sealed class StartAutoDutyExecutor(
+        AutoDutyIpc autoDutyIpc,
+        TerritoryData territoryData,
+        IClientState clientState) : TaskExecutor<StartAutoDutyTask>
+    {
+        protected override bool Start()
+        {
+            autoDutyIpc.StartInstance(Task.ContentFinderConditionId);
+            return true;
+        }
+
+        public override ETaskResult Update()
+        {
+            if (!territoryData.TryGetTerritoryIdForContentFinderCondition(Task.ContentFinderConditionId,
+                    out uint territoryId))
+                throw new TaskException("Failed to get territory ID for content finder condition");
+
+            return clientState.TerritoryType == territoryId ? ETaskResult.TaskComplete : ETaskResult.StillRunning;
+        }
+    }
+
+    internal sealed record WaitAutoDutyTask(uint ContentFinderConditionId) : ITask
+    {
+        public override string ToString() => $"Wait(AutoDuty, left instance {ContentFinderConditionId})";
+    }
+
+    internal sealed class WaitAutoDutyExecutor(
+        AutoDutyIpc autoDutyIpc,
+        TerritoryData territoryData,
+        IClientState clientState) : TaskExecutor<WaitAutoDutyTask>
+    {
+        protected override bool Start() => true;
+
+        public override ETaskResult Update()
+        {
+            if (!territoryData.TryGetTerritoryIdForContentFinderCondition(Task.ContentFinderConditionId,
+                    out uint territoryId))
+                throw new TaskException("Failed to get territory ID for content finder condition");
+
+            return clientState.TerritoryType != territoryId && autoDutyIpc.IsStopped()
+                ? ETaskResult.TaskComplete
+                : ETaskResult.StillRunning;
         }
     }
 
-    internal sealed record Task(uint ContentFinderConditionId) : ITask
+    internal sealed record OpenDutyFinderTask(uint ContentFinderConditionId) : ITask
     {
         public override string ToString() => $"OpenDutyFinder({ContentFinderConditionId})";
     }
 
-    internal sealed class OpenDutyWindowExecutor(
+    internal sealed class OpenDutyFinderExecutor(
         GameFunctions gameFunctions,
-        ICondition condition) : TaskExecutor<Task>
+        ICondition condition) : TaskExecutor<OpenDutyFinderTask>
     {
         protected override bool Start()
         {
 
 using Questionable.Controller.Steps.Common;
 using Questionable.Controller.Utils;
 using Questionable.Data;
+using Questionable.External;
 using Questionable.Functions;
 using Questionable.Model;
 using Questionable.Model.Questing;
     internal sealed class Factory(
         IClientState clientState,
         ICondition condition,
-        TerritoryData territoryData)
+        TerritoryData territoryData,
+        AutoDutyIpc autoDutyIpc)
         : ITaskFactory
     {
         public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
                 case EInteractionType.Snipe:
                     return [new WaitNextStepOrSequence()];
 
-                case EInteractionType.Duty:
+                case EInteractionType.Duty when !autoDutyIpc.IsConfiguredToRunContent(step.ContentFinderConditionId, step.AutoDutyEnabled):
                 case EInteractionType.SinglePlayerDuty:
                     return [new EndAutomation()];
 
 
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
 using System.Collections.Immutable;
 using System.Globalization;
 using System.Linq;
+using Dalamud.Game;
 using Dalamud.Plugin.Services;
+using Dalamud.Utility;
 using FFXIVClientStructs.FFXIV.Client.Game.Character;
 using Lumina.Excel.Sheets;
 
     private readonly ImmutableDictionary<ushort, uint> _dutyTerritories;
     private readonly ImmutableDictionary<uint, string> _instanceNames;
     private readonly ImmutableDictionary<uint, string> _contentFinderConditionNames;
+    private readonly ImmutableDictionary<uint, uint> _contentFinderConditionIds;
 
     public TerritoryData(IDataManager dataManager)
     {
 
         _instanceNames = dataManager.GetExcelSheet<ContentFinderCondition>()
             .Where(x => x.RowId > 0 && x.Content.RowId != 0 && x.ContentLinkType == 1 && x.ContentType.RowId != 6)
-            .ToImmutableDictionary(x => x.Content.RowId, x => x.Name.ToString());
+            .ToImmutableDictionary(x => x.Content.RowId, x => x.Name.ToDalamudString().ToString());
 
         _contentFinderConditionNames = dataManager.GetExcelSheet<ContentFinderCondition>()
             .Where(x => x.RowId > 0 && x.Content.RowId != 0 && x.ContentLinkType == 1 && x.ContentType.RowId != 6)
-            .ToImmutableDictionary(x => x.RowId, x => x.Name.ToString());
+            .ToImmutableDictionary(x => x.RowId, x => FixName(x.Name.ToDalamudString().ToString(), dataManager.Language));
+        _contentFinderConditionIds = dataManager.GetExcelSheet<ContentFinderCondition>()
+            .Where(x => x.RowId > 0 && x.Content.RowId != 0 && x.ContentLinkType == 1 && x.ContentType.RowId != 6)
+            .ToImmutableDictionary(x => x.RowId, x => x.TerritoryType.RowId);
     }
 
     public string? GetName(ushort territoryId) => _territoryNames.GetValueOrDefault(territoryId);
     public string? GetInstanceName(ushort instanceId) => _instanceNames.GetValueOrDefault(instanceId);
 
     public string? GetContentFinderConditionName(uint cfcId) => _contentFinderConditionNames.GetValueOrDefault(cfcId);
+
+    public bool TryGetTerritoryIdForContentFinderCondition(uint cfcId, out uint territoryId) =>
+        _contentFinderConditionIds.TryGetValue(cfcId, out territoryId);
+
+    private static string FixName(string name, ClientLanguage language)
+    {
+        if (string.IsNullOrEmpty(name) || language != ClientLanguage.English)
+            return name;
+
+        return string.Concat(name[0].ToString().ToUpper(CultureInfo.InvariantCulture), name.AsSpan(1));
+    }
 }
 
--- /dev/null
+using Dalamud.Plugin;
+using Dalamud.Plugin.Ipc;
+using Dalamud.Plugin.Ipc.Exceptions;
+using Microsoft.Extensions.Logging;
+using Questionable.Controller.Steps;
+using Questionable.Data;
+
+namespace Questionable.External;
+
+internal sealed class AutoDutyIpc
+{
+    private readonly Configuration _configuration;
+    private readonly TerritoryData _territoryData;
+    private readonly ILogger<AutoDutyIpc> _logger;
+    private readonly ICallGateSubscriber<uint,bool> _contentHasPath;
+    private readonly ICallGateSubscriber<uint,int,bool,object> _run;
+    private readonly ICallGateSubscriber<bool> _isStopped;
+
+    public AutoDutyIpc(IDalamudPluginInterface pluginInterface, Configuration configuration, TerritoryData territoryData, ILogger<AutoDutyIpc> logger)
+    {
+        _configuration = configuration;
+        _territoryData = territoryData;
+        _logger = logger;
+        _contentHasPath = pluginInterface.GetIpcSubscriber<uint, bool>("AutoDuty.ContentHasPath");
+        _run = pluginInterface.GetIpcSubscriber<uint, int, bool, object>("AutoDuty.Run");
+        _isStopped = pluginInterface.GetIpcSubscriber<bool>("AutoDuty.IsStopped");
+    }
+
+    public bool IsConfiguredToRunContent(uint? cfcId, bool autoDutyEnabled)
+    {
+        if (cfcId == null)
+            return false;
+
+        if (!_configuration.Duties.RunInstancedContentWithAutoDuty)
+            return false;
+
+        if (_configuration.Duties.BlacklistedDutyCfcIds.Contains(cfcId.Value))
+            return false;
+
+        if (_configuration.Duties.WhitelistedDutyCfcIds.Contains(cfcId.Value) &&
+            _territoryData.TryGetTerritoryIdForContentFinderCondition(cfcId.Value, out _))
+            return true;
+
+        return autoDutyEnabled && HasPath(cfcId.Value);
+    }
+
+    public bool HasPath(uint cfcId)
+    {
+        if (!_territoryData.TryGetTerritoryIdForContentFinderCondition(cfcId, out uint territoryType))
+            return false;
+
+        try
+        {
+            return _contentHasPath.InvokeFunc(territoryType);
+        }
+        catch (IpcError e)
+        {
+            _logger.LogWarning("Unable to query AutoDuty for path in territory {TerritoryType}: {Message}", territoryType, e.Message);
+            return false;
+        }
+    }
+
+    public void StartInstance(uint cfcId)
+    {
+        if (!_territoryData.TryGetTerritoryIdForContentFinderCondition(cfcId, out uint territoryType))
+            throw new TaskException($"Unknown ContentFinderConditionId {cfcId}");
+
+        try
+        {
+            _run.InvokeAction(territoryType, 0, true);
+        }
+        catch (IpcError e)
+        {
+            throw new TaskException($"Unable to run content with AutoDuty: {e.Message}", e);
+        }
+    }
+
+    public bool IsStopped()
+    {
+        try
+        {
+            return _isStopped.InvokeFunc();
+        }
+        catch (IpcError)
+        {
+            return true;
+        }
+    }
+}
 
         serviceCollection.AddSingleton<TextAdvanceIpc>();
         serviceCollection.AddSingleton<NotificationMasterIpc>();
         serviceCollection.AddSingleton<AutomatonIpc>();
+        serviceCollection.AddSingleton<AutoDutyIpc>();
     }
 
     private static void AddTaskFactories(ServiceCollection serviceCollection)
             .AddTaskFactoryAndExecutor<AethernetShard.Attune, AethernetShard.Factory, AethernetShard.DoAttune>();
         serviceCollection.AddTaskFactoryAndExecutor<Aetheryte.Attune, Aetheryte.Factory, Aetheryte.DoAttune>();
         serviceCollection.AddTaskFactoryAndExecutor<Combat.Task, Combat.Factory, Combat.HandleCombat>();
-        serviceCollection.AddTaskFactoryAndExecutor<Duty.Task, Duty.Factory, Duty.OpenDutyWindowExecutor>();
+        serviceCollection.AddTaskFactoryAndExecutor<Duty.OpenDutyFinderTask, Duty.Factory, Duty.OpenDutyFinderExecutor>();
+        serviceCollection.AddTaskExecutor<Duty.StartAutoDutyTask, Duty.StartAutoDutyExecutor>();
+        serviceCollection.AddTaskExecutor<Duty.WaitAutoDutyTask, Duty.WaitAutoDutyExecutor>();
         serviceCollection.AddTaskFactory<Emote.Factory>();
         serviceCollection.AddTaskExecutor<Emote.UseOnObject, Emote.UseOnObjectExecutor>();
         serviceCollection.AddTaskExecutor<Emote.UseOnSelf, Emote.UseOnSelfExecutor>();
 
 using System;
 using System.Collections.Generic;
+using System.Globalization;
 using System.Linq;
+using System.Numerics;
+using System.Text;
 using Dalamud.Game.Text;
+using Dalamud.Interface;
 using Dalamud.Interface.Colors;
 using Dalamud.Interface.Components;
 using Dalamud.Interface.Utility.Raii;
 using LLib.ImGui;
 using Lumina.Excel.Sheets;
 using Questionable.Controller;
+using Questionable.Data;
 using Questionable.External;
+using Questionable.Model;
 using GrandCompany = FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany;
 
 namespace Questionable.Windows;
 
 internal sealed class ConfigWindow : LWindow, IPersistableWindowConfig
 {
+    private const string DutyClipboardPrefix = "qst:duty:";
+    private const string DutyClipboardSeparator = ";";
+    private const string DutyWhitelistPrefix = "+";
+    private const string DutyBlacklistPrefix = "-";
+
     private static readonly List<(uint Id, string Name)> DefaultMounts = [(0, "Mount Roulette")];
 
     private readonly IDalamudPluginInterface _pluginInterface;
     private readonly NotificationMasterIpc _notificationMasterIpc;
     private readonly Configuration _configuration;
     private readonly CombatController _combatController;
+    private readonly QuestRegistry _questRegistry;
+    private readonly AutoDutyIpc _autoDutyIpc;
 
     private readonly uint[] _mountIds;
     private readonly string[] _mountNames;
     private readonly string[] _grandCompanyNames =
         ["None (manually pick quest)", "Maelstrom", "Twin Adder", "Immortal Flames"];
 
+    private readonly string[] _supportedCfcOptions =
+    [
+        $"{SeIconChar.Circle.ToIconChar()} Enabled (Default)",
+        $"{SeIconChar.Circle.ToIconChar()} Enabled",
+        $"{SeIconChar.Cross.ToIconChar()} Disabled"
+    ];
+
+    private readonly string[] _unsupportedCfcOptions =
+    [
+        $"{SeIconChar.Cross.ToIconChar()} Disabled (Default)",
+        $"{SeIconChar.Circle.ToIconChar()} Enabled",
+        $"{SeIconChar.Cross.ToIconChar()} Disabled"
+    ];
+
+    private readonly Dictionary<EExpansionVersion, List<DutyInfo>> _contentFinderConditionNames;
+
     public ConfigWindow(IDalamudPluginInterface pluginInterface,
         NotificationMasterIpc notificationMasterIpc,
         Configuration configuration,
         IDataManager dataManager,
-        CombatController combatController)
+        CombatController combatController,
+        TerritoryData territoryData,
+        QuestRegistry questRegistry,
+        AutoDutyIpc autoDutyIpc)
         : base("Config - Questionable###QuestionableConfig", ImGuiWindowFlags.AlwaysAutoResize)
     {
         _pluginInterface = pluginInterface;
         _notificationMasterIpc = notificationMasterIpc;
         _configuration = configuration;
         _combatController = combatController;
+        _questRegistry = questRegistry;
+        _autoDutyIpc = autoDutyIpc;
 
         var mounts = dataManager.GetExcelSheet<Mount>()
             .Where(x => x is { RowId: > 0, Icon: > 0 })
             .ToList();
         _mountIds = DefaultMounts.Select(x => x.Id).Concat(mounts.Select(x => x.MountId)).ToArray();
         _mountNames = DefaultMounts.Select(x => x.Name).Concat(mounts.Select(x => x.Name)).ToArray();
+
+        _contentFinderConditionNames = dataManager.GetExcelSheet<DawnContent>()
+            .Where(x => x.RowId > 0)
+            .Select(x => x.Content.ValueNullable)
+            .Where(x => x != null)
+            .Select(x => x!.Value)
+            .Select(x => new
+            {
+                Expansion = (EExpansionVersion)x.TerritoryType.Value.ExVersion.RowId,
+                CfcId = x.RowId,
+                Name = territoryData.GetContentFinderConditionName(x.RowId) ?? "?",
+                TerritoryId = x.TerritoryType.RowId,
+                ContentType = x.ContentType.RowId,
+                Level = x.ClassJobLevelRequired,
+                x.SortKey
+            })
+            .GroupBy(x => x.Expansion)
+            .ToDictionary(x => x.Key,
+                x => x.OrderBy(y => y.Level)
+                    .ThenBy(y => y.ContentType)
+                    .ThenBy(y => y.SortKey)
+                    .Select(y => new DutyInfo(y.CfcId, y.TerritoryId, $"{SeIconChar.LevelEn.ToIconChar()}{FormatLevel(y.Level)} {y.Name}"))
+                    .ToList());
     }
 
     public WindowConfig WindowConfig => _configuration.ConfigWindowConfig;
 
+    private static string FormatLevel(int level)
+    {
+        if (level == 0)
+            return string.Empty;
+
+        return $"{FormatLevel(level / 10)}{(SeIconChar.Number0 + level % 10).ToIconChar()}";
+    }
+
     public override void Draw()
     {
         using var tabBar = ImRaii.TabBar("QuestionableConfigTabs");
             return;
 
         DrawGeneralTab();
+        DrawDutiesTab();
         DrawNotificationsTab();
         DrawAdvancedTab();
     }
         }
     }
 
+    private void DrawDutiesTab()
+    {
+        using var tab = ImRaii.TabItem("Duties");
+        if (!tab)
+            return;
+
+        bool runInstancedContentWithAutoDuty = _configuration.Duties.RunInstancedContentWithAutoDuty;
+        if (ImGui.Checkbox("Run instanced content with AutoDuty and BossMod", ref runInstancedContentWithAutoDuty))
+        {
+            _configuration.Duties.RunInstancedContentWithAutoDuty = runInstancedContentWithAutoDuty;
+            Save();
+        }
+
+        ImGui.SameLine();
+        ImGuiComponents.HelpMarker(
+            "The combat module used for this is configured by AutoDuty, ignoring whichever selection you've made in Questionable's \"General\" configuration.");
+
+        ImGui.Separator();
+
+        using (ImRaii.Disabled(!runInstancedContentWithAutoDuty))
+        {
+            ImGui.Text(
+                "Questionable includes a default list of duties that work if AutoDuty and BossMod are installed.");
+
+            ImGui.Text("The included list of duties can change with each update, and is based on the following spreadsheet:");
+            if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.GlobeEurope, "Open AutoDuty spreadsheet"))
+                Util.OpenLink(
+                    "https://docs.google.com/spreadsheets/d/151RlpqRcCpiD_VbQn6Duf-u-S71EP7d0mx3j1PDNoNA/edit?pli=1#gid=0");
+
+            ImGui.Separator();
+            ImGui.Text("You can override the dungeon settings for each individual dungeon/trial:");
+
+            using (var child = ImRaii.Child("DutyConfiguration", new Vector2(-1, 400), true))
+            {
+                if (child)
+                {
+                    foreach (EExpansionVersion expansion in Enum.GetValues<EExpansionVersion>())
+                    {
+                        if (ImGui.CollapsingHeader(expansion.ToString()))
+                        {
+                            using var table = ImRaii.Table($"Duties{expansion}", 2, ImGuiTableFlags.SizingFixedFit);
+                            if (table)
+                            {
+                                ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthStretch);
+                                ImGui.TableSetupColumn("Options", ImGuiTableColumnFlags.WidthFixed, 200f);
+
+                                if (_contentFinderConditionNames.TryGetValue(expansion, out var cfcNames))
+                                {
+                                    foreach (var (cfcId, territoryId, name) in cfcNames)
+                                    {
+                                        if (_questRegistry.TryGetDutyByContentFinderConditionId(cfcId,
+                                                out bool autoDutyEnabledByDefault))
+                                        {
+                                            ImGui.TableNextRow();
+
+                                            string[] labels = autoDutyEnabledByDefault
+                                                ? _supportedCfcOptions
+                                                : _unsupportedCfcOptions;
+                                            int value = 0;
+                                            if (_configuration.Duties.WhitelistedDutyCfcIds.Contains(cfcId))
+                                                value = 1;
+                                            if (_configuration.Duties.BlacklistedDutyCfcIds.Contains(cfcId))
+                                                value = 2;
+
+                                            if (ImGui.TableNextColumn())
+                                            {
+                                                ImGui.AlignTextToFramePadding();
+                                                ImGui.TextUnformatted(name);
+                                                if (ImGui.IsItemHovered() && _configuration.Advanced.AdditionalStatusInformation)
+                                                {
+                                                    using var tooltip = ImRaii.Tooltip();
+                                                    if (tooltip)
+                                                    {
+                                                        ImGui.TextUnformatted(name);
+                                                        ImGui.Separator();
+                                                        ImGui.BulletText($"TerritoryId: {territoryId}");
+                                                        ImGui.BulletText($"ContentFinderConditionId: {cfcId}");
+                                                    }
+                                                }
+
+                                                if (runInstancedContentWithAutoDuty && !_autoDutyIpc.HasPath(cfcId))
+                                                    ImGuiComponents.HelpMarker("This duty is not supported by AutoDuty", FontAwesomeIcon.Times, ImGuiColors.DalamudRed);
+                                            }
+
+                                            if (ImGui.TableNextColumn())
+                                            {
+                                                using var _ = ImRaii.PushId($"##Dungeon{cfcId}");
+                                                ImGui.SetNextItemWidth(200);
+                                                if (ImGui.Combo(string.Empty, ref value, labels, labels.Length))
+                                                {
+                                                    _configuration.Duties.WhitelistedDutyCfcIds.Remove(cfcId);
+                                                    _configuration.Duties.BlacklistedDutyCfcIds.Remove(cfcId);
+
+                                                    if (value == 1)
+                                                        _configuration.Duties.WhitelistedDutyCfcIds.Add(cfcId);
+                                                    else if (value == 2)
+                                                        _configuration.Duties.BlacklistedDutyCfcIds.Add(cfcId);
+
+                                                    Save();
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            using (ImRaii.Disabled(_configuration.Duties.WhitelistedDutyCfcIds.Count +
+                       _configuration.Duties.BlacklistedDutyCfcIds.Count == 0))
+            {
+                if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Copy, "Export to clipboard"))
+                {
+                    var whitelisted =
+                        _configuration.Duties.WhitelistedDutyCfcIds.Select(x => $"{DutyWhitelistPrefix}{x}");
+                    var blacklisted =
+                        _configuration.Duties.BlacklistedDutyCfcIds.Select(x => $"{DutyBlacklistPrefix}{x}");
+                    string text = DutyClipboardPrefix + Convert.ToBase64String(Encoding.UTF8.GetBytes(
+                        string.Join(DutyClipboardSeparator, whitelisted.Concat(blacklisted))));
+                    ImGui.SetClipboardText(text);
+                }
+            }
+
+            ImGui.SameLine();
+
+            string? clipboardText = GetClipboardText();
+            using (ImRaii.Disabled(clipboardText == null || !clipboardText.StartsWith(DutyClipboardPrefix, StringComparison.InvariantCulture)))
+            {
+                if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Paste, "Import from Clipboard"))
+                {
+                    clipboardText = clipboardText!.Substring(DutyClipboardPrefix.Length);
+                    string text = Encoding.UTF8.GetString(Convert.FromBase64String(clipboardText));
+
+                    _configuration.Duties.WhitelistedDutyCfcIds.Clear();
+                    _configuration.Duties.BlacklistedDutyCfcIds.Clear();
+                    foreach (string part in text.Split(DutyClipboardSeparator))
+                    {
+                        if (part.StartsWith(DutyWhitelistPrefix, StringComparison.InvariantCulture) &&
+                            uint.TryParse(part.AsSpan(DutyWhitelistPrefix.Length), CultureInfo.InvariantCulture,
+                                out uint whitelistedCfcId))
+                            _configuration.Duties.WhitelistedDutyCfcIds.Add(whitelistedCfcId);
+
+                        if (part.StartsWith(DutyBlacklistPrefix, StringComparison.InvariantCulture) &&
+                            uint.TryParse(part.AsSpan(DutyBlacklistPrefix.Length), CultureInfo.InvariantCulture,
+                                out uint blacklistedCfcId))
+                            _configuration.Duties.WhitelistedDutyCfcIds.Add(blacklistedCfcId);
+                    }
+                }
+            }
+
+            ImGui.SameLine();
+
+            using (var unused = ImRaii.Disabled(!ImGui.IsKeyDown(ImGuiKey.ModCtrl)))
+            {
+                if (ImGui.Button("Reset to default"))
+                {
+                    _configuration.Duties.WhitelistedDutyCfcIds.Clear();
+                    _configuration.Duties.BlacklistedDutyCfcIds.Clear();
+                    Save();
+                }
+            }
+
+            if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
+                ImGui.SetTooltip("Hold CTRL to enable this button.");
+        }
+    }
+
     private void DrawNotificationsTab()
     {
         using var tab = ImRaii.TabItem("Notifications");
     private void Save() => _pluginInterface.SavePluginConfig(_configuration);
 
     public void SaveWindowConfig() => Save();
+
+    /// <summary>
+    /// The default implementation for <see cref="ImGui.GetClipboardText"/> throws an NullReferenceException if the clipboard is empty, maybe also if it doesn't contain text.
+    /// </summary>
+    private unsafe string? GetClipboardText()
+    {
+        byte* ptr = ImGuiNative.igGetClipboardText();
+        if (ptr == null)
+            return null;
+
+        int byteCount = 0;
+        while (ptr[byteCount] != 0)
+            ++byteCount;
+        return Encoding.UTF8.GetString(ptr, byteCount);
+    }
+
+    private sealed record DutyInfo(uint CfcId, uint TerritoryId, string Name);
 }