Short answer
The one serving them. OpenAI shipped ChatGPT support for MCP Events on 29 September 2026, so a server can push data on a standing subscription, and the draft defines no way to list live subscriptions. Whatever holds your notes has to keep that list itself: every connection, what it reached, and a revoke button.
Until last week, an AI reaching your team's notes was something that happened while you were looking at it. You asked, the agent called a tool, the tool returned, and the moment ended. MCP Events ends that. A subscription is a grant that keeps working after everyone has gone home, and the draft that defines it defines no way to list the ones you have given out.
What did OpenAI actually ship on 29 September?
At DevDay on 29 September 2026, OpenAI added ChatGPT support for the proposed MCP Events extension. OpenAI's developer documentation says ChatGPT calls three methods on your server: events/list to discover what it can watch, events/subscribe to create or refresh a subscription, and events/unsubscribe to stop. Your server advertises support by returning "events": {} in its server/discover capabilities, verifies the callback with a signed single-use challenge before it sends any application data, then POSTs each event to an HTTPS URL signed per Standard Webhooks.
The extension is not part of the MCP specification. It lives in modelcontextprotocol/experimental-ext-triggers-events, is marked Status: Draft proposal, and is dated 2026-02-19. OpenAI's page requires protocol revision 2026-07-28, supports webhook delivery only, caps a payload at 256 KiB, and lists availability as Work chats on ChatGPT web, Work chats in the desktop app with Cloud selected, and with dots.
The direction of travel is what matters. Every MCP call before this was a pull: the client asked, the server answered, nothing persisted. An event subscription is the server holding a standing instruction to send.
Why is a subscription different from a tool call?
Because a tool call is checked when it happens and a subscription is checked when it is made.
The draft is explicit that events/subscribe must run as an authenticated principal and that the subscription key is the tuple (principal, delivery.url, name, arguments). It is also explicit about the lifetime: the client suggests a ttlMs, the server returns a refreshBefore timestamp which is the actual grant, and refreshBefore: null grants no expiry at all. The client re-calls events/subscribe before that timestamp to stay alive. On revocation the design sketch says the server "SHOULD periodically re-verify permissions" without defining what periodically means.
So the thing holding open access to your data is a row in someone's database with a webhook URL on it. That is a credential, whatever it is called in the schema. WorkOS made the same observation from the identity side, and noted the design sketch states there is no server-side subscription listing method.
This is the point where it stops being a protocol question and becomes a question about where your team's knowledge lives. If the only durable record of what is still plugged into your notes is kept by the server that holds your notes, then choosing that server is the control. Baalda is a team second brain built on plain markdown files on your own disk, open source under Apache-2.0, that serves MCP at POST /api/mcp, and the part of it that answers this story is not the editor. It is the connection list.
Who can tell you what is still subscribed to your team's notes?
Only the thing serving them. ChatGPT will call events/unsubscribe when a person clicks "Stop monitoring", but OpenAI's documentation does not describe a place to see every live subscription across a workspace, and the draft gives servers no listing method to build one from. A team of ten has no identity function and no quarterly access review. The list has to come for free or it does not exist.
In Baalda it comes from the token. Every connection into a vault is a minted mcp_ token, scoped to one user and one vault, stored only as its sha256 hash so the plaintext exists exactly once, at creation. Vault Settings → MCP then shows the connections as a list, and each row carries:
- A live dot. MCP here is stateless HTTP with no socket to watch, so "Connected" means the token made a request in the last three minutes.
- The client's name, read off the User-Agent it sent. Claude Code, Cursor, Claude, or the leading token of whatever else connected.
- The token prefix, so you can tell two connections apart without seeing either secret.
- A call count, bumped per
tools/callrather than per JSON-RPC message, so the number reflects work done and not handshakes. - Last active, as a relative time.
- An expandable list of the 22 tools that connection can reach, each badged read, write or delete.
- Revoke.
None of that is an audit product you buy separately. It is the same row the server reads to answer the request.
What happens when someone leaves?
The call fails, on the next call.
A Baalda MCP token encodes a user and a vault, and verifyMcpToken re-checks that user's role in that vault on every single request rather than trusting the grant that was made when the token was minted. Lose membership and the next request from that token resolves to nothing. The OAuth path does the same: consent records which vault a connector was pointed at, keyed by client and user, and the bearer is resolved through the identical membership check, so both doors land in the same place.
Compare that to the gap the MCP Events draft leaves open. A subscription granted with ttlMs: null has no refresh cycle at all, so there is no moment at which a revoked permission is noticed. Re-checking on every request is not a clever feature. It is just the only honest place to put the check when the grant outlives the conversation.
What does Baalda not do here?
It does not do MCP Events, and that is a real gap rather than a position.
Baalda's MCP server implements protocol revision 2025-06-18. It has no events/list, no events/subscribe, no events/unsubscribe, and it does not advertise an events capability. GET /api/mcp returns 405, because there is no server-to-client stream of any kind. Baalda is pull only: an agent asks, the server answers, nothing is left standing. So the actual thing OpenAI shipped on 29 September, ChatGPT reacting the moment a note changes, is not something you can do against a Baalda vault today. If that automation is what you need this quarter, a Notion or Linear MCP server that has shipped Events is the honest answer, and our Notion comparison is fairer about where Notion wins than this paragraph has room for.
Two more limits worth saying plainly. Revoking a connection stops the next read; it does not unsay what a model already read, and no access control anywhere does. And a list of connections only helps if somebody opens it. The reason to care that it is one screen rather than a log export is that one screen is the only kind of review a ten-person team actually performs.
Where does this leave a team of ten?
With one question to answer before the next connector gets added, and it is not a protocol question.
Pull-based MCP is about to stop being the only shape. The subscriptions are coming, from OpenAI first and from everyone else behind it, and they are good: an agent that notices a spec changed is worth more than one that has to be asked. What arrives with them is a class of access that persists, that nobody has to be present for, and that the current draft gives you no standard way to enumerate.
So the thing to check about whatever holds your team's written knowledge is narrow. Can you see, today, in one place, every client that can reach it, what each one is allowed to touch, when it last did, and can you cut one. If the answer is a support ticket, the answer is no. Connecting an AI to your notes over MCP is the easy half. Being able to disconnect it is the half that decides whether a team second brain is something you own or something you are renting, and it is the same reason the open source, local-first case was never really about the licence text. The setup for Baalda's own endpoint is in the MCP doc.
