mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-02 01:49:51 +08:00
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,9 +0,0 @@
|
||||
mutation generateUserAccessToken($input: GenerateAccessTokenInput!) {
|
||||
generateUserAccessToken(input: $input) {
|
||||
id
|
||||
name
|
||||
token
|
||||
createdAt
|
||||
expiresAt
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
mutation revokeUserAccessToken($id: String!) {
|
||||
revokeUserAccessToken(id: $id)
|
||||
}
|
||||
@@ -67,28 +67,6 @@ export const licenseBodyFragment = `fragment licenseBody on License {
|
||||
validatedAt
|
||||
variant
|
||||
}`;
|
||||
export const generateUserAccessTokenMutation = {
|
||||
id: 'generateUserAccessTokenMutation' as const,
|
||||
op: 'generateUserAccessToken',
|
||||
query: `mutation generateUserAccessToken($input: GenerateAccessTokenInput!) {
|
||||
generateUserAccessToken(input: $input) {
|
||||
id
|
||||
name
|
||||
token
|
||||
createdAt
|
||||
expiresAt
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const revokeUserAccessTokenMutation = {
|
||||
id: 'revokeUserAccessTokenMutation' as const,
|
||||
op: 'revokeUserAccessToken',
|
||||
query: `mutation revokeUserAccessToken($id: String!) {
|
||||
revokeUserAccessToken(id: $id)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const adminAllSharedLinksQuery = {
|
||||
id: 'adminAllSharedLinksQuery' as const,
|
||||
op: 'adminAllSharedLinks',
|
||||
@@ -2574,6 +2552,85 @@ export const listNotificationsQuery = {
|
||||
}`,
|
||||
};
|
||||
|
||||
export const createMcpCredentialMutation = {
|
||||
id: 'createMcpCredentialMutation' as const,
|
||||
op: 'createMcpCredential',
|
||||
query: `mutation createMcpCredential($input: CreateMcpCredentialInput!) {
|
||||
createMcpCredential(input: $input) {
|
||||
credential {
|
||||
id
|
||||
name
|
||||
workspaceId
|
||||
accessMode
|
||||
fingerprint
|
||||
createdAt
|
||||
expiresAt
|
||||
lastUsedAt
|
||||
revokedAt
|
||||
graceEndsAt
|
||||
status
|
||||
}
|
||||
token
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const mcpCredentialsQuery = {
|
||||
id: 'mcpCredentialsQuery' as const,
|
||||
op: 'mcpCredentials',
|
||||
query: `query mcpCredentials($workspaceId: String!) {
|
||||
mcpCredentialReadWriteAvailable
|
||||
mcpCredentials(workspaceId: $workspaceId) {
|
||||
id
|
||||
name
|
||||
workspaceId
|
||||
accessMode
|
||||
fingerprint
|
||||
createdAt
|
||||
expiresAt
|
||||
lastUsedAt
|
||||
revokedAt
|
||||
graceEndsAt
|
||||
status
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const revokeMcpCredentialMutation = {
|
||||
id: 'revokeMcpCredentialMutation' as const,
|
||||
op: 'revokeMcpCredential',
|
||||
query: `mutation revokeMcpCredential($id: ID!, $workspaceId: String!) {
|
||||
revokeMcpCredential(id: $id, workspaceId: $workspaceId)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const rotateMcpCredentialMutation = {
|
||||
id: 'rotateMcpCredentialMutation' as const,
|
||||
op: 'rotateMcpCredential',
|
||||
query: `mutation rotateMcpCredential($id: ID!, $workspaceId: String!, $expirationDays: Int!) {
|
||||
rotateMcpCredential(
|
||||
id: $id
|
||||
workspaceId: $workspaceId
|
||||
expirationDays: $expirationDays
|
||||
) {
|
||||
credential {
|
||||
id
|
||||
name
|
||||
workspaceId
|
||||
accessMode
|
||||
fingerprint
|
||||
createdAt
|
||||
expiresAt
|
||||
lastUsedAt
|
||||
revokedAt
|
||||
graceEndsAt
|
||||
status
|
||||
}
|
||||
token
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const mentionUserMutation = {
|
||||
id: 'mentionUserMutation' as const,
|
||||
op: 'mentionUser',
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
mutation createMcpCredential($input: CreateMcpCredentialInput!) {
|
||||
createMcpCredential(input: $input) {
|
||||
credential {
|
||||
id
|
||||
name
|
||||
workspaceId
|
||||
accessMode
|
||||
fingerprint
|
||||
createdAt
|
||||
expiresAt
|
||||
lastUsedAt
|
||||
revokedAt
|
||||
graceEndsAt
|
||||
status
|
||||
}
|
||||
token
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
query mcpCredentials($workspaceId: String!) {
|
||||
mcpCredentialReadWriteAvailable
|
||||
mcpCredentials(workspaceId: $workspaceId) {
|
||||
id
|
||||
name
|
||||
workspaceId
|
||||
accessMode
|
||||
fingerprint
|
||||
createdAt
|
||||
expiresAt
|
||||
lastUsedAt
|
||||
revokedAt
|
||||
graceEndsAt
|
||||
status
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
mutation revokeMcpCredential($id: ID!, $workspaceId: String!) {
|
||||
revokeMcpCredential(id: $id, workspaceId: $workspaceId)
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
mutation rotateMcpCredential(
|
||||
$id: ID!
|
||||
$workspaceId: String!
|
||||
$expirationDays: Int!
|
||||
) {
|
||||
rotateMcpCredential(
|
||||
id: $id
|
||||
workspaceId: $workspaceId
|
||||
expirationDays: $expirationDays
|
||||
) {
|
||||
credential {
|
||||
id
|
||||
name
|
||||
workspaceId
|
||||
accessMode
|
||||
fingerprint
|
||||
createdAt
|
||||
expiresAt
|
||||
lastUsedAt
|
||||
revokedAt
|
||||
graceEndsAt
|
||||
status
|
||||
}
|
||||
token
|
||||
}
|
||||
}
|
||||
@@ -37,14 +37,6 @@ export interface Scalars {
|
||||
Upload: { input: File; output: File };
|
||||
}
|
||||
|
||||
export interface AccessToken {
|
||||
__typename?: 'AccessToken';
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
expiresAt: Maybe<Scalars['DateTime']['output']>;
|
||||
id: Scalars['String']['output'];
|
||||
name: Scalars['String']['output'];
|
||||
}
|
||||
|
||||
export interface AddContextBlobInput {
|
||||
blobId: Scalars['String']['input'];
|
||||
contextId: Scalars['String']['input'];
|
||||
@@ -954,6 +946,13 @@ export interface CreateCheckoutSessionInput {
|
||||
variant?: InputMaybe<SubscriptionVariant>;
|
||||
}
|
||||
|
||||
export interface CreateMcpCredentialInput {
|
||||
accessMode?: McpAccessMode;
|
||||
expirationDays?: Scalars['Int']['input'];
|
||||
name: Scalars['String']['input'];
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface CreateUserInput {
|
||||
email: Scalars['String']['input'];
|
||||
name?: InputMaybe<Scalars['String']['input']>;
|
||||
@@ -1424,11 +1423,6 @@ export interface ForkChatSessionInput {
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface GenerateAccessTokenInput {
|
||||
expiresAt?: InputMaybe<Scalars['DateTime']['input']>;
|
||||
name: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface GrantDocUserRolesInput {
|
||||
docId: Scalars['String']['input'];
|
||||
role: DocRole;
|
||||
@@ -1754,6 +1748,34 @@ export interface ManageUserInput {
|
||||
name?: InputMaybe<Scalars['String']['input']>;
|
||||
}
|
||||
|
||||
export enum McpAccessMode {
|
||||
READ_ONLY = 'READ_ONLY',
|
||||
READ_WRITE = 'READ_WRITE',
|
||||
}
|
||||
|
||||
export enum McpCredentialStatus {
|
||||
ACTIVE = 'ACTIVE',
|
||||
EXPIRED = 'EXPIRED',
|
||||
EXPIRING = 'EXPIRING',
|
||||
REVOKED = 'REVOKED',
|
||||
ROTATING = 'ROTATING',
|
||||
}
|
||||
|
||||
export interface McpCredentialType {
|
||||
__typename?: 'McpCredentialType';
|
||||
accessMode: McpAccessMode;
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
expiresAt: Scalars['DateTime']['output'];
|
||||
fingerprint: Scalars['String']['output'];
|
||||
graceEndsAt: Maybe<Scalars['DateTime']['output']>;
|
||||
id: Scalars['ID']['output'];
|
||||
lastUsedAt: Maybe<Scalars['DateTime']['output']>;
|
||||
name: Scalars['String']['output'];
|
||||
revokedAt: Maybe<Scalars['DateTime']['output']>;
|
||||
status: McpCredentialStatus;
|
||||
workspaceId: Scalars['String']['output'];
|
||||
}
|
||||
|
||||
export interface MeetingActionItemType {
|
||||
__typename?: 'MeetingActionItemType';
|
||||
deadline: Maybe<Scalars['String']['output']>;
|
||||
@@ -1870,6 +1892,7 @@ export interface Mutation {
|
||||
/** Create a stripe customer portal to manage payment methods */
|
||||
createCustomerPortal: Scalars['String']['output'];
|
||||
createInviteLink: InviteLink;
|
||||
createMcpCredential: RevealedMcpCredentialType;
|
||||
createReply: ReplyObjectType;
|
||||
createSelfhostWorkspaceCustomerPortal: Scalars['String']['output'];
|
||||
/** Create a new user */
|
||||
@@ -1894,7 +1917,6 @@ export interface Mutation {
|
||||
/** Create a chat session */
|
||||
forkCopilotSession: Scalars['String']['output'];
|
||||
generateLicenseKey: Scalars['String']['output'];
|
||||
generateUserAccessToken: RevealedAccessToken;
|
||||
grantCommercialEntitlement: Scalars['Boolean']['output'];
|
||||
grantDocUserRoles: Scalars['Boolean']['output'];
|
||||
grantMember: Scalars['Boolean']['output'];
|
||||
@@ -1941,10 +1963,11 @@ export interface Mutation {
|
||||
revokeCommercialEntitlement: Scalars['Boolean']['output'];
|
||||
revokeDocUserRoles: Scalars['Boolean']['output'];
|
||||
revokeInviteLink: Scalars['Boolean']['output'];
|
||||
revokeMcpCredential: Scalars['Boolean']['output'];
|
||||
revokeMember: Scalars['Boolean']['output'];
|
||||
revokePublicDoc: DocType;
|
||||
revokeUserAccessToken: Scalars['Boolean']['output'];
|
||||
rotateAuthSigningKey: Array<AuthSigningKeyType>;
|
||||
rotateMcpCredential: RevealedMcpCredentialType;
|
||||
sendChangeEmail: Scalars['Boolean']['output'];
|
||||
sendChangePasswordEmail: Scalars['Boolean']['output'];
|
||||
sendSetPasswordEmail: Scalars['Boolean']['output'];
|
||||
@@ -2115,6 +2138,10 @@ export interface MutationCreateInviteLinkArgs {
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface MutationCreateMcpCredentialArgs {
|
||||
input: CreateMcpCredentialInput;
|
||||
}
|
||||
|
||||
export interface MutationCreateReplyArgs {
|
||||
input: ReplyCreateInput;
|
||||
}
|
||||
@@ -2183,10 +2210,6 @@ export interface MutationGenerateLicenseKeyArgs {
|
||||
sessionId: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface MutationGenerateUserAccessTokenArgs {
|
||||
input: GenerateAccessTokenInput;
|
||||
}
|
||||
|
||||
export interface MutationGrantCommercialEntitlementArgs {
|
||||
plan: Scalars['String']['input'];
|
||||
quantity?: InputMaybe<Scalars['Int']['input']>;
|
||||
@@ -2322,6 +2345,11 @@ export interface MutationRevokeInviteLinkArgs {
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface MutationRevokeMcpCredentialArgs {
|
||||
id: Scalars['ID']['input'];
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface MutationRevokeMemberArgs {
|
||||
userId: Scalars['String']['input'];
|
||||
workspaceId: Scalars['String']['input'];
|
||||
@@ -2332,14 +2360,16 @@ export interface MutationRevokePublicDocArgs {
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface MutationRevokeUserAccessTokenArgs {
|
||||
id: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface MutationRotateAuthSigningKeyArgs {
|
||||
expectedActiveKeyId: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface MutationRotateMcpCredentialArgs {
|
||||
expirationDays?: Scalars['Int']['input'];
|
||||
id: Scalars['ID']['input'];
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface MutationSendChangeEmailArgs {
|
||||
callbackUrl: Scalars['String']['input'];
|
||||
}
|
||||
@@ -2706,6 +2736,8 @@ export interface Query {
|
||||
error: ErrorDataUnion;
|
||||
/** get workspace invitation info */
|
||||
getInviteInfo: InvitationType;
|
||||
mcpCredentialReadWriteAvailable: Scalars['Boolean']['output'];
|
||||
mcpCredentials: Array<McpCredentialType>;
|
||||
prices: Array<SubscriptionPrice>;
|
||||
/** Get public user by id */
|
||||
publicUserById: Maybe<PublicUserType>;
|
||||
@@ -2714,8 +2746,6 @@ export interface Query {
|
||||
* @deprecated Use realtime subscription "workspace.embedding.progress.changed" instead.
|
||||
*/
|
||||
queryWorkspaceEmbeddingStatus: ContextWorkspaceEmbeddingStatus;
|
||||
/** @deprecated use currentUser.revealedAccessTokens */
|
||||
revealedAccessTokens: Array<RevealedAccessToken>;
|
||||
/** server config */
|
||||
serverConfig: ServerConfigType;
|
||||
/** Get user by email */
|
||||
@@ -2774,6 +2804,10 @@ export interface QueryGetInviteInfoArgs {
|
||||
inviteId: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface QueryMcpCredentialsArgs {
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface QueryPublicUserByIdArgs {
|
||||
id: Scalars['String']['input'];
|
||||
}
|
||||
@@ -2914,12 +2948,9 @@ export interface ResponseTooLargeErrorDataType {
|
||||
receivedBytes: Scalars['Int']['output'];
|
||||
}
|
||||
|
||||
export interface RevealedAccessToken {
|
||||
__typename?: 'RevealedAccessToken';
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
expiresAt: Maybe<Scalars['DateTime']['output']>;
|
||||
id: Scalars['String']['output'];
|
||||
name: Scalars['String']['output'];
|
||||
export interface RevealedMcpCredentialType {
|
||||
__typename?: 'RevealedMcpCredentialType';
|
||||
credential: McpCredentialType;
|
||||
token: Scalars['String']['output'];
|
||||
}
|
||||
|
||||
@@ -3450,7 +3481,6 @@ export interface UserSettingsType {
|
||||
|
||||
export interface UserType {
|
||||
__typename?: 'UserType';
|
||||
accessTokens: Array<AccessToken>;
|
||||
/** User avatar url */
|
||||
avatarUrl: Maybe<Scalars['String']['output']>;
|
||||
calendarAccounts: Array<CalendarAccountObjectType>;
|
||||
@@ -3480,7 +3510,6 @@ export interface UserType {
|
||||
notifications: PaginatedNotificationObjectType;
|
||||
quota: UserQuotaType;
|
||||
quotaUsage: UserQuotaUsageType;
|
||||
revealedAccessTokens: Array<RevealedAccessToken>;
|
||||
/** Get user settings */
|
||||
settings: UserSettingsType;
|
||||
subscriptions: Array<SubscriptionType>;
|
||||
@@ -3842,31 +3871,6 @@ export interface TokenType {
|
||||
token: Scalars['String']['output'];
|
||||
}
|
||||
|
||||
export type GenerateUserAccessTokenMutationVariables = Exact<{
|
||||
input: GenerateAccessTokenInput;
|
||||
}>;
|
||||
|
||||
export type GenerateUserAccessTokenMutation = {
|
||||
__typename?: 'Mutation';
|
||||
generateUserAccessToken: {
|
||||
__typename?: 'RevealedAccessToken';
|
||||
id: string;
|
||||
name: string;
|
||||
token: string;
|
||||
createdAt: string;
|
||||
expiresAt: string | null;
|
||||
};
|
||||
};
|
||||
|
||||
export type RevokeUserAccessTokenMutationVariables = Exact<{
|
||||
id: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type RevokeUserAccessTokenMutation = {
|
||||
__typename?: 'Mutation';
|
||||
revokeUserAccessToken: boolean;
|
||||
};
|
||||
|
||||
export type AdminAllSharedLinksQueryVariables = Exact<{
|
||||
pagination: PaginationInput;
|
||||
filter?: InputMaybe<AdminAllSharedLinksFilterInput>;
|
||||
@@ -7227,6 +7231,93 @@ export type ListNotificationsQuery = {
|
||||
} | null;
|
||||
};
|
||||
|
||||
export type CreateMcpCredentialMutationVariables = Exact<{
|
||||
input: CreateMcpCredentialInput;
|
||||
}>;
|
||||
|
||||
export type CreateMcpCredentialMutation = {
|
||||
__typename?: 'Mutation';
|
||||
createMcpCredential: {
|
||||
__typename?: 'RevealedMcpCredentialType';
|
||||
token: string;
|
||||
credential: {
|
||||
__typename?: 'McpCredentialType';
|
||||
id: string;
|
||||
name: string;
|
||||
workspaceId: string;
|
||||
accessMode: McpAccessMode;
|
||||
fingerprint: string;
|
||||
createdAt: string;
|
||||
expiresAt: string;
|
||||
lastUsedAt: string | null;
|
||||
revokedAt: string | null;
|
||||
graceEndsAt: string | null;
|
||||
status: McpCredentialStatus;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
export type McpCredentialsQueryVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type McpCredentialsQuery = {
|
||||
__typename?: 'Query';
|
||||
mcpCredentialReadWriteAvailable: boolean;
|
||||
mcpCredentials: Array<{
|
||||
__typename?: 'McpCredentialType';
|
||||
id: string;
|
||||
name: string;
|
||||
workspaceId: string;
|
||||
accessMode: McpAccessMode;
|
||||
fingerprint: string;
|
||||
createdAt: string;
|
||||
expiresAt: string;
|
||||
lastUsedAt: string | null;
|
||||
revokedAt: string | null;
|
||||
graceEndsAt: string | null;
|
||||
status: McpCredentialStatus;
|
||||
}>;
|
||||
};
|
||||
|
||||
export type RevokeMcpCredentialMutationVariables = Exact<{
|
||||
id: Scalars['ID']['input'];
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type RevokeMcpCredentialMutation = {
|
||||
__typename?: 'Mutation';
|
||||
revokeMcpCredential: boolean;
|
||||
};
|
||||
|
||||
export type RotateMcpCredentialMutationVariables = Exact<{
|
||||
id: Scalars['ID']['input'];
|
||||
workspaceId: Scalars['String']['input'];
|
||||
expirationDays: Scalars['Int']['input'];
|
||||
}>;
|
||||
|
||||
export type RotateMcpCredentialMutation = {
|
||||
__typename?: 'Mutation';
|
||||
rotateMcpCredential: {
|
||||
__typename?: 'RevealedMcpCredentialType';
|
||||
token: string;
|
||||
credential: {
|
||||
__typename?: 'McpCredentialType';
|
||||
id: string;
|
||||
name: string;
|
||||
workspaceId: string;
|
||||
accessMode: McpAccessMode;
|
||||
fingerprint: string;
|
||||
createdAt: string;
|
||||
expiresAt: string;
|
||||
lastUsedAt: string | null;
|
||||
revokedAt: string | null;
|
||||
graceEndsAt: string | null;
|
||||
status: McpCredentialStatus;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
export type MentionUserMutationVariables = Exact<{
|
||||
input: MentionInput;
|
||||
}>;
|
||||
@@ -8262,6 +8353,11 @@ export type Queries =
|
||||
variables: ListNotificationsQueryVariables;
|
||||
response: ListNotificationsQuery;
|
||||
}
|
||||
| {
|
||||
name: 'mcpCredentialsQuery';
|
||||
variables: McpCredentialsQueryVariables;
|
||||
response: McpCredentialsQuery;
|
||||
}
|
||||
| {
|
||||
name: 'pricesQuery';
|
||||
variables: PricesQueryVariables;
|
||||
@@ -8304,16 +8400,6 @@ export type Queries =
|
||||
};
|
||||
|
||||
export type Mutations =
|
||||
| {
|
||||
name: 'generateUserAccessTokenMutation';
|
||||
variables: GenerateUserAccessTokenMutationVariables;
|
||||
response: GenerateUserAccessTokenMutation;
|
||||
}
|
||||
| {
|
||||
name: 'revokeUserAccessTokenMutation';
|
||||
variables: RevokeUserAccessTokenMutationVariables;
|
||||
response: RevokeUserAccessTokenMutation;
|
||||
}
|
||||
| {
|
||||
name: 'adminUpdateWorkspaceMutation';
|
||||
variables: AdminUpdateWorkspaceMutationVariables;
|
||||
@@ -8669,6 +8755,21 @@ export type Mutations =
|
||||
variables: PreviewLicenseMutationVariables;
|
||||
response: PreviewLicenseMutation;
|
||||
}
|
||||
| {
|
||||
name: 'createMcpCredentialMutation';
|
||||
variables: CreateMcpCredentialMutationVariables;
|
||||
response: CreateMcpCredentialMutation;
|
||||
}
|
||||
| {
|
||||
name: 'revokeMcpCredentialMutation';
|
||||
variables: RevokeMcpCredentialMutationVariables;
|
||||
response: RevokeMcpCredentialMutation;
|
||||
}
|
||||
| {
|
||||
name: 'rotateMcpCredentialMutation';
|
||||
variables: RotateMcpCredentialMutationVariables;
|
||||
response: RotateMcpCredentialMutation;
|
||||
}
|
||||
| {
|
||||
name: 'mentionUserMutation';
|
||||
variables: MentionUserMutationVariables;
|
||||
|
||||
Reference in New Issue
Block a user