diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee14d361f9..22593d4862 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -76,6 +76,7 @@
 - Enhance: トレンドハッシュタグ取得時のパフォーマンスを大幅に向上
 - Enhance: WebSocket接続が多い場合のパフォーマンスを向上
 - Enhance: 不要なPostgreSQLのインデックスを削除しパフォーマンスを向上
+- Feat: サーバーサイレンス機能が追加されました
 - Fix: 連合なしアンケートに投票をするとUpdateがリモートに配信されてしまうのを修正
 - Fix: nodeinfoにおいてCORS用のヘッダーが設定されていないのを修正
 - Fix: 同じ種類のTLのストリーミングを複数接続できない問題を修正
diff --git a/locales/en-US.yml b/locales/en-US.yml
index 66825eaa7f..a2873181fe 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -195,6 +195,7 @@ perHour: "Per Hour"
 perDay: "Per Day"
 stopActivityDelivery: "Stop sending activities"
 blockThisInstance: "Block this instance"
+silenceThisInstance: "Silence this instance"
 operations: "Operations"
 software: "Software"
 version: "Version"
@@ -213,6 +214,13 @@ clearQueueConfirmText: "Any undelivered notes remaining in the queue will not be
 clearCachedFiles: "Clear cache"
 clearCachedFilesConfirm: "Are you sure that you want to delete all cached remote files?"
 blockedInstances: "Blocked Instances"
+silencedInstances: "Silenced Instances"
+silencedInstancesDescription: "List the hostnames of the instances that you want to\
+  \ silence. Accounts in the listed instances are treated as \"Silenced\", can only make follow requests, and cannot mention local accounts if not followed. This will not affect the blocked instances."
+hiddenTags: "Hidden Hashtags"
+hiddenTagsDescription: "List the hashtags (without the #) of the hashtags you wish\
+  \ to hide from trending and explore. Hidden hashtags are still discoverable via\
+  \ other means. Blocked instances are not affected even if listed here."
 blockedInstancesDescription: "List the hostnames of the instances that you want to block separated by linebreaks. Listed instances will no longer be able to communicate with this instance."
 muteAndBlock: "Mutes and Blocks"
 mutedUsers: "Muted users"
@@ -794,7 +802,7 @@ active: "Active"
 offline: "Offline"
 notRecommended: "Not recommended"
 botProtection: "Bot Protection"
-instanceBlocking: "Blocked Instances"
+instanceBlocking: "Blocked/Silenced Instances"
 selectAccount: "Select account"
 switchAccount: "Switch account"
 enabled: "Enabled"
diff --git a/locales/index.d.ts b/locales/index.d.ts
index 2494c1709b..483c470be8 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -198,6 +198,7 @@ export interface Locale {
     "perDay": string;
     "stopActivityDelivery": string;
     "blockThisInstance": string;
+    "silenceThisInstance": string;
     "operations": string;
     "software": string;
     "version": string;
@@ -217,6 +218,8 @@ export interface Locale {
     "clearCachedFilesConfirm": string;
     "blockedInstances": string;
     "blockedInstancesDescription": string;
+    "silencedInstances": string;
+    "silencedInstancesDescription": string;
     "muteAndBlock": string;
     "mutedUsers": string;
     "blockedUsers": string;
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 9adc4381a7..725d1e7a87 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -195,6 +195,7 @@ perHour: "1時間ごと"
 perDay: "1日ごと"
 stopActivityDelivery: "アクティビティの配送を停止"
 blockThisInstance: "このサーバーをブロック"
+silenceThisInstance: "サーバーをサイレンス"
 operations: "操作"
 software: "ソフトウェア"
 version: "バージョン"
@@ -213,7 +214,9 @@ clearQueueConfirmText: "未配達の投稿は配送されなくなります。
 clearCachedFiles: "キャッシュをクリア"
 clearCachedFilesConfirm: "キャッシュされたリモートファイルをすべて削除しますか?"
 blockedInstances: "ブロックしたサーバー"
-blockedInstancesDescription: "ブロックしたいサーバーのホストを改行で区切って設定します。ブロックされたサーバーは、このサーバーとやり取りできなくなります。サブドメインもブロックされます。"
+blockedInstancesDescription: "ブロックしたいサーバーのホストを改行で区切って設定します。ブロックされたサーバーは、このインスタンスとやり取りできなくなります。"
+silencedInstances: "サイレンスしたサーバー"
+silencedInstancesDescription: "サイレンスしたいサーバーのホストを改行で区切って設定します。サイレンスされたサーバーに所属するアカウントはすべて「サイレンス」として扱われ、フォローがすべてリクエストになり、フォロワーでないローカルアカウントにはメンションできなくなります。ブロックしたインスタンスには影響しません。"
 muteAndBlock: "ミュートとブロック"
 mutedUsers: "ミュートしたユーザー"
 blockedUsers: "ブロックしたユーザー"
@@ -794,7 +797,7 @@ active: "アクティブ"
 offline: "オフライン"
 notRecommended: "非推奨"
 botProtection: "Botプロテクション"
-instanceBlocking: "サーバーブロック"
+instanceBlocking: "サーバーブロック・サイレンス"
 selectAccount: "アカウントを選択"
 switchAccount: "アカウントを切り替え"
 enabled: "有効"
diff --git a/packages/backend/migration/1697247230117-InstanceSilence.js b/packages/backend/migration/1697247230117-InstanceSilence.js
new file mode 100644
index 0000000000..5fdbca3b27
--- /dev/null
+++ b/packages/backend/migration/1697247230117-InstanceSilence.js
@@ -0,0 +1,16 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and other misskey contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+export class InstanceSilence1697247230117 {
+    name = 'InstanceSilence1697247230117'
+
+    async up(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "meta" ADD "silencedHosts" character varying(1024) array NOT NULL DEFAULT '{}'`);
+    }
+
+		async down(queryRunner) {
+				await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "silencedHosts"`);
+		}
+}
diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts
index 400f1ec98c..a308e1aaa8 100644
--- a/packages/backend/src/core/NoteCreateService.ts
+++ b/packages/backend/src/core/NoteCreateService.ts
@@ -56,6 +56,7 @@ import { SearchService } from '@/core/SearchService.js';
 import { FeaturedService } from '@/core/FeaturedService.js';
 import { RedisTimelineService } from '@/core/RedisTimelineService.js';
 import { nyaize } from '@/misc/nyaize.js';
+import { UtilityService } from '@/core/UtilityService.js';
 
 type NotificationType = 'reply' | 'renote' | 'quote' | 'mention';
 
@@ -215,6 +216,7 @@ export class NoteCreateService implements OnApplicationShutdown {
 		private perUserNotesChart: PerUserNotesChart,
 		private activeUsersChart: ActiveUsersChart,
 		private instanceChart: InstanceChart,
+		private utilityService: UtilityService,
 	) { }
 
 	@bindThis
@@ -259,6 +261,12 @@ export class NoteCreateService implements OnApplicationShutdown {
 			}
 		}
 
+		const inSilencedInstance = this.utilityService.isSilencedHost((await this.metaService.fetch()).silencedHosts, user.host);
+
+		if (data.visibility === 'public' && inSilencedInstance && user.host !== null) {
+			data.visibility = 'home';
+		}
+
 		if (data.renote) {
 			switch (data.renote.visibility) {
 				case 'public':
diff --git a/packages/backend/src/core/UserFollowingService.ts b/packages/backend/src/core/UserFollowingService.ts
index f6d0c3a6d5..87484f0383 100644
--- a/packages/backend/src/core/UserFollowingService.ts
+++ b/packages/backend/src/core/UserFollowingService.ts
@@ -3,7 +3,7 @@
  * SPDX-License-Identifier: AGPL-3.0-only
  */
 
-import { Inject, Injectable, OnModuleInit, forwardRef } from '@nestjs/common';
+import { Inject, Injectable, OnModuleInit } from '@nestjs/common';
 import { ModuleRef } from '@nestjs/core';
 import { IsNull } from 'typeorm';
 import type { MiLocalUser, MiPartialLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser } from '@/models/User.js';
@@ -28,6 +28,7 @@ import { MetaService } from '@/core/MetaService.js';
 import { CacheService } from '@/core/CacheService.js';
 import type { Config } from '@/config.js';
 import { AccountMoveService } from '@/core/AccountMoveService.js';
+import { UtilityService } from '@/core/UtilityService.js';
 import Logger from '../logger.js';
 
 const logger = new Logger('following/create');
@@ -71,6 +72,7 @@ export class UserFollowingService implements OnModuleInit {
 		private instancesRepository: InstancesRepository,
 
 		private cacheService: CacheService,
+		private utilityService: UtilityService,
 		private userEntityService: UserEntityService,
 		private idService: IdService,
 		private queueService: QueueService,
@@ -118,15 +120,16 @@ export class UserFollowingService implements OnModuleInit {
 		}
 
 		const followeeProfile = await this.userProfilesRepository.findOneByOrFail({ userId: followee.id });
-
 		// フォロー対象が鍵アカウントである or
 		// フォロワーがBotであり、フォロー対象がBotからのフォローに慎重である or
-		// フォロワーがローカルユーザーであり、フォロー対象がリモートユーザーである
+		// フォロワーがローカルユーザーであり、フォロー対象がリモートユーザーである or
+		// フォロワーがローカルユーザーであり、フォロー対象がサイレンスされているサーバーである
 		// 上記のいずれかに当てはまる場合はすぐフォローせずにフォローリクエストを発行しておく
 		if (
 			followee.isLocked ||
 			(followeeProfile.carefulBot && follower.isBot) ||
-			(this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee) && process.env.FORCE_FOLLOW_REMOTE_USER_FOR_TESTING !== 'true')
+			(this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee) && process.env.FORCE_FOLLOW_REMOTE_USER_FOR_TESTING !== 'true') ||
+			(this.userEntityService.isLocalUser(followee) && this.userEntityService.isRemoteUser(follower) && this.utilityService.isSilencedHost((await this.metaService.fetch()).silencedHosts, follower.host))
 		) {
 			let autoAccept = false;
 
diff --git a/packages/backend/src/core/UtilityService.ts b/packages/backend/src/core/UtilityService.ts
index d2d2776bd2..b95e41167b 100644
--- a/packages/backend/src/core/UtilityService.ts
+++ b/packages/backend/src/core/UtilityService.ts
@@ -35,6 +35,12 @@ export class UtilityService {
 		return blockedHosts.some(x => `.${host.toLowerCase()}`.endsWith(`.${x}`));
 	}
 
+	@bindThis
+	public isSilencedHost(silencedHosts: string[] | undefined, host: string | null): boolean {
+		if (!silencedHosts || host == null) return false;
+		return silencedHosts.some(x => `.${host.toLowerCase()}`.endsWith(`.${x}`));
+	}
+
 	@bindThis
 	public extractDbHost(uri: string): string {
 		const url = new URL(uri);
diff --git a/packages/backend/src/core/entities/InstanceEntityService.ts b/packages/backend/src/core/entities/InstanceEntityService.ts
index 0e27e9df7f..9afe87eab7 100644
--- a/packages/backend/src/core/entities/InstanceEntityService.ts
+++ b/packages/backend/src/core/entities/InstanceEntityService.ts
@@ -3,9 +3,8 @@
  * SPDX-License-Identifier: AGPL-3.0-only
  */
 
-import { Injectable } from '@nestjs/common';
+import { Inject, Injectable } from '@nestjs/common';
 import type { Packed } from '@/misc/json-schema.js';
-import type { } from '@/models/Blocking.js';
 import type { MiInstance } from '@/models/Instance.js';
 import { MetaService } from '@/core/MetaService.js';
 import { bindThis } from '@/decorators.js';
@@ -43,6 +42,7 @@ export class InstanceEntityService {
 			description: instance.description,
 			maintainerName: instance.maintainerName,
 			maintainerEmail: instance.maintainerEmail,
+			isSilenced: this.utilityService.isSilencedHost(meta.silencedHosts, instance.host),
 			iconUrl: instance.iconUrl,
 			faviconUrl: instance.faviconUrl,
 			themeColor: instance.themeColor,
diff --git a/packages/backend/src/models/Meta.ts b/packages/backend/src/models/Meta.ts
index d2bd0c26e9..23ae513ede 100644
--- a/packages/backend/src/models/Meta.ts
+++ b/packages/backend/src/models/Meta.ts
@@ -76,6 +76,11 @@ export class MiMeta {
 	})
 	public sensitiveWords: string[];
 
+	@Column('varchar', {
+		length: 1024, array: true, default: '{}',
+	})
+	public silencedHosts: string[];
+
 	@Column('varchar', {
 		length: 1024,
 		nullable: true,
diff --git a/packages/backend/src/models/json-schema/federation-instance.ts b/packages/backend/src/models/json-schema/federation-instance.ts
index ac07519f16..4ad84d02ff 100644
--- a/packages/backend/src/models/json-schema/federation-instance.ts
+++ b/packages/backend/src/models/json-schema/federation-instance.ts
@@ -93,6 +93,11 @@ export const packedFederationInstanceSchema = {
 			type: 'string',
 			optional: false, nullable: true,
 		},
+		isSilenced: {
+			type: "boolean",
+			optional: false,
+			nullable: false,
+		},
 		infoUpdatedAt: {
 			type: 'string',
 			optional: false, nullable: true,
diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts
index 5a74456ab0..f294934344 100644
--- a/packages/backend/src/server/api/endpoints/admin/meta.ts
+++ b/packages/backend/src/server/api/endpoints/admin/meta.ts
@@ -105,6 +105,16 @@ export const meta = {
 				type: 'boolean',
 				optional: false, nullable: false,
 			},
+			silencedHosts: {
+				type: "array",
+				optional: true,
+				nullable: false,
+				items: {
+					type: "string",
+					optional: false,
+					nullable: false,
+				},
+			},
 			pinnedUsers: {
 				type: 'array',
 				optional: false, nullable: false,
@@ -367,6 +377,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				pinnedUsers: instance.pinnedUsers,
 				hiddenTags: instance.hiddenTags,
 				blockedHosts: instance.blockedHosts,
+				silencedHosts: instance.silencedHosts,
 				sensitiveWords: instance.sensitiveWords,
 				preservedUsernames: instance.preservedUsernames,
 				hcaptchaSecretKey: instance.hcaptchaSecretKey,
diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts
index 7db25e659f..72c4936c13 100644
--- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts
+++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts
@@ -20,18 +20,26 @@ export const paramDef = {
 	type: 'object',
 	properties: {
 		disableRegistration: { type: 'boolean', nullable: true },
-		pinnedUsers: { type: 'array', nullable: true, items: {
-			type: 'string',
-		} },
-		hiddenTags: { type: 'array', nullable: true, items: {
-			type: 'string',
-		} },
-		blockedHosts: { type: 'array', nullable: true, items: {
-			type: 'string',
-		} },
-		sensitiveWords: { type: 'array', nullable: true, items: {
-			type: 'string',
-		} },
+		pinnedUsers: {
+			type: 'array', nullable: true, items: {
+				type: 'string',
+			},
+		},
+		hiddenTags: {
+			type: 'array', nullable: true, items: {
+				type: 'string',
+			},
+		},
+		blockedHosts: {
+			type: 'array', nullable: true, items: {
+				type: 'string',
+			},
+		},
+		sensitiveWords: {
+			type: 'array', nullable: true, items: {
+				type: 'string',
+			},
+		},
 		themeColor: { type: 'string', nullable: true, pattern: '^#[0-9a-fA-F]{6}$' },
 		mascotImageUrl: { type: 'string', nullable: true },
 		bannerUrl: { type: 'string', nullable: true },
@@ -67,9 +75,11 @@ export const paramDef = {
 		proxyAccountId: { type: 'string', format: 'misskey:id', nullable: true },
 		maintainerName: { type: 'string', nullable: true },
 		maintainerEmail: { type: 'string', nullable: true },
-		langs: { type: 'array', items: {
-			type: 'string',
-		} },
+		langs: {
+			type: 'array', items: {
+				type: 'string',
+			},
+		},
 		summalyProxy: { type: 'string', nullable: true },
 		deeplAuthKey: { type: 'string', nullable: true },
 		deeplIsPro: { type: 'boolean' },
@@ -115,6 +125,13 @@ export const paramDef = {
 		perUserHomeTimelineCacheMax: { type: 'integer' },
 		perUserListTimelineCacheMax: { type: 'integer' },
 		notesPerOneAd: { type: 'integer' },
+		silencedHosts: {
+			type: 'array',
+			nullable: true,
+			items: {
+				type: 'string',
+			},
+		},
 	},
 	required: [],
 } as const;
@@ -147,7 +164,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 			if (Array.isArray(ps.sensitiveWords)) {
 				set.sensitiveWords = ps.sensitiveWords.filter(Boolean);
 			}
-
+			if (Array.isArray(ps.silencedHosts)) {
+				let lastValue = '';
+				set.silencedHosts = ps.silencedHosts.sort().filter((h) => {
+					const lv = lastValue;
+					lastValue = h;
+					return h !== '' && h !== lv && !set.blockedHosts?.includes(h);
+				});
+			}
 			if (ps.themeColor !== undefined) {
 				set.themeColor = ps.themeColor;
 			}
diff --git a/packages/backend/src/server/api/endpoints/federation/instances.ts b/packages/backend/src/server/api/endpoints/federation/instances.ts
index be73e5dbb8..c8beefa9c7 100644
--- a/packages/backend/src/server/api/endpoints/federation/instances.ts
+++ b/packages/backend/src/server/api/endpoints/federation/instances.ts
@@ -36,6 +36,7 @@ export const paramDef = {
 		blocked: { type: 'boolean', nullable: true },
 		notResponding: { type: 'boolean', nullable: true },
 		suspended: { type: 'boolean', nullable: true },
+		silenced: { type: "boolean", nullable: true },
 		federating: { type: 'boolean', nullable: true },
 		subscribing: { type: 'boolean', nullable: true },
 		publishing: { type: 'boolean', nullable: true },
@@ -102,6 +103,23 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				}
 			}
 
+			if (typeof ps.silenced === "boolean") {
+				const meta = await this.metaService.fetch(true);
+
+				if (ps.silenced) {
+					if (meta.silencedHosts.length === 0) {
+						return [];
+					}
+					query.andWhere("instance.host IN (:...silences)", {
+						silences: meta.silencedHosts,
+					});
+				} else if (meta.silencedHosts.length > 0) {
+					query.andWhere("instance.host NOT IN (:...silences)", {
+						silences: meta.silencedHosts,
+					});
+				}
+			}
+
 			if (typeof ps.federating === 'boolean') {
 				if (ps.federating) {
 					query.andWhere('((instance.followingCount > 0) OR (instance.followersCount > 0))');
diff --git a/packages/frontend/src/components/MkInstanceCardMini.vue b/packages/frontend/src/components/MkInstanceCardMini.vue
index de726e3aa4..e384b7a0bc 100644
--- a/packages/frontend/src/components/MkInstanceCardMini.vue
+++ b/packages/frontend/src/components/MkInstanceCardMini.vue
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<div :class="[$style.root, { yellow: instance.isNotResponding, red: instance.isBlocked, gray: instance.isSuspended }]">
+<div :class="[$style.root, { yellow: instance.isNotResponding, red: instance.isBlocked, gray: instance.isSuspended, blue: instance.isSilenced }]">
 	<img class="icon" :src="getInstanceIcon(instance)" alt="" loading="lazy"/>
 	<div class="body">
 		<span class="host">{{ instance.name ?? instance.host }}</span>
@@ -89,6 +89,12 @@ function getInstanceIcon(instance): string {
 		height: 30px;
 	}
 
+  &:global(.blue) {
+    --c: rgba(0, 42, 255, 0.15);
+    background-image: linear-gradient(45deg, var(--c) 16.67%, transparent 16.67%, transparent 50%, var(--c) 50%, var(--c) 66.67%, transparent 66.67%, transparent 100%);
+    background-size: 16px 16px;
+  }
+
 	&:global(.yellow) {
 		--c: rgb(255 196 0 / 15%);
 		background-image: linear-gradient(45deg, var(--c) 16.67%, transparent 16.67%, transparent 50%, var(--c) 50%, var(--c) 66.67%, transparent 66.67%, transparent 100%);
diff --git a/packages/frontend/src/pages/about.federation.vue b/packages/frontend/src/pages/about.federation.vue
index 2aa5af939b..333af93ef8 100644
--- a/packages/frontend/src/pages/about.federation.vue
+++ b/packages/frontend/src/pages/about.federation.vue
@@ -18,6 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<option value="subscribing">{{ i18n.ts.subscribing }}</option>
 				<option value="publishing">{{ i18n.ts.publishing }}</option>
 				<option value="suspended">{{ i18n.ts.suspended }}</option>
+				<option value="silenced">{{ i18n.ts.silence }}</option>
 				<option value="blocked">{{ i18n.ts.blocked }}</option>
 				<option value="notResponding">{{ i18n.ts.notResponding }}</option>
 			</MkSelect>
@@ -75,6 +76,7 @@ const pagination = {
 			state === 'publishing' ? { publishing: true } :
 			state === 'suspended' ? { suspended: true } :
 			state === 'blocked' ? { blocked: true } :
+			state === 'silenced' ? { silenced: true } :
 			state === 'notResponding' ? { notResponding: true } :
 			{}),
 	})),
@@ -83,6 +85,7 @@ const pagination = {
 function getStatus(instance) {
 	if (instance.isSuspended) return 'Suspended';
 	if (instance.isBlocked) return 'Blocked';
+	if (instance.isSilenced) return 'Silenced';
 	if (instance.isNotResponding) return 'Error';
 	return 'Alive';
 }
diff --git a/packages/frontend/src/pages/admin/instance-block.vue b/packages/frontend/src/pages/admin/instance-block.vue
index 9a0f5e026b..259354b3d0 100644
--- a/packages/frontend/src/pages/admin/instance-block.vue
+++ b/packages/frontend/src/pages/admin/instance-block.vue
@@ -5,14 +5,17 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkStickyContainer>
-	<template #header><XHeader :actions="headerActions" :tabs="headerTabs"/></template>
+	<template #header><XHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
 	<MkSpacer :contentMax="700" :marginMin="16" :marginMax="32">
 		<FormSuspense :p="init">
-			<MkTextarea v-model="blockedHosts">
+			<MkTextarea v-if="tab === 'block'" v-model="blockedHosts">
 				<span>{{ i18n.ts.blockedInstances }}</span>
 				<template #caption>{{ i18n.ts.blockedInstancesDescription }}</template>
 			</MkTextarea>
-
+			<MkTextarea v-else-if="tab === 'silence'" v-model="silencedHosts" class="_formBlock">
+				<span>{{ i18n.ts.silencedInstances }}</span>
+				<template #caption>{{ i18n.ts.silencedInstancesDescription }}</template>
+			</MkTextarea>
 			<MkButton primary @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
 		</FormSuspense>
 	</MkSpacer>
@@ -20,7 +23,6 @@ SPDX-License-Identifier: AGPL-3.0-only
 </template>
 
 <script lang="ts" setup>
-import { } from 'vue';
 import XHeader from './_header_.vue';
 import MkButton from '@/components/MkButton.vue';
 import MkTextarea from '@/components/MkTextarea.vue';
@@ -31,15 +33,20 @@ import { i18n } from '@/i18n.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
 
 let blockedHosts: string = $ref('');
+let silencedHosts: string = $ref('');
+let tab = $ref('block');
 
 async function init() {
 	const meta = await os.api('admin/meta');
 	blockedHosts = meta.blockedHosts.join('\n');
+	silencedHosts = meta.silencedHosts.join('\n');
 }
 
 function save() {
 	os.apiWithDialog('admin/update-meta', {
 		blockedHosts: blockedHosts.split('\n') || [],
+		silencedHosts: silencedHosts.split('\n') || [],
+
 	}).then(() => {
 		fetchInstance();
 	});
@@ -47,7 +54,15 @@ function save() {
 
 const headerActions = $computed(() => []);
 
-const headerTabs = $computed(() => []);
+const headerTabs = $computed(() => [{
+	key: 'block',
+	title: i18n.ts.block,
+	icon: 'ti ti-ban',
+}, {
+	key: 'silence',
+	title: i18n.ts.silence,
+	icon: 'ti ti-eye-off',
+}]);
 
 definePageMetadata({
 	title: i18n.ts.instanceBlocking,
diff --git a/packages/frontend/src/pages/instance-info.vue b/packages/frontend/src/pages/instance-info.vue
index 2285e4c88e..fb93637e00 100644
--- a/packages/frontend/src/pages/instance-info.vue
+++ b/packages/frontend/src/pages/instance-info.vue
@@ -36,7 +36,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<div class="_gaps_s">
 					<MkSwitch v-model="suspended" :disabled="!instance" @update:modelValue="toggleSuspend">{{ i18n.ts.stopActivityDelivery }}</MkSwitch>
 					<MkSwitch v-model="isBlocked" :disabled="!meta || !instance" @update:modelValue="toggleBlock">{{ i18n.ts.blockThisInstance }}</MkSwitch>
-					<MkButton @click="refreshMetadata"><i class="ti ti-refresh"></i> Refresh metadata</MkButton>
+                    <MkSwitch v-model="isSilenced" :disabled="!meta || !instance" @update:modelValue="toggleSilenced">{{ i18n.ts.silenceThisInstance }}</MkSwitch>
+                    <MkButton @click="refreshMetadata"><i class="ti ti-refresh"></i> Refresh metadata</MkButton>
 				</div>
 			</FormSection>
 
@@ -147,6 +148,7 @@ let meta = $ref<Misskey.entities.AdminInstanceMetadata | null>(null);
 let instance = $ref<Misskey.entities.Instance | null>(null);
 let suspended = $ref(false);
 let isBlocked = $ref(false);
+let isSilenced = $ref(false);
 let faviconUrl = $ref<string | null>(null);
 
 const usersPagination = {
@@ -169,7 +171,8 @@ async function fetch(): Promise<void> {
 	});
 	suspended = instance.isSuspended;
 	isBlocked = instance.isBlocked;
-	faviconUrl = getProxiedImageUrlNullable(instance.faviconUrl, 'preview') ?? getProxiedImageUrlNullable(instance.iconUrl, 'preview');
+    isSilenced = instance.isSilenced;
+    faviconUrl = getProxiedImageUrlNullable(instance.faviconUrl, 'preview') ?? getProxiedImageUrlNullable(instance.iconUrl, 'preview');
 }
 
 async function toggleBlock(): Promise<void> {
@@ -180,7 +183,14 @@ async function toggleBlock(): Promise<void> {
 		blockedHosts: isBlocked ? meta.blockedHosts.concat([host]) : meta.blockedHosts.filter(x => x !== host),
 	});
 }
-
+async function toggleSilenced(): Promise<void> {
+    if (!meta) throw new Error('No meta?');
+    if (!instance) throw new Error('No instance?');
+    const { host } = instance;
+    await os.api('admin/update-meta', {
+        silencedHosts: isSilenced ? meta.silencedHosts.concat([host]) : meta.silencedHosts.filter(x => x !== host),
+    });
+}
 async function toggleSuspend(): Promise<void> {
 	if (!instance) throw new Error('No instance?');
 	await os.api('admin/federation/update-instance', {
diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md
index b9777993fd..6b01321047 100644
--- a/packages/misskey-js/etc/misskey-js.api.md
+++ b/packages/misskey-js/etc/misskey-js.api.md
@@ -29,6 +29,7 @@ type Ad = TODO_2;
 // @public (undocumented)
 type AdminInstanceMetadata = DetailedInstanceMetadata & {
     blockedHosts: string[];
+    silencedHosts: string[];
     app192IconUrl: string | null;
     app512IconUrl: string | null;
     manifestJsonOverride: string;
@@ -2359,6 +2360,7 @@ type Instance = {
     lastCommunicatedAt: DateString;
     isNotResponding: boolean;
     isSuspended: boolean;
+    isSilenced: boolean;
     isBlocked: boolean;
     softwareName: string | null;
     softwareVersion: string | null;
@@ -2985,7 +2987,7 @@ type UserSorting = '+follower' | '-follower' | '+createdAt' | '-createdAt' | '+u
 // src/api.types.ts:18:25 - (ae-forgotten-export) The symbol "NoParams" needs to be exported by the entry point index.d.ts
 // src/api.types.ts:630:18 - (ae-forgotten-export) The symbol "ShowUserReq" needs to be exported by the entry point index.d.ts
 // src/entities.ts:107:2 - (ae-forgotten-export) The symbol "notificationTypes_2" needs to be exported by the entry point index.d.ts
-// src/entities.ts:601:2 - (ae-forgotten-export) The symbol "ModerationLogPayloads" needs to be exported by the entry point index.d.ts
+// src/entities.ts:603:2 - (ae-forgotten-export) The symbol "ModerationLogPayloads" needs to be exported by the entry point index.d.ts
 // src/streaming.types.ts:33:4 - (ae-forgotten-export) The symbol "FIXME" needs to be exported by the entry point index.d.ts
 
 // (No @packageDocumentation comment for this package)
diff --git a/packages/misskey-js/src/entities.ts b/packages/misskey-js/src/entities.ts
index bcf5538532..e05412abb9 100644
--- a/packages/misskey-js/src/entities.ts
+++ b/packages/misskey-js/src/entities.ts
@@ -385,6 +385,7 @@ export type InstanceMetadata = LiteInstanceMetadata | DetailedInstanceMetadata;
 export type AdminInstanceMetadata = DetailedInstanceMetadata & {
 	// TODO: There are more fields.
 	blockedHosts: string[];
+	silencedHosts: string[];
 	app192IconUrl: string | null;
 	app512IconUrl: string | null;
 	manifestJsonOverride: string;
@@ -545,6 +546,7 @@ export type Instance = {
 	lastCommunicatedAt: DateString;
 	isNotResponding: boolean;
 	isSuspended: boolean;
+	isSilenced: boolean;
 	isBlocked: boolean;
 	softwareName: string | null;
 	softwareVersion: string | null;