Som dosť závislý na seriáli Posledný z nás.
MCP sú všade a z dobrého dôvodu.Je to ďalší krok v evolúcii aplikácií.
Byť schopný používať všetko z jedného chatu bez prístupu k žiadnej aplikácii.Poštovnénaplánovať všetky vaše sociálne príspevky z chatu! Takže som začal kopať do kódu Postiz a pridal k nemu!
MCP repozitórium je trochu zvláštne
Každý MCP má dopravu, ktorá je metódou, ktorú LLM používajú na rozhovor s naším systémom.
There are two primary methods at the moment: Stdio, čo je v podstate príkazový riadok, a SSE.
Naozaj nechápem, prečo si vybrali SSE - je to v podstate dlhá žiadosť, ktorá nikdy nekončí a prenáša udalosti klientovi.
Problém s touto metódou spočíva v tom, že ak chcete odoslať informácie späť na server, musíte odoslať ďalšiu poštovú žiadosť (ako je SSE jednosmerná komunikácia), čo znamená, že musíte držať stav.
V ich príklade držia stav v pamäti aplikácie a hádajte, čo?Mnohí sa sťažujú na úniky pamäte, pretože stav nie je vymazaný, keď sa používateľ odpojí.
Použil by som WebSockets. Majú vstavaný režim spánku a nemusíte preň udržiavať stav.
Kúpanie v
Vykopal som do Anthropic typcript SDK a nebol prekvapený. Cíti sa to hrubé. Veľa vecí sa nepoužíva vo výrobe, ako sú "Zdroje." Spôsob, akým vás vyžadujú, aby ste všetko globálne udržali v pamäti, je katastrofa, ktorá čaká na to, aby sa stalo.
Je tiež ťažké implementovať autentifikáciu a dostať používateľa z kontextu, aby sme mohli získať ich podrobnosti.
Postiz je postavený s NestJS, takže pri použití trasy SSE zatvorí pozorovateľný po odpojení, čo vám umožní odstrániť všetko z pamäte.
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 {};
}
}
Dekorácie ️
To je pre vás, ak ste veľkým fanúšikom OOP rámcov ako NestJS/Laravel/Spring. vytvoril som cool dekorátor vytvoriť nástroje ako API "endpoints".
@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}`,
},
];
}
Celý kód nájdete v Postiz tu:https://github.com/gitroomhq/postiz-app/tree/main/libraries/nestjs-libraries/src/mcp
a tu :https://github.com/gitroomhq/postiz-app/tree/main/apps/backend/src/mcp
Force the LLM to Do Stuff 💪🏻
Bolo by pekné mať vstavanú možnosť nútiť LLM, aby urobil iné veci predtým, než získa prístup k našim veciam.
Vždy, keď som povedal Cursorovi, aby pre mňa naplánoval príspevok, snažil sa naplánovať ho na rok 2024.
Potreboval som odovzdať niektoré detaily konfigurácie, takže som vytvorilPOSTIZ_CONFIGURATION_PRERUN
Dúfam, že LLM to vždy zavolá predtým, než urobí veci.
Ale mnohokrát to ignorovalo (typické), takže som musel byť kreatívny.POSTIZ_SCHEDULE_POST
, pridal som novú nehnuteľnosť s názvomconfigId
a zmeniť názov nástroja config naPOSTIZ_GET_CONFIG_ID.
Výstup konfig je:id: ${makeId(10)} Today date is ${dayjs.utc().format()}
To núti LLM vždy zavolať predtým, a dátum bol stanovený! :)
Bolo to pre mňa ešte lepšie, pretože som vedel, že mi odteraz pošle dátumy UTC.
Použitie prípadov
Myslím, že funguje najlepšie v kombinácii s viacerými súbormi nástrojov, napríklad:
- →
- Pripojte ho k kurzorovi a požiadajte ho, aby naplánoval príspevok o vašej práci dnes. →
- Pripojte ho k Notion a požiadajte o naplánovanie všetkých najnovších prác tímu na sociálnych médiách - pozrite sa na Composio MCPs. →
- Pripojte ho k ľubovoľnému SaaS, ktorý má CopilotKit a naplánujte príspevky na základe aplikácie. →
Poštovné MCP
Poštovnéje najsilnejší nástroj na plánovanie sociálnych médií s otvoreným zdrojovým kódom - a teraz jediný plánovač, ktorý ponúka MCP (natívne, nie so Zapierom alebo niečím podobným)
S novým MCP môžete naplánovať všetky svoje príspevky z klientov Cursor / Windsurf a Anthropic.
Všetko je 100% zadarmo :)
Ak sa vám to páči, nezabudnite nás hviezdiť ⭐️https://github.com/gitroomhq/postiz-aplikácia