diff --git a/lib/components/debug-logs-context-provider.react.js b/lib/components/debug-logs-context-provider.react.js
new file mode 100644
--- /dev/null
+++ b/lib/components/debug-logs-context-provider.react.js
@@ -0,0 +1,45 @@
+// @flow
+
+import * as React from 'react';
+
+import { type DebugLog, DebugLogsContext } from './debug-logs-context.js';
+
+type Props = {
+  +children: React.Node,
+};
+
+function DebugLogsContextProvider(props: Props): React.Node {
+  const [logs, setLogs] = React.useState<$ReadOnlyArray<DebugLog>>([]);
+
+  const addLog = React.useCallback(
+    (title: string, message: string) =>
+      setLogs(prevLogs => [
+        ...prevLogs,
+        {
+          title,
+          message,
+          timestamp: Date.now(),
+        },
+      ]),
+    [],
+  );
+
+  const clearLogs = React.useCallback(() => setLogs([]), []);
+
+  const contextValue = React.useMemo(
+    () => ({
+      logs,
+      addLog,
+      clearLogs,
+    }),
+    [addLog, clearLogs, logs],
+  );
+
+  return (
+    <DebugLogsContext.Provider value={contextValue}>
+      {props.children}
+    </DebugLogsContext.Provider>
+  );
+}
+
+export { DebugLogsContextProvider };
diff --git a/lib/components/debug-logs-context.js b/lib/components/debug-logs-context.js
new file mode 100644
--- /dev/null
+++ b/lib/components/debug-logs-context.js
@@ -0,0 +1,31 @@
+// @flow
+
+import invariant from 'invariant';
+import * as React from 'react';
+
+export type DebugLog = {
+  +title: string,
+  +message: string,
+  +timestamp: number,
+};
+
+export type DebugLogsContextType = {
+  +logs: $ReadOnlyArray<DebugLog>,
+  +addLog: (title: string, message: string) => mixed,
+  +clearLogs: () => mixed,
+};
+
+const DebugLogsContext: React.Context<DebugLogsContextType> =
+  React.createContext<DebugLogsContextType>({
+    logs: [],
+    addLog: () => {},
+    clearLogs: () => {},
+  });
+
+function useDebugLogs(): DebugLogsContextType {
+  const debugLogsContext = React.useContext(DebugLogsContext);
+  invariant(debugLogsContext, 'Debug logs context should be present');
+  return debugLogsContext;
+}
+
+export { DebugLogsContext, useDebugLogs };
diff --git a/native/navigation/route-names.js b/native/navigation/route-names.js
--- a/native/navigation/route-names.js
+++ b/native/navigation/route-names.js
@@ -188,6 +188,7 @@
 export const SecondaryDeviceConnectedRouteName = 'SecondaryDeviceConnected';
 export const SecondaryDeviceNotRespondingRouteName =
   'SecondaryDeviceNotResponding';
+export const DebugLogsScreenRouteName = 'DebugLogsScreen';
 
 export type RootParamList = {
   +LoggedOutModal: void,
@@ -304,6 +305,7 @@
   +KeyserverSelectionList: void,
   +AddKeyserver: void,
   +FarcasterAccountSettings: void,
+  +DebugLogsScreen: void,
 };
 
 export type CalendarParamList = {
diff --git a/native/profile/debug-logs-screen.react.js b/native/profile/debug-logs-screen.react.js
new file mode 100644
--- /dev/null
+++ b/native/profile/debug-logs-screen.react.js
@@ -0,0 +1,82 @@
+// @flow
+
+import Clipboard from '@react-native-clipboard/clipboard';
+import * as React from 'react';
+import { FlatList, View, Text } from 'react-native';
+
+import {
+  useDebugLogs,
+  type DebugLog,
+} from 'lib/components/debug-logs-context.js';
+
+import type { ProfileNavigationProp } from './profile.react.js';
+import PrimaryButton from '../components/primary-button.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useStyles } from '../themes/colors.js';
+
+type Props = {
+  +navigation: ProfileNavigationProp<'DebugLogsScreen'>,
+  +route: NavigationRoute<'DebugLogsScreen'>,
+};
+
+// eslint-disable-next-line no-unused-vars
+function DebugLogsScreen(props: Props): React.Node {
+  const { logs, clearLogs } = useDebugLogs();
+
+  const copyLogs = React.useCallback(() => {
+    Clipboard.setString(JSON.stringify(logs));
+  }, [logs]);
+
+  const styles = useStyles(unboundStyles);
+
+  const renderItem = React.useCallback(
+    ({ item }: { +item: DebugLog, ... }) => {
+      const date = new Date(item.timestamp);
+      const timestampString = date.toISOString();
+      return (
+        <View style={styles.item}>
+          <Text style={styles.timestamp}>{timestampString}</Text>
+          <Text style={styles.title}>{item.title}</Text>
+          <Text style={styles.message}>{item.message}</Text>
+        </View>
+      );
+    },
+    [styles.item, styles.message, styles.timestamp, styles.title],
+  );
+
+  return (
+    <View style={styles.view}>
+      <FlatList data={logs} renderItem={renderItem} />
+      <PrimaryButton onPress={clearLogs} variant="danger" label="Clear Logs" />
+      <PrimaryButton onPress={copyLogs} variant="enabled" label="Copy Logs" />
+    </View>
+  );
+}
+
+const unboundStyles = {
+  view: {
+    flex: 1,
+    backgroundColor: 'panelBackground',
+    padding: 24,
+  },
+  item: {
+    backgroundColor: 'panelForeground',
+    borderWidth: 1,
+    borderTopWidth: 1,
+    borderColor: 'panelForegroundBorder',
+    marginBottom: 8,
+    padding: 8,
+  },
+  timestamp: {
+    color: 'panelForegroundLabel',
+  },
+  title: {
+    color: 'panelForegroundLabel',
+    fontSize: 16,
+  },
+  message: {
+    color: 'panelForegroundSecondaryLabel',
+  },
+};
+
+export default DebugLogsScreen;
diff --git a/native/profile/profile-screen.react.js b/native/profile/profile-screen.react.js
--- a/native/profile/profile-screen.react.js
+++ b/native/profile/profile-screen.react.js
@@ -57,6 +57,7 @@
   KeyserverSelectionListRouteName,
   TunnelbrokerMenuRouteName,
   FarcasterAccountSettingsRouteName,
+  DebugLogsScreenRouteName,
 } from '../navigation/route-names.js';
 import { useSelector } from '../redux/redux-utils.js';
 import { type Colors, useColors, useStyles } from '../themes/colors.js';
@@ -199,7 +200,8 @@
     let developerTools,
       defaultNotifications,
       keyserverSelection,
-      tunnelbrokerMenu;
+      tunnelbrokerMenu,
+      debugLogs;
     const { staffCanSee } = this.props;
     if (staffCanSee) {
       developerTools = (
@@ -226,6 +228,10 @@
           onPress={this.onPressTunnelbrokerMenu}
         />
       );
+
+      debugLogs = (
+        <ProfileRow content="Debug logs" onPress={this.onPressDebugLogs} />
+      );
     }
 
     let backupMenu;
@@ -342,6 +348,7 @@
             <ProfileRow content="Build info" onPress={this.onPressBuildInfo} />
             {developerTools}
             {dmActions}
+            {debugLogs}
           </View>
           <View style={this.props.styles.unpaddedSection}>
             <ProfileRow
@@ -546,6 +553,10 @@
   onPressCreateThread = () => {
     void this.props.onCreateDMThread();
   };
+
+  onPressDebugLogs = () => {
+    this.props.navigation.navigate({ name: DebugLogsScreenRouteName });
+  };
 }
 
 const logOutLoadingStatusSelector =
diff --git a/native/profile/profile.react.js b/native/profile/profile.react.js
--- a/native/profile/profile.react.js
+++ b/native/profile/profile.react.js
@@ -14,6 +14,7 @@
 import AppearancePreferences from './appearance-preferences.react.js';
 import BackupMenu from './backup-menu.react.js';
 import BuildInfo from './build-info.react.js';
+import DebugLogsScreen from './debug-logs-screen.react.js';
 import DefaultNotificationsPreferences from './default-notifications-preferences.react.js';
 import DeleteAccount from './delete-account.react.js';
 import DevTools from './dev-tools.react.js';
@@ -52,6 +53,7 @@
   type ScreenParamList,
   type ProfileParamList,
   TunnelbrokerMenuRouteName,
+  DebugLogsScreenRouteName,
 } from '../navigation/route-names.js';
 import type { TabNavigationProp } from '../navigation/tab-navigator.react.js';
 import { useStyles, useColors } from '../themes/colors.js';
@@ -83,6 +85,7 @@
 const blockListOptions = { headerTitle: 'Block list' };
 const defaultNotificationsOptions = { headerTitle: 'Default Notifications' };
 const farcasterSettingsOptions = { headerTitle: 'Farcaster account' };
+const debugLogsScreenOptions = { headerTitle: 'Logs' };
 
 export type ProfileNavigationProp<
   RouteName: $Keys<ProfileParamList> = $Keys<ProfileParamList>,
@@ -222,6 +225,11 @@
             component={FarcasterAccountSettings}
             options={farcasterSettingsOptions}
           />
+          <Profile.Screen
+            name={DebugLogsScreenRouteName}
+            component={DebugLogsScreen}
+            options={debugLogsScreenOptions}
+          />
         </Profile.Navigator>
       </KeyboardAvoidingView>
     </View>
diff --git a/native/root.react.js b/native/root.react.js
--- a/native/root.react.js
+++ b/native/root.react.js
@@ -24,6 +24,7 @@
 import { PersistGate as ReduxPersistGate } from 'redux-persist/es/integration/react.js';
 
 import { ChatMentionContextProvider } from 'lib/components/chat-mention-provider.react.js';
+import { DebugLogsContextProvider } from 'lib/components/debug-logs-context-provider.react.js';
 import { EditUserAvatarProvider } from 'lib/components/edit-user-avatar-provider.react.js';
 import { ENSCacheProvider } from 'lib/components/ens-cache-provider.react.js';
 import { FarcasterChannelPrefetchHandler } from 'lib/components/farcaster-channel-prefetch-handler.react.js';
@@ -334,95 +335,97 @@
     );
   }
   return (
-    <GestureHandlerRootView style={styles.app}>
-      <StaffContextProvider>
-        <IdentityServiceContextProvider>
-          <UserIdentityCacheProvider>
-            <ENSCacheProvider
-              ethersProvider={ethersProvider}
-              alchemyKey={alchemyKey}
-            >
-              <NeynarClientProvider apiKey={neynarKey}>
-                <TunnelbrokerProvider>
-                  <IdentitySearchProvider>
-                    <SecondaryDeviceQRAuthContextProvider
-                      parseTunnelbrokerQRAuthMessage={
-                        parseTunnelbrokerQRAuthMessage
-                      }
-                      composeTunnelbrokerQRAuthMessage={
-                        composeTunnelbrokerQRAuthMessage
-                      }
-                      generateAESKey={generateQRAuthAESKey}
-                      performBackupRestore={performBackupRestore}
-                      onLogInError={handleSecondaryDeviceLogInError}
-                    >
-                      <FeatureFlagsProvider>
-                        <NavContext.Provider value={navContext}>
-                          <RootContext.Provider value={rootContext}>
-                            <InputStateContainer>
-                              <MessageEditingContextProvider>
-                                <SafeAreaProvider
-                                  initialMetrics={initialWindowMetrics}
-                                >
-                                  <ActionSheetProvider>
-                                    <MediaCacheProvider
-                                      persistence={filesystemMediaCache}
-                                    >
-                                      <EditUserAvatarProvider>
-                                        <NativeEditThreadAvatarProvider>
-                                          <MarkdownContextProvider>
-                                            <MessageSearchProvider>
-                                              <BottomSheetProvider>
-                                                <RegistrationContextProvider>
-                                                  <SQLiteDataHandler />
-                                                  <ConnectedStatusBar />
-                                                  <ReduxPersistGate
-                                                    persistor={getPersistor()}
-                                                  >
-                                                    {gated}
-                                                  </ReduxPersistGate>
-                                                  <PersistedStateGate>
-                                                    <KeyserverConnectionsHandler
-                                                      socketComponent={Socket}
-                                                      detectUnsupervisedBackgroundRef={
-                                                        detectUnsupervisedBackgroundRef
-                                                      }
-                                                    />
-                                                    <DMActivityHandler />
-                                                    <VersionSupportedChecker />
-                                                    <PlatformDetailsSynchronizer />
-                                                    <BackgroundIdentityLoginHandler />
-                                                    <PrekeysHandler />
-                                                    <ReportHandler />
-                                                    <FarcasterChannelPrefetchHandler />
-                                                    <AutoJoinCommunityHandler />
-                                                    <SyncCommunityStoreHandler />
-                                                    <InitialStateSharingHandler />
-                                                  </PersistedStateGate>
-                                                  {navigation}
-                                                </RegistrationContextProvider>
-                                              </BottomSheetProvider>
-                                            </MessageSearchProvider>
-                                          </MarkdownContextProvider>
-                                        </NativeEditThreadAvatarProvider>
-                                      </EditUserAvatarProvider>
-                                    </MediaCacheProvider>
-                                  </ActionSheetProvider>
-                                </SafeAreaProvider>
-                              </MessageEditingContextProvider>
-                            </InputStateContainer>
-                          </RootContext.Provider>
-                        </NavContext.Provider>
-                      </FeatureFlagsProvider>
-                    </SecondaryDeviceQRAuthContextProvider>
-                  </IdentitySearchProvider>
-                </TunnelbrokerProvider>
-              </NeynarClientProvider>
-            </ENSCacheProvider>
-          </UserIdentityCacheProvider>
-        </IdentityServiceContextProvider>
-      </StaffContextProvider>
-    </GestureHandlerRootView>
+    <DebugLogsContextProvider>
+      <GestureHandlerRootView style={styles.app}>
+        <StaffContextProvider>
+          <IdentityServiceContextProvider>
+            <UserIdentityCacheProvider>
+              <ENSCacheProvider
+                ethersProvider={ethersProvider}
+                alchemyKey={alchemyKey}
+              >
+                <NeynarClientProvider apiKey={neynarKey}>
+                  <TunnelbrokerProvider>
+                    <IdentitySearchProvider>
+                      <SecondaryDeviceQRAuthContextProvider
+                        parseTunnelbrokerQRAuthMessage={
+                          parseTunnelbrokerQRAuthMessage
+                        }
+                        composeTunnelbrokerQRAuthMessage={
+                          composeTunnelbrokerQRAuthMessage
+                        }
+                        generateAESKey={generateQRAuthAESKey}
+                        performBackupRestore={performBackupRestore}
+                        onLogInError={handleSecondaryDeviceLogInError}
+                      >
+                        <FeatureFlagsProvider>
+                          <NavContext.Provider value={navContext}>
+                            <RootContext.Provider value={rootContext}>
+                              <InputStateContainer>
+                                <MessageEditingContextProvider>
+                                  <SafeAreaProvider
+                                    initialMetrics={initialWindowMetrics}
+                                  >
+                                    <ActionSheetProvider>
+                                      <MediaCacheProvider
+                                        persistence={filesystemMediaCache}
+                                      >
+                                        <EditUserAvatarProvider>
+                                          <NativeEditThreadAvatarProvider>
+                                            <MarkdownContextProvider>
+                                              <MessageSearchProvider>
+                                                <BottomSheetProvider>
+                                                  <RegistrationContextProvider>
+                                                    <SQLiteDataHandler />
+                                                    <ConnectedStatusBar />
+                                                    <ReduxPersistGate
+                                                      persistor={getPersistor()}
+                                                    >
+                                                      {gated}
+                                                    </ReduxPersistGate>
+                                                    <PersistedStateGate>
+                                                      <KeyserverConnectionsHandler
+                                                        socketComponent={Socket}
+                                                        detectUnsupervisedBackgroundRef={
+                                                          detectUnsupervisedBackgroundRef
+                                                        }
+                                                      />
+                                                      <DMActivityHandler />
+                                                      <VersionSupportedChecker />
+                                                      <PlatformDetailsSynchronizer />
+                                                      <BackgroundIdentityLoginHandler />
+                                                      <PrekeysHandler />
+                                                      <ReportHandler />
+                                                      <FarcasterChannelPrefetchHandler />
+                                                      <AutoJoinCommunityHandler />
+                                                      <SyncCommunityStoreHandler />
+                                                      <InitialStateSharingHandler />
+                                                    </PersistedStateGate>
+                                                    {navigation}
+                                                  </RegistrationContextProvider>
+                                                </BottomSheetProvider>
+                                              </MessageSearchProvider>
+                                            </MarkdownContextProvider>
+                                          </NativeEditThreadAvatarProvider>
+                                        </EditUserAvatarProvider>
+                                      </MediaCacheProvider>
+                                    </ActionSheetProvider>
+                                  </SafeAreaProvider>
+                                </MessageEditingContextProvider>
+                              </InputStateContainer>
+                            </RootContext.Provider>
+                          </NavContext.Provider>
+                        </FeatureFlagsProvider>
+                      </SecondaryDeviceQRAuthContextProvider>
+                    </IdentitySearchProvider>
+                  </TunnelbrokerProvider>
+                </NeynarClientProvider>
+              </ENSCacheProvider>
+            </UserIdentityCacheProvider>
+          </IdentityServiceContextProvider>
+        </StaffContextProvider>
+      </GestureHandlerRootView>
+    </DebugLogsContextProvider>
   );
 }
 
diff --git a/web/root.js b/web/root.js
--- a/web/root.js
+++ b/web/root.js
@@ -11,6 +11,7 @@
 import thunk from 'redux-thunk';
 import { WagmiProvider } from 'wagmi';
 
+import { DebugLogsContextProvider } from 'lib/components/debug-logs-context-provider.react.js';
 import IntegrityHandler from 'lib/components/integrity-handler.react.js';
 import PrekeysHandler from 'lib/components/prekeys-handler.react.js';
 import ReportHandler from 'lib/components/report-handler.react.js';
@@ -62,25 +63,27 @@
 const RootProvider = (): React.Node => (
   <Provider store={store}>
     <ErrorBoundary>
-      <WagmiProvider config={wagmiConfig}>
-        <QueryClientProvider client={queryClient}>
-          <CallKeyserverEndpointProvider>
-            <InitialReduxStateGate persistor={persistor}>
-              <IdentityServiceContextProvider>
-                <UserIdentityCacheProvider>
-                  <Router history={history.getHistoryObject()}>
-                    <Route path="*" component={App} />
-                  </Router>
-                  <PrekeysHandler />
-                  <SQLiteDataHandler />
-                  <IntegrityHandler />
-                  <ReportHandler canSendReports={true} />
-                </UserIdentityCacheProvider>
-              </IdentityServiceContextProvider>
-            </InitialReduxStateGate>
-          </CallKeyserverEndpointProvider>
-        </QueryClientProvider>
-      </WagmiProvider>
+      <DebugLogsContextProvider>
+        <WagmiProvider config={wagmiConfig}>
+          <QueryClientProvider client={queryClient}>
+            <CallKeyserverEndpointProvider>
+              <InitialReduxStateGate persistor={persistor}>
+                <IdentityServiceContextProvider>
+                  <UserIdentityCacheProvider>
+                    <Router history={history.getHistoryObject()}>
+                      <Route path="*" component={App} />
+                    </Router>
+                    <PrekeysHandler />
+                    <SQLiteDataHandler />
+                    <IntegrityHandler />
+                    <ReportHandler canSendReports={true} />
+                  </UserIdentityCacheProvider>
+                </IdentityServiceContextProvider>
+              </InitialReduxStateGate>
+            </CallKeyserverEndpointProvider>
+          </QueryClientProvider>
+        </WagmiProvider>
+      </DebugLogsContextProvider>
     </ErrorBoundary>
   </Provider>
 );
diff --git a/web/settings/account-settings.react.js b/web/settings/account-settings.react.js
--- a/web/settings/account-settings.react.js
+++ b/web/settings/account-settings.react.js
@@ -32,6 +32,7 @@
 import css from './account-settings.css';
 import AppearanceChangeModal from './appearance-change-modal.react.js';
 import BackupTestRestoreModal from './backup-test-restore-modal.react.js';
+import DebugLogsModal from './debug-logs-modal.react.js';
 import BlockListModal from './relationship/block-list-modal.react.js';
 import FriendListModal from './relationship/friend-list-modal.react.js';
 import TunnelbrokerMessagesScreen from './tunnelbroker-message-list.react.js';
@@ -178,6 +179,11 @@
     [pushModal],
   );
 
+  const openDebugLogs = React.useCallback(
+    () => pushModal(<DebugLogsModal />),
+    [pushModal],
+  );
+
   if (!currentUserInfo || currentUserInfo.anonymous) {
     return null;
   }
@@ -294,6 +300,25 @@
     );
   }
 
+  let debugLogs;
+  if (staffCanSee) {
+    debugLogs = (
+      <div className={css.preferencesContainer}>
+        <h4 className={css.preferencesHeader}>Debug menu</h4>
+        <div className={css.content}>
+          <ul>
+            <li>
+              <span>See debug logs</span>
+              <Button variant="text" onClick={openDebugLogs}>
+                <p className={css.buttonText}>See List</p>
+              </Button>
+            </li>
+          </ul>
+        </div>
+      </div>
+    );
+  }
+
   return (
     <div className={css.container}>
       <div className={css.contentContainer}>
@@ -329,6 +354,7 @@
         {backup}
         {deviceData}
         {dms}
+        {debugLogs}
       </div>
     </div>
   );
diff --git a/web/settings/debug-logs-modal.css b/web/settings/debug-logs-modal.css
new file mode 100644
--- /dev/null
+++ b/web/settings/debug-logs-modal.css
@@ -0,0 +1,47 @@
+.container {
+  display: flex;
+  flex-direction: column;
+  height: 60vh;
+  gap: 8px;
+}
+
+.logsList {
+  display: flex;
+  flex-direction: column;
+  flex: 1;
+  overflow-y: scroll;
+}
+
+.item {
+  margin: 4px 0;
+  padding: 4px 0;
+  color: var(--text-background-secondary-default);
+  transition: 0.1s;
+}
+
+.item:hover {
+  background-color: var(--modal-listItem-primary-hover);
+}
+
+.timestamp {
+  font-size: var(--m-font-16);
+}
+
+.title {
+  font-size: var(--l-font-18);
+  color: var(--text-background-primary-default);
+}
+
+.message {
+  font-size: var(--m-font-16);
+}
+
+.buttons {
+  display: flex;
+  gap: 8px;
+  justify-content: space-between;
+}
+
+.button {
+  flex: 1;
+}
diff --git a/web/settings/debug-logs-modal.react.js b/web/settings/debug-logs-modal.react.js
new file mode 100644
--- /dev/null
+++ b/web/settings/debug-logs-modal.react.js
@@ -0,0 +1,58 @@
+// @flow
+
+import * as React from 'react';
+
+import { useDebugLogs } from 'lib/components/debug-logs-context.js';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
+
+import css from './debug-logs-modal.css';
+import Button, { buttonThemes } from '../components/button.react.js';
+import Modal from '../modals/modal.react.js';
+
+function DebugLogsModal(): React.Node {
+  const { logs, clearLogs } = useDebugLogs();
+  const { popModal } = useModalContext();
+
+  const messageList = React.useMemo(
+    () =>
+      logs.map((item, index) => {
+        const date = new Date(item.timestamp);
+        const timestampString = date.toISOString();
+        return (
+          <div key={index} className={css.item}>
+            <div className={css.timestamp}>{timestampString}</div>
+            <div className={css.title}>{item.title}</div>
+            <div className={css.message}>{item.message}</div>
+          </div>
+        );
+      }),
+    [logs],
+  );
+
+  const copyLogs = React.useCallback(async () => {
+    await navigator.clipboard.writeText(JSON.stringify(logs));
+  }, [logs]);
+
+  return (
+    <Modal name="Debug Logs" onClose={popModal} size="large">
+      <div className={css.container}>
+        <div className={css.logsList}>{messageList}</div>
+        <div className={css.buttons}>
+          <Button variant="filled" className={css.button} onClick={copyLogs}>
+            Copy Logs
+          </Button>
+          <Button
+            variant="filled"
+            buttonColor={buttonThemes.danger}
+            className={css.button}
+            onClick={clearLogs}
+          >
+            Clear Logs
+          </Button>
+        </div>
+      </div>
+    </Modal>
+  );
+}
+
+export default DebugLogsModal;