Inspiration
Okay so here's the thing that was driving us a little crazy before this project even had a name: everyone's work is scattered across like five different tabs. Jira has the tickets, Notion has the specs, ClickUp has the sprint, the calendar has the meetings, and the inbox has all the "hey can you..." messages. Nobody's tool sees the whole picture, and we kept thinking, why isn't there just one brain sitting across all of it? Something connected with your own permissions that can actually answer questions or take action from one place, even when the request spans two apps at once, like "read my Q3 Roadmap in Notion and make a Jira ticket for each initiative on it." That question is basically the whole project.
What it does
There's one endpoint, POST /assistant/brain, and you just talk to it in plain English. It figures out which of your connected tools it needs to touch (Jira, Notion, ClickUp) and chains them together in a single turn. So you can ask it to read a Notion roadmap and create a Jira ticket per initiative, and it genuinely just does that. No copy pasting, no switching tabs. It only shows you tools for apps you've actually connected, both reads and writes work end to end (searching and reading across all three, creating real Jira issues and Notion pages straight from a chat message), and every action passes through a policy engine that flat out refuses destructive operations no matter what a provider claims it can do.
How we built it
We split the whole thing into two halves on purpose: a synchronous API you actually talk to, and a separate background worker that handles anything time based or long running. NestJS and PostgreSQL underneath, with a Prisma schema that models how work actually looks, things like tasks, docs, messages, meetings, decisions, typed relationships like blocks and depends_on, agent runs, approvals, a full audit trail, instead of just dumping everything into a chat log. That schema is honestly the backbone of the whole project, since it means the parts we didn't get to build yet are already shaped and just waiting to be wired up.
The brain is the part we're most excited about. It's one endpoint, POST /assistant/brain, sitting behind a model that does native tool calling, and it only ever gets offered tools for the apps you've actually connected. Jira, Notion, and ClickUp all connect through their own hosted MCP servers over OAuth, and instead of hard coding what each provider can do, we built a shared tool registry that providers just register themselves into. So the orchestrator has no idea it's talking to "Jira" specifically, it just sees a set of typed tools, which means adding a new app later is a registration, not a rewrite. Every action also has to pass through a policy engine before anything actually happens, and that engine hard disables destructive stuff like deletes no matter what a provider's MCP claims it supports. For the model itself we built a swappable provider contract so the brain isn't married to one vendor, we ran Groq's gpt-oss-120b as the main brain with Bedrock's Gemma 3 4B as a fallback, and switching between them (or dropping in something stronger later) is a single env var, not a rewrite.
The cron and background job side is the half we designed in real depth but didn't get to fully build, and we wanted to be upfront about that rather than hide it. The idea is a Redis and BullMQ worker sitting behind everything, doing five things: assembling a nightly "here's what's on fire, what's blocked, what's due" brief without anyone asking, running incremental sync jobs so we're reading from a fresh local copy instead of hitting providers live every single time, renewing webhooks before they expire (since Jira, Gmail, and Google Calendar all quietly expire things on totally different clocks), retrying failed jobs with backoff and routing dead ones to a dead letter queue instead of just losing them, and running a delayed check after every approved write to actually confirm the change stuck, since we never wanted to just trust the model's word that something worked. Right now SyncCoordinatorService is a deliberate stub that returns a well formed sync request, so the moment Redis gets added, BullMQ can just pick it up and run.
Codex was honestly a huge part of getting from the fuzzy idea to this actual shape. It helped design the propose, approve, execute, verify loop, the API and worker split, and the SourceObject work graph instead of forcing everything into a generic "task." It also caught real problems early, our Notion adapter being pinned to an outdated API version, OAuth callbacks needing user bound state so accounts couldn't get mixed up, and ClickUp's own docs actually contradicting each other on whether delete tools even exist. Beyond the architecture, it also chewed through the less exciting work, DTOs, validation, normalizing the slightly wrong argument names a weaker model kept generating, error mapping, test scaffolding, which freed us up to spend our time on the actual cross app chaining instead of boilerplate.
Challenges we ran into
The biggest challenge honestly wasn't architecture, it was model quality. Gemma 3 4B on Bedrock kept mangling tool calls and had a rough time chaining multi step requests, so a decent chunk of our code exists purely to babysit it, cleaning up slightly wrong argument names, catching malformed tool syntax, retrying when things failed. Groq's bigger model handled things noticeably better, and when we tested against a bigger commercial model it was better still, which told us the gap really was raw capability and not our prompting. We also learned the hard way that MCP isn't some magic uniform layer. Jira, Notion, and ClickUp all expire credentials differently and sign webhooks differently, so that abstraction really has to live in our own policy layer rather than being inherited from the providers. And honestly, we just ran out of time. The whole cron and background jobs side of the architecture (scheduled daily briefs, incremental sync, webhook renewal jobs, retry and dead letter handling, verifying actions after the fact) is fully designed but not built yet. SyncCoordinatorService right now is a deliberate stub just waiting for Redis and BullMQ.
Accomplishments that we're proud of
Getting a real, working cross app loop up and running, not a mock, that actually reads from Notion and writes to Jira in one request, feels genuinely exciting. We're also proud that security wasn't an afterthought here: an encrypted per user token vault, CSRF safe single use OAuth state, a policy engine that refuses destructive actions no matter what an MCP server claims, and a multi tenant setup baked in from day one. The work graph schema turned out detailed enough that the features we didn't get to build yet are already shaped for it, so what's left is wiring things up, not rethinking the whole thing. And we really like that swapping the model brain is just one env var, not a rewrite.
What we learned
Depth beats breadth in a hackathon, no question. One fully working cross app loop taught us so much more than five half connected integrations would have. MCP is not a uniform abstraction, every provider disagrees with itself on the details, so the policy layer has to be ours and not something we can just inherit. Never trust the model with credentials, and never trust its word that something "worked." Tokens stay locked in our own handlers, and success has to come from an actual provider receipt. A good schema goes a long way. Modeling the full work graph early meant that even the features we hadn't built yet already had a place in the design. On the flip side, weaker models need a lot more guardrails, and a surprising amount of our code is just there to handle their mistakes.
What's next
Next up is standing up Redis and BullMQ and the actual worker process so we can turn on scheduled daily briefs, cursor based incremental sync, webhook renewal crons, and delayed post action verification. After that, Gmail and Google Calendar, both already modeled in the schema and ready to go. Down the line we'd love to expose the whole thing as our own MCP server so tools like ChatGPT and Claude could use it as a work context source too.
Log in or sign up for Devpost to join the conversation.