feat(core): improve mcp management (#15221)

#### PR Dependency Tree


* **PR #15221** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added MCP credential management (create/reveal, list, rotate, revoke)
with expiration and status tracking.
* Introduced read-only vs read/write access modes, with read/write
tooling enabled only when permitted.
* Added workspace MCP credential configuration UI, including token
reveal and setup generation.
  * Added MCP credential GraphQL APIs to back the UI.
* **Changes**
* Replaced legacy access-token support with MCP credentials across
authentication and realtime updates.
* **Bug Fixes**
* MCP authentication now reliably rejects revoked, rotated, expired, or
disabled-user credentials.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
DarkSky
2026-07-12 19:30:44 +08:00
committed by GitHub
parent abf37d3dfa
commit 9b81c6debd
57 changed files with 2180 additions and 1213 deletions

View File

@@ -1,28 +1,28 @@
{
"ar": 94,
"ca": 91,
"ar": 92,
"ca": 89,
"da": 4,
"de": 100,
"el-GR": 90,
"de": 98,
"el-GR": 88,
"en": 100,
"es-AR": 90,
"es-CL": 91,
"es": 90,
"fa": 90,
"fr": 94,
"es-AR": 88,
"es-CL": 89,
"es": 88,
"fa": 88,
"fr": 92,
"hi": 1,
"it": 91,
"ja": 90,
"kk": 98,
"ko": 91,
"nb-NO": 45,
"pl": 91,
"pt-BR": 90,
"ru": 92,
"sv-SE": 90,
"tr": 98,
"uk": 90,
"ur": 98,
"it": 89,
"ja": 88,
"kk": 96,
"ko": 89,
"nb-NO": 44,
"pl": 89,
"pt-BR": 88,
"ru": 90,
"sv-SE": 88,
"tr": 96,
"uk": 88,
"ur": 96,
"zh-Hans": 100,
"zh-Hant": 92
"zh-Hant": 90
}

View File

@@ -8882,6 +8882,196 @@ export function useAFFiNEI18N(): {
* `The MCP token is shown only once. Delete and recreate it to copy the JSON configuration.`
*/
["com.affine.integration.mcp-server.copy-json.disabled-hint"](): string;
/**
* `Credentials`
*/
["com.affine.integration.mcp-server.credentials.title"](): string;
/**
* `Use a separate credential for each MCP client so it can be revoked independently.`
*/
["com.affine.integration.mcp-server.credentials.description"](): string;
/**
* `Create credential`
*/
["com.affine.integration.mcp-server.action.create"](): string;
/**
* `Rotate`
*/
["com.affine.integration.mcp-server.action.rotate"](): string;
/**
* `Revoke credential`
*/
["com.affine.integration.mcp-server.action.revoke"](): string;
/**
* `Copy token`
*/
["com.affine.integration.mcp-server.action.copy-token"](): string;
/**
* `Copy JSON`
*/
["com.affine.integration.mcp-server.action.copy-json"](): string;
/**
* `Done`
*/
["com.affine.integration.mcp-server.action.done"](): string;
/**
* `Failed to load MCP credentials.`
*/
["com.affine.integration.mcp-server.load-error"](): string;
/**
* `No MCP credentials`
*/
["com.affine.integration.mcp-server.empty.title"](): string;
/**
* `Create a workspace-bound credential to connect an MCP client.`
*/
["com.affine.integration.mcp-server.empty.description"](): string;
/**
* `Read only`
*/
["com.affine.integration.mcp-server.access.read-only"](): string;
/**
* `Can read and search documents in this workspace using your current permissions.`
*/
["com.affine.integration.mcp-server.access.read-only-desc"](): string;
/**
* `Read and write`
*/
["com.affine.integration.mcp-server.access.read-write"](): string;
/**
* `Expires {{date}}`
*/
["com.affine.integration.mcp-server.meta.expires"](options: {
readonly date: string;
}): string;
/**
* `Created {{date}}`
*/
["com.affine.integration.mcp-server.meta.created"](options: {
readonly date: string;
}): string;
/**
* `Last used {{date}}`
*/
["com.affine.integration.mcp-server.meta.last-used"](options: {
readonly date: string;
}): string;
/**
* `Never used`
*/
["com.affine.integration.mcp-server.meta.never-used"](): string;
/**
* `Old token valid until {{date}}`
*/
["com.affine.integration.mcp-server.meta.grace-until"](options: {
readonly date: string;
}): string;
/**
* `Active`
*/
["com.affine.integration.mcp-server.status.active"](): string;
/**
* `Rotating`
*/
["com.affine.integration.mcp-server.status.rotating"](): string;
/**
* `Expiring`
*/
["com.affine.integration.mcp-server.status.expiring"](): string;
/**
* `Expired`
*/
["com.affine.integration.mcp-server.status.expired"](): string;
/**
* `Revoked`
*/
["com.affine.integration.mcp-server.status.revoked"](): string;
/**
* `Create MCP credential`
*/
["com.affine.integration.mcp-server.create.title"](): string;
/**
* `This credential will only work with this workspace's MCP endpoint.`
*/
["com.affine.integration.mcp-server.create.description"](): string;
/**
* `Label`
*/
["com.affine.integration.mcp-server.field.label"](): string;
/**
* `Access`
*/
["com.affine.integration.mcp-server.field.access"](): string;
/**
* `Expires in`
*/
["com.affine.integration.mcp-server.field.expiry"](): string;
/**
* `{{days}} days`
*/
["com.affine.integration.mcp-server.expiry.days"](options: {
readonly days: string;
}): string;
/**
* `MCP credential created`
*/
["com.affine.integration.mcp-server.reveal.title"](): string;
/**
* `Copy this credential now. You won’t be able to see it again.`
*/
["com.affine.integration.mcp-server.reveal.warning"](): string;
/**
* `The old token remains valid until {{date}}.`
*/
["com.affine.integration.mcp-server.reveal.old-valid-until"](options: {
readonly date: string;
}): string;
/**
* `Credential`
*/
["com.affine.integration.mcp-server.reveal.token"](): string;
/**
* `MCP configuration`
*/
["com.affine.integration.mcp-server.reveal.config"](): string;
/**
* `Rotate this credential?`
*/
["com.affine.integration.mcp-server.rotate.title"](): string;
/**
* `A new token will be created immediately. The old token remains valid for up to 24 hours so you can update the MCP client.`
*/
["com.affine.integration.mcp-server.rotate.description"](): string;
/**
* `Revoke “{{name}}”?`
*/
["com.affine.integration.mcp-server.revoke.title"](options: {
readonly name: string;
}): string;
/**
* `All generations of this credential will stop working immediately. This cannot be undone.`
*/
["com.affine.integration.mcp-server.revoke.description"](): string;
/**
* `Supported capabilities`
*/
["com.affine.integration.mcp-server.capabilities.title"](): string;
/**
* `Read documents`
*/
["com.affine.integration.mcp-server.capabilities.read"](): string;
/**
* `Keyword search`
*/
["com.affine.integration.mcp-server.capabilities.keyword-search"](): string;
/**
* `Semantic search`
*/
["com.affine.integration.mcp-server.capabilities.semantic-search"](): string;
/**
* `Create and update documents`
*/
["com.affine.integration.mcp-server.capabilities.write"](): string;
/**
* `Notes`
*/

View File

@@ -2224,6 +2224,50 @@
"com.affine.integration.mcp-server.name": "MCP Server",
"com.affine.integration.mcp-server.desc": "Enable other MCP Client to search and read the doc of AFFiNE.",
"com.affine.integration.mcp-server.copy-json.disabled-hint": "The MCP token is shown only once. Delete and recreate it to copy the JSON configuration.",
"com.affine.integration.mcp-server.credentials.title": "Credentials",
"com.affine.integration.mcp-server.credentials.description": "Use a separate credential for each MCP client so it can be revoked independently.",
"com.affine.integration.mcp-server.action.create": "Create credential",
"com.affine.integration.mcp-server.action.rotate": "Rotate",
"com.affine.integration.mcp-server.action.revoke": "Revoke credential",
"com.affine.integration.mcp-server.action.copy-token": "Copy token",
"com.affine.integration.mcp-server.action.copy-json": "Copy JSON",
"com.affine.integration.mcp-server.action.done": "Done",
"com.affine.integration.mcp-server.load-error": "Failed to load MCP credentials.",
"com.affine.integration.mcp-server.empty.title": "No MCP credentials",
"com.affine.integration.mcp-server.empty.description": "Create a workspace-bound credential to connect an MCP client.",
"com.affine.integration.mcp-server.access.read-only": "Read only",
"com.affine.integration.mcp-server.access.read-only-desc": "Can read and search documents in this workspace using your current permissions.",
"com.affine.integration.mcp-server.access.read-write": "Read and write",
"com.affine.integration.mcp-server.meta.expires": "Expires {{date}}",
"com.affine.integration.mcp-server.meta.created": "Created {{date}}",
"com.affine.integration.mcp-server.meta.last-used": "Last used {{date}}",
"com.affine.integration.mcp-server.meta.never-used": "Never used",
"com.affine.integration.mcp-server.meta.grace-until": "Old token valid until {{date}}",
"com.affine.integration.mcp-server.status.active": "Active",
"com.affine.integration.mcp-server.status.rotating": "Rotating",
"com.affine.integration.mcp-server.status.expiring": "Expiring",
"com.affine.integration.mcp-server.status.expired": "Expired",
"com.affine.integration.mcp-server.status.revoked": "Revoked",
"com.affine.integration.mcp-server.create.title": "Create MCP credential",
"com.affine.integration.mcp-server.create.description": "This credential will only work with this workspace's MCP endpoint.",
"com.affine.integration.mcp-server.field.label": "Label",
"com.affine.integration.mcp-server.field.access": "Access",
"com.affine.integration.mcp-server.field.expiry": "Expires in",
"com.affine.integration.mcp-server.expiry.days": "{{days}} days",
"com.affine.integration.mcp-server.reveal.title": "MCP credential created",
"com.affine.integration.mcp-server.reveal.warning": "Copy this credential now. You won’t be able to see it again.",
"com.affine.integration.mcp-server.reveal.old-valid-until": "The old token remains valid until {{date}}.",
"com.affine.integration.mcp-server.reveal.token": "Credential",
"com.affine.integration.mcp-server.reveal.config": "MCP configuration",
"com.affine.integration.mcp-server.rotate.title": "Rotate this credential?",
"com.affine.integration.mcp-server.rotate.description": "A new token will be created immediately. The old token remains valid for up to 24 hours so you can update the MCP client.",
"com.affine.integration.mcp-server.revoke.title": "Revoke “{{name}}”?",
"com.affine.integration.mcp-server.revoke.description": "All generations of this credential will stop working immediately. This cannot be undone.",
"com.affine.integration.mcp-server.capabilities.title": "Supported capabilities",
"com.affine.integration.mcp-server.capabilities.read": "Read documents",
"com.affine.integration.mcp-server.capabilities.keyword-search": "Keyword search",
"com.affine.integration.mcp-server.capabilities.semantic-search": "Semantic search",
"com.affine.integration.mcp-server.capabilities.write": "Create and update documents",
"com.affine.audio.notes": "Notes",
"com.affine.audio.transcribing": "Transcribing",
"com.affine.audio.transcribe.non-owner.confirm.title": "Unable to retrieve AI results for others",

View File

@@ -2224,6 +2224,50 @@
"com.affine.integration.mcp-server.name": "MCP服务器",
"com.affine.integration.mcp-server.desc": "允许其他 MCP 客户端搜索和 AFFiNE 的文档。",
"com.affine.integration.mcp-server.copy-json.disabled-hint": "MCP token 仅显示一次。请删除并重新创建,以复制 JSON 配置。",
"com.affine.integration.mcp-server.credentials.title": "凭证",
"com.affine.integration.mcp-server.credentials.description": "为每个 MCP 客户端使用独立凭证,以便单独吊销。",
"com.affine.integration.mcp-server.action.create": "创建凭证",
"com.affine.integration.mcp-server.action.rotate": "轮换",
"com.affine.integration.mcp-server.action.revoke": "吊销凭证",
"com.affine.integration.mcp-server.action.copy-token": "复制 token",
"com.affine.integration.mcp-server.action.copy-json": "复制 JSON",
"com.affine.integration.mcp-server.action.done": "完成",
"com.affine.integration.mcp-server.load-error": "加载 MCP 凭证失败。",
"com.affine.integration.mcp-server.empty.title": "暂无 MCP 凭证",
"com.affine.integration.mcp-server.empty.description": "创建绑定当前工作区的凭证以连接 MCP 客户端。",
"com.affine.integration.mcp-server.access.read-only": "只读",
"com.affine.integration.mcp-server.access.read-only-desc": "可按你的当前权限读取和搜索此工作区的文档。",
"com.affine.integration.mcp-server.access.read-write": "读写",
"com.affine.integration.mcp-server.meta.expires": "{{date}} 到期",
"com.affine.integration.mcp-server.meta.created": "创建于 {{date}}",
"com.affine.integration.mcp-server.meta.last-used": "最近使用于 {{date}}",
"com.affine.integration.mcp-server.meta.never-used": "从未使用",
"com.affine.integration.mcp-server.meta.grace-until": "旧 token 有效至 {{date}}",
"com.affine.integration.mcp-server.status.active": "有效",
"com.affine.integration.mcp-server.status.rotating": "轮换中",
"com.affine.integration.mcp-server.status.expiring": "即将到期",
"com.affine.integration.mcp-server.status.expired": "已到期",
"com.affine.integration.mcp-server.status.revoked": "已吊销",
"com.affine.integration.mcp-server.create.title": "创建 MCP 凭证",
"com.affine.integration.mcp-server.create.description": "此凭证只能用于当前工作区的 MCP endpoint。",
"com.affine.integration.mcp-server.field.label": "名称",
"com.affine.integration.mcp-server.field.access": "权限",
"com.affine.integration.mcp-server.field.expiry": "有效期",
"com.affine.integration.mcp-server.expiry.days": "{{days}} 天",
"com.affine.integration.mcp-server.reveal.title": "MCP 凭证已创建",
"com.affine.integration.mcp-server.reveal.warning": "请立即复制此凭证,关闭后将无法再次查看。",
"com.affine.integration.mcp-server.reveal.old-valid-until": "旧 token 在 {{date}} 前仍然有效。",
"com.affine.integration.mcp-server.reveal.token": "凭证",
"com.affine.integration.mcp-server.reveal.config": "MCP 配置",
"com.affine.integration.mcp-server.rotate.title": "轮换此凭证?",
"com.affine.integration.mcp-server.rotate.description": "系统将立即创建新 token;旧 token 最多保留 24 小时,以便更新 MCP 客户端。",
"com.affine.integration.mcp-server.revoke.title": "吊销“{{name}}”?",
"com.affine.integration.mcp-server.revoke.description": "此凭证的所有世代会立即失效,且无法恢复。",
"com.affine.integration.mcp-server.capabilities.title": "支持的能力",
"com.affine.integration.mcp-server.capabilities.read": "读取文档",
"com.affine.integration.mcp-server.capabilities.keyword-search": "关键词搜索",
"com.affine.integration.mcp-server.capabilities.semantic-search": "语义搜索",
"com.affine.integration.mcp-server.capabilities.write": "创建和更新文档",
"com.affine.audio.notes": "笔记",
"com.affine.audio.transcribing": "转录",
"com.affine.audio.transcribe.non-owner.confirm.title": "无法检索他人的 AI 结果",