diff --git a/web/src/components/Panel/group/Wrapper.tsx b/web/src/components/Panel/group/Wrapper.tsx
index f307488e..28536e1e 100644
--- a/web/src/components/Panel/group/Wrapper.tsx
+++ b/web/src/components/Panel/group/Wrapper.tsx
@@ -6,6 +6,11 @@ import { CommonPanelWrapper } from '../common/Wrapper';
 import { usePanelWindow } from '@/hooks/usePanelWindow';
 import { OpenedPanelTip } from '@/components/OpenedPanelTip';
 import { IconBtn } from '@/components/IconBtn';
+import {
+  DMPluginPanelActionProps,
+  GroupPluginPanelActionProps,
+  pluginPanelActions,
+} from '@/plugin/common';
 
 /**
  * 群组面板通用包装器
@@ -41,6 +46,26 @@ export const GroupPanelWrapper: React.FC<GroupPanelWrapperProps> = React.memo(
       <CommonPanelWrapper
         header={panelInfo.name}
         actions={(setRightPanel) => [
+          ...pluginPanelActions
+            .filter(
+              (action): action is GroupPluginPanelActionProps =>
+                action.position === 'group'
+            )
+            .map((action) => (
+              <IconBtn
+                key={action.name}
+                title={action.label}
+                shape="square"
+                icon={action.icon}
+                iconClassName="text-2xl"
+                onClick={() =>
+                  action.onClick({
+                    groupId: props.groupId,
+                    panelId: props.panelId,
+                  })
+                }
+              />
+            )),
           <IconBtn
             key="open"
             title={t('在新窗口打开')}
diff --git a/web/src/components/Panel/personal/ConversePanel.tsx b/web/src/components/Panel/personal/ConversePanel.tsx
index 113a72b0..73fd1556 100644
--- a/web/src/components/Panel/personal/ConversePanel.tsx
+++ b/web/src/components/Panel/personal/ConversePanel.tsx
@@ -14,6 +14,7 @@ import { AppendDMConverseMembers } from '@/components/modals/AppendDMConverseMem
 import { usePanelWindow } from '@/hooks/usePanelWindow';
 import { OpenedPanelTip } from '@/components/OpenedPanelTip';
 import { IconBtn } from '@/components/IconBtn';
+import { DMPluginPanelActionProps, pluginPanelActions } from '@/plugin/common';
 
 const ConversePanelTitle: React.FC<{ converse: ChatConverseState }> =
   React.memo(({ converse }) => {
@@ -60,6 +61,21 @@ export const ConversePanel: React.FC<ConversePanelProps> = React.memo(
           }
 
           return _compact([
+            ...pluginPanelActions
+              .filter(
+                (action): action is DMPluginPanelActionProps =>
+                  action.position === 'dm'
+              )
+              .map((action) => (
+                <IconBtn
+                  key={action.name}
+                  title={action.label}
+                  shape="square"
+                  icon={action.icon}
+                  iconClassName="text-2xl"
+                  onClick={() => action.onClick({ converseId })}
+                />
+              )),
             <IconBtn
               key="open"
               title={t('在新窗口打开')}
diff --git a/web/src/plugin/common/reg.ts b/web/src/plugin/common/reg.ts
index 6078b84e..db8fe252 100644
--- a/web/src/plugin/common/reg.ts
+++ b/web/src/plugin/common/reg.ts
@@ -161,3 +161,36 @@ export const [pluginRootRoute, regPluginRootRoute] = buildRegList<{
   path: string;
   component: React.ComponentType;
 }>();
+
+export interface BasePluginPanelActionProps {
+  /**
+   * 唯一标识
+   */
+  name: string;
+  /**
+   * 显示名
+   */
+  label: string;
+  /**
+   * 来自iconify的图标标识
+   */
+  icon: string;
+}
+
+export interface GroupPluginPanelActionProps
+  extends BasePluginPanelActionProps {
+  position: 'group';
+  onClick: (ctx: { groupId: string; panelId: string }) => void;
+}
+
+export interface DMPluginPanelActionProps extends BasePluginPanelActionProps {
+  position: 'dm';
+  onClick: (ctx: { converseId: string }) => void;
+}
+
+/**
+ * 注册面板操作
+ */
+export const [pluginPanelActions, regPluginPanelAction] = buildRegList<
+  GroupPluginPanelActionProps | DMPluginPanelActionProps
+>();