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:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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`
|
||||
*/
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 结果",
|
||||
|
||||
Reference in New Issue
Block a user