feat(mcp): enable Payload MCP plugin
Register mcpPlugin on the Payload config. Auth now also accepts payload-mcp-api-keys, so the generated types carry the new collection and the user union widens accordingly. Follow-up commits guard user auth paths against these API-key sessions. Also apply incidental prettier formatting to generatePlainText().
This commit is contained in:
parent
83790a629b
commit
b70ff4dff8
3 changed files with 89 additions and 14 deletions
|
|
@ -35,6 +35,7 @@
|
|||
"@payloadcms/email-nodemailer": "3.88.0",
|
||||
"@payloadcms/next": "3.88.0",
|
||||
"@payloadcms/payload-cloud": "3.88.0",
|
||||
"@payloadcms/plugin-mcp": "^3.88.0",
|
||||
"@payloadcms/richtext-lexical": "3.88.0",
|
||||
"@payloadcms/ui": "3.88.0",
|
||||
"@radix-ui/react-avatar": "^1.2.6",
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ export type SupportedTimezones =
|
|||
export interface Config {
|
||||
auth: {
|
||||
users: UserAuthOperations;
|
||||
'payload-mcp-api-keys': PayloadMcpApiKeyAuthOperations;
|
||||
};
|
||||
blocks: {};
|
||||
collections: {
|
||||
|
|
@ -112,6 +113,7 @@ export interface Config {
|
|||
'arma-sync-events': ArmaSyncEvent;
|
||||
'arma-commands': ArmaCommand;
|
||||
'plugin-ai-instructions': PluginAiInstruction;
|
||||
'payload-mcp-api-keys': PayloadMcpApiKey;
|
||||
'payload-kv': PayloadKv;
|
||||
'payload-locked-documents': PayloadLockedDocument;
|
||||
'payload-preferences': PayloadPreference;
|
||||
|
|
@ -171,6 +173,7 @@ export interface Config {
|
|||
'arma-sync-events': ArmaSyncEventsSelect<false> | ArmaSyncEventsSelect<true>;
|
||||
'arma-commands': ArmaCommandsSelect<false> | ArmaCommandsSelect<true>;
|
||||
'plugin-ai-instructions': PluginAiInstructionsSelect<false> | PluginAiInstructionsSelect<true>;
|
||||
'payload-mcp-api-keys': PayloadMcpApiKeysSelect<false> | PayloadMcpApiKeysSelect<true>;
|
||||
'payload-kv': PayloadKvSelect<false> | PayloadKvSelect<true>;
|
||||
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
|
||||
|
|
@ -192,7 +195,7 @@ export interface Config {
|
|||
widgets: {
|
||||
collections: CollectionsWidget;
|
||||
};
|
||||
user: User;
|
||||
user: User | PayloadMcpApiKey;
|
||||
jobs: {
|
||||
tasks: unknown;
|
||||
workflows: unknown;
|
||||
|
|
@ -214,6 +217,24 @@ export interface UserAuthOperations {
|
|||
username: string;
|
||||
};
|
||||
}
|
||||
export interface PayloadMcpApiKeyAuthOperations {
|
||||
forgotPassword: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
login: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
registerFirstUser: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
unlock: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "media".
|
||||
|
|
@ -2872,6 +2893,33 @@ export interface PluginAiInstruction {
|
|||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* API keys control which collections, resources, tools, and prompts MCP clients can access
|
||||
*
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-mcp-api-keys".
|
||||
*/
|
||||
export interface PayloadMcpApiKey {
|
||||
id: number;
|
||||
/**
|
||||
* The user that the API key is associated with.
|
||||
*/
|
||||
user: number | User;
|
||||
/**
|
||||
* A useful label for the API key.
|
||||
*/
|
||||
label?: string | null;
|
||||
/**
|
||||
* The purpose of the API key.
|
||||
*/
|
||||
description?: string | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
enableAPIKey?: boolean | null;
|
||||
apiKey?: string | null;
|
||||
apiKeyIndex?: string | null;
|
||||
collection: 'payload-mcp-api-keys';
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-kv".
|
||||
|
|
@ -3075,11 +3123,20 @@ export interface PayloadLockedDocument {
|
|||
| ({
|
||||
relationTo: 'plugin-ai-instructions';
|
||||
value: number | PluginAiInstruction;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'payload-mcp-api-keys';
|
||||
value: number | PayloadMcpApiKey;
|
||||
} | null);
|
||||
globalSlug?: string | null;
|
||||
user: {
|
||||
user:
|
||||
| {
|
||||
relationTo: 'users';
|
||||
value: number | User;
|
||||
}
|
||||
| {
|
||||
relationTo: 'payload-mcp-api-keys';
|
||||
value: number | PayloadMcpApiKey;
|
||||
};
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
|
|
@ -3090,9 +3147,14 @@ export interface PayloadLockedDocument {
|
|||
*/
|
||||
export interface PayloadPreference {
|
||||
id: number;
|
||||
user: {
|
||||
user:
|
||||
| {
|
||||
relationTo: 'users';
|
||||
value: number | User;
|
||||
}
|
||||
| {
|
||||
relationTo: 'payload-mcp-api-keys';
|
||||
value: number | PayloadMcpApiKey;
|
||||
};
|
||||
key?: string | null;
|
||||
value?:
|
||||
|
|
@ -4364,6 +4426,20 @@ export interface PluginAiInstructionsSelect<T extends boolean = true> {
|
|||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-mcp-api-keys_select".
|
||||
*/
|
||||
export interface PayloadMcpApiKeysSelect<T extends boolean = true> {
|
||||
user?: T;
|
||||
label?: T;
|
||||
description?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
enableAPIKey?: T;
|
||||
apiKey?: T;
|
||||
apiKeyIndex?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-kv_select".
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ import { nodemailerAdapter } from "@payloadcms/email-nodemailer";
|
|||
import nodemailer from "nodemailer";
|
||||
import { Shims } from "@/collections/Shims";
|
||||
import { payloadAiPlugin, PayloadAiPluginLexicalEditorFeature } from "@ai-stack/payloadcms";
|
||||
import { mcpPlugin } from "@payloadcms/plugin-mcp";
|
||||
import { createOpenAI } from "@ai-sdk/openai";
|
||||
import { createTextStreamResponse, jsonSchema, streamObject } from "ai";
|
||||
|
||||
|
|
@ -104,11 +105,7 @@ function plainTextToLexicalJson(text: string): Record<string, unknown> {
|
|||
};
|
||||
}
|
||||
|
||||
async function generatePlainText(
|
||||
prompt: string,
|
||||
system: string,
|
||||
model: string,
|
||||
): Promise<string> {
|
||||
async function generatePlainText(prompt: string, system: string, model: string): Promise<string> {
|
||||
const baseUrl = process.env.UNSLOTH_URL || "https://uns.onyxsimple.com/v1";
|
||||
const response = await fetch(`${baseUrl}/chat/completions`, {
|
||||
method: "POST",
|
||||
|
|
@ -288,6 +285,7 @@ export default buildConfig({
|
|||
plugins: [
|
||||
// payloadCloudPlugin(),
|
||||
// storage-adapter-placeholder
|
||||
mcpPlugin({}),
|
||||
payloadAiPlugin({
|
||||
collections: {
|
||||
[GameHardResources.slug]: true,
|
||||
|
|
|
|||
Loading…
Reference in a new issue