אני די מכור לסדרה האחרונה שלנו.אני מתנצל על הכיסוי. MCPs נמצאים בכל מקום ומסיבה טובה.זה הצעד הבא בהתפתחות האפליקציות. להיות מסוגל להשתמש בכל דבר מתוך צ'אט אחד מבלי לגשת לכל אפליקציה. כדי לתזמן את כל הפוסטים החברתיים שלך מן הצ'אט! אז, התחלתי לחפור לתוך קוד Postiz ולהוסיף אליו! פוסטים → MCP Repository הוא קצת מוזר לכל MCP יש תחבורה, שהיא השיטה שבה LLMs להשתמש כדי לדבר עם המערכת שלנו. Stdio, שהוא בעצם שורת פקודות, ו- SSE. There are two primary methods at the moment אני לא ממש מבין למה הם בחרו ב- SSE - זה בעצם בקשה ארוכה שאינה נגמרת ומעבירה אירועים ללקוח. הבעיה עם שיטה זו היא כי כדי לשלוח מידע בחזרה לשרת, עליך לשלוח בקשה דואר נוספת (כי SSE היא תקשורת חד-צדדית), כלומר עליך לשמור על המצב. בדוגמה שלהם, הם מחזיקים את המצב בזיכרון של האפליקציה, ונחשו מה? יש להם מצב שינה מובנה, ואתה לא צריך לשמור על מצב עבור זה. חפירה ב חפצתי ב- Anthropic typcript SDK ולא הופתעתי. זה מרגיש מגוחך. דברים רבים אינם בשימוש בייצור, כגון "משאבים". כמו כן, קשה ליישם אימות ולהוציא את המשתמש מהקשר כדי שנוכל לקבל את הפרטים שלהם. Postiz בנוי עם NestJS, כך שכאשר אתה משתמש במסלול SSE, זה סוגר את המשמש ברגע שהוא מתנתק, ומאפשר לך להסיר הכל מהזיכרון. import EventEmitter from 'events'; import { finalize, fromEvent, startWith } from 'rxjs'; @Injectable() export class McpService { static event = new EventEmitter(); constructor( private _mainMcp: MainMcp ) { } async runServer(apiKey: string, organization: string) { const server = McpSettings.load(organization, this._mainMcp).server(); const transport = new McpTransport(organization); const observer = fromEvent( McpService.event, `organization-${organization}` ).pipe( startWith({ type: 'endpoint', data: process.env.NEXT_PUBLIC_BACKEND_URL + '/mcp/' + apiKey + '/messages', }), finalize(() => { transport.close(); }) ); console.log('MCP transport started'); await server.connect(transport); return observer; } async processPostBody(organization: string, body: object) { const server = McpSettings.load(organization, this._mainMcp).server(); const message = JSONRPCMessageSchema.parse(body); const transport = new McpTransport(organization); await server.connect(transport); transport.handlePostMessage(message); return {}; } } Decorators FTW 🎖️ זה בשבילך אם אתה מעריץ גדול של מסגרות OOP כמו NestJS/Laravel/Spring. @McpTool({ toolName: 'POSTIZ_GET_CONFIG_ID' }) async preRun() { return [ { type: 'text', text: `id: ${makeId(10)} Today date is ${dayjs.utc().format()}`, }, ]; } @McpTool({ toolName: 'POSTIZ_PROVIDERS_LIST' }) async listOfProviders(organization: string) { const list = ( await this._integrationService.getIntegrationsList(organization) ).map((org) => ({ id: org.id, name: org.name, identifier: org.providerIdentifier, picture: org.picture, disabled: org.disabled, profile: org.profile, customer: org.customer ? { id: org.customer.id, name: org.customer.name, } : undefined, })); return [{ type: 'text', text: JSON.stringify(list) }]; } @McpTool({ toolName: 'POSTIZ_SCHEDULE_POST', zod: { type: eenum(['draft', 'scheduled']), configId: string(), generatePictures: boolean(), date: string().describe('UTC TIME'), providerId: string().describe('Use POSTIZ_PROVIDERS_LIST to get the id'), posts: array(object({ text: string(), images: array(string()) })), }, }) async schedulePost( organization: string, obj: { type: 'draft' | 'schedule'; generatePictures: boolean; date: string; providerId: string; posts: { text: string }[]; } ) { const create = await this._postsService.createPost(organization, { date: obj.date, type: obj.type, tags: [], posts: [ { group: makeId(10), value: await Promise.all( obj.posts.map(async (post) => ({ content: post.text, id: makeId(10), image: !obj.generatePictures ? [] : [ { id: makeId(10), path: await this._openAiService.generateImage( post.text, true ), }, ], })) ), // @ts-ignore settings: {}, integration: { id: obj.providerId, }, }, ], }); return [ { type: 'text', text: `Post created successfully, check it here: ${process.env.FRONTEND_URL}/p/${create[0].postId}`, }, ]; } את כל הקוד ניתן למצוא בפוסטים כאן: https://github.com/gitroomhq/postiz-app/tree/main/libraries/nestjs-libraries/src/mcp וכאן : https://github.com/gitroomhq/postiz-app/tree/main/apps/backend/src/mcp תגיות קשורות תגיות קשורות תגיות קשורות תגיות קשורות זה יהיה נחמד שיש אפשרות מובנית להכריח את LLM לעשות דברים שונים לפני שהוא מקבל גישה לדברים שלנו. בכל פעם שאמרתי לקורסור לתזמן עבורי פוסט, הוא ניסה לתזמן אותו ל-2024. הייתי צריך להעביר כמה פרטים Config, אז יצרתי את מקווה, LLM תמיד יקרא את זה לפני שאתה עושה דברים. POSTIZ_CONFIGURATION_PRERUN אבל זה התעלם מזה פעמים רבות (טיפוסי), אז הייתי צריך להיות יצירתי. הוספתי נכס חדש בשם ושינתה את שם הכלי Config ל התוצאה של Config היא: POSTIZ_SCHEDULE_POST configId POSTIZ_GET_CONFIG_ID. id: ${makeId(10)} Today date is ${dayjs.utc().format()} זה הכריח את LLM תמיד לקרוא לו קודם לכן, ואת התאריך היה קבוע! :) זה היה אפילו יותר טוב בשבילי כי ידעתי שזה ישלח לי תאריכים UTC מעכשיו. שימוש מקרים אני חושב שזה עובד הכי טוב כאשר הוא משולב עם מספר קבוצות של כלים, למשל: → → → → התחבר ל- Cursor ולבקש ממנו לתזמן פוסט על העבודה שלך היום. צור קשר עם Notion ולבקש לתזמן את כל העבודה האחרונה של הצוות ברשתות החברתיות - בדוק את Composio MCPs. חיבר אותו לכל מערכת SaaS שיש לה CopilotKit ותזמן פוסטים בהתבסס על האפליקציה. תגית: MCP הוא כלי התזמון החברתי הפתוח ביותר - ועכשיו התזמורת היחידה המציעה MCP (באופן טבעי, לא עם Zapier או משהו כזה) פוסטים עם MCP החדש, אתה יכול לתזמן את כל הפוסטים שלך מ Cursor / Windsurf ו Anthropic לקוחות. הכל 100% בחינם כמובן :) אם אתה אוהב את זה, אנא אל תשכח לכוכב אותנו ⭐️ HTTPS://github.com/Gitroomhq/Postiz-app