diff --git a/components/account/AccountHeader.vue b/components/account/AccountHeader.vue
index 167ed2b6..df7f330b 100644
--- a/components/account/AccountHeader.vue
+++ b/components/account/AccountHeader.vue
@@ -20,6 +20,7 @@ const relationship = $(useRelationship(account))
 
 const namedFields = ref<mastodon.v1.AccountField[]>([])
 const iconFields = ref<mastodon.v1.AccountField[]>([])
+const isEditingPersonalNote = ref<boolean>(false)
 const hasHeader = $computed(() => !account.header.endsWith('/original/missing.png'))
 
 function getFieldIconTitle(fieldName: string) {
@@ -80,6 +81,19 @@ watchEffect(() => {
   iconFields.value = icons
 })
 
+async function editNote(event: Event) {
+  if (!event.target || !('value' in event.target) || !relationship)
+    return
+
+  const newNote = event.target?.value as string
+
+  if (relationship.note?.trim() === newNote.trim())
+    return
+
+  const newNoteApiResult = await client.v1.accounts.createNote(account.id, { comment: newNote })
+  relationship.note = newNoteApiResult.note
+}
+
 const isSelf = $(useSelfAccount(() => account))
 const isNotifiedOnPost = $computed(() => !!relationship?.notifying)
 </script>
@@ -107,7 +121,11 @@ const isNotifiedOnPost = $computed(() => !!relationship?.notifying)
             </NuxtLink>
             <AccountFollowButton :account="account" :command="command" />
             <span inset-ie-0 flex gap-2 items-center>
-              <AccountMoreButton :account="account" :command="command" />
+              <AccountMoreButton
+                :account="account" :command="command"
+                @add-note="isEditingPersonalNote = true"
+                @remove-note="isEditingPersonalNote = false"
+              />
               <CommonTooltip v-if="!isSelf && relationship?.following" :content="getNotificationIconTitle()">
                 <button
                   :aria-pressed="isNotifiedOnPost"
@@ -145,6 +163,25 @@ const isNotifiedOnPost = $computed(() => !!relationship?.notifying)
           <AccountHandle :account="account" />
         </div>
       </div>
+      <label
+        v-if="relationship?.note?.length !== 0 || isEditingPersonalNote"
+        space-y-2
+        pb-4
+        block
+        border="b base"
+      >
+        <div flex flex-row space-x-2 flex-v-center>
+          <div i-ri-edit-2-line />
+          <p font-medium>
+            {{ $t('account.profile_personal_note') }}
+          </p>
+        </div>
+        <textarea
+          input-base
+          :value="relationship?.note ?? ''"
+          @change="editNote"
+        />
+      </label>
       <div v-if="account.note" max-h-100 overflow-y-auto>
         <ContentRich text-4 text-base :content="account.note" :emojis="account.emojis" />
       </div>
diff --git a/components/account/AccountMoreButton.vue b/components/account/AccountMoreButton.vue
index 9545e8ee..47ddeabc 100644
--- a/components/account/AccountMoreButton.vue
+++ b/components/account/AccountMoreButton.vue
@@ -5,6 +5,11 @@ const { account } = defineProps<{
   account: mastodon.v1.Account
   command?: boolean
 }>()
+const emit = defineEmits<{
+  (evt: 'addNote'): void
+  (evt: 'removeNote'): void
+}>()
+
 let relationship = $(useRelationship(account))
 
 const isSelf = $(useSelfAccount(() => account))
@@ -63,6 +68,19 @@ async function toggleReblogs() {
   const showingReblogs = !relationship?.showingReblogs
   relationship = await client.v1.accounts.follow(account.id, { reblogs: showingReblogs })
 }
+
+async function addUserNote() {
+  emit('addNote')
+}
+
+async function removeUserNote() {
+  if (!relationship!.note || relationship!.note.length === 0)
+    return
+
+  const newNote = await client.v1.accounts.createNote(account.id, { comment: '' })
+  relationship!.note = newNote.note
+  emit('removeNote')
+}
 </script>
 
 <template>
@@ -112,6 +130,21 @@ async function toggleReblogs() {
             @click="toggleReblogs()"
           />
 
+          <CommonDropdownItem
+            v-if="!relationship?.note || relationship?.note?.length === 0"
+            :text="$t('menu.add_personal_note', [`@${account.acct}`])"
+            icon="i-ri-edit-2-line"
+            :command="command"
+            @click="addUserNote()"
+          />
+          <CommonDropdownItem
+            v-else
+            :text="$t('menu.remove_personal_note', [`@${account.acct}`])"
+            icon="i-ri-edit-2-line"
+            :command="command"
+            @click="removeUserNote()"
+          />
+
           <CommonDropdownItem
             v-if="!relationship?.muting"
             :text="$t('menu.mute_account', [`@${account.acct}`])"
diff --git a/locales/en.json b/locales/en.json
index cb89f2b2..116476d6 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -34,6 +34,7 @@
     "posts": "Posts",
     "posts_count": "{0} Posts|{0} Post|{0} Posts",
     "profile_description": "{0}'s profile header",
+    "profile_personal_note": "Personal Note",
     "profile_unavailable": "Profile unavailable",
     "request_follow": "Request to follow",
     "unblock": "Unblock",
@@ -225,6 +226,7 @@
     "sequence_then": "then"
   },
   "menu": {
+    "add_personal_note": "Add personal note to {0}",
     "block_account": "Block {0}",
     "block_domain": "Block domain {0}",
     "copy_link_to_post": "Copy link to this post",
@@ -239,6 +241,7 @@
     "mute_conversation": "Mute this post",
     "open_in_original_site": "Open in original site",
     "pin_on_profile": "Pin on profile",
+    "remove_personal_note": "Remove personal note from {0}",
     "share_post": "Share this post",
     "show_favourited_and_boosted_by": "Show who favorited and boosted",
     "show_reblogs": "Show boosts from {0}",