Skip to main content

Private beta: Request private beta access

zenitya
All posts

Essay7 min read

One MCP connection for every AI tool and skill your team uses

How a team keeps its AI tools and skills in one place and gets them in Claude, ChatGPT, Cursor or any MCP client, with a worked example for a marketing and a finance team.

Jakub KotowskiCo-founder, Zenitya

Zenitya keeps a team's AI tools and skills in one place and serves them to every agent through a single MCP connection, https://api.zenitya.com/mcp. Whoever is in the right group gets the same tools and the same instructions in Claude, ChatGPT, Cursor, Pi or any other MCP client, on a laptop, in a cloud agent or in a web chat.

I want to explain why we built it this way and what it looks like in a real company, with a marketing team and a finance team as the example.

Every agent setup is personal, and that is the problem

In a team of ten people using agents there are usually ten different setups. One person has a great script for pulling campaign numbers. Another has a prompt in their notes that finally makes the agent format the weekly report correctly. A third connected five MCP servers on their laptop and none of it exists in their cloud agent or in Claude on their phone.

The knowledge is there, it just does not spread. When the person with the good script is on holiday, the report takes the rest of the team an afternoon. When someone new joins, they start from zero and rebuild the same things the team already has.

What changes with one connection

Zenitya splits the work into two things, and both live in your repositories:

  • Tools are TypeScript functions with a strict schema, written with @zenitya/sdk and shipped with zya deploy. They run the same way every time, in Zenitya's cloud, with the credentials they need kept as secrets.
  • Skills are SKILL.md files that describe how your organization works: the process, the policy, which tool to call and in what order. They follow the open Agent Skills format.

Groups decide who gets what. A group holds people, service accounts and Slack or Discord channels, and you grant tools and skills to the group. Each person connects their agent once, signs in with Google and from then on sees exactly what their groups give them. When a tool or skill changes, the next request already uses the new version and nobody needs to reconnect.

For one person with many tools

Even alone this is useful. Your tools stop living in one machine's config. The same campaignPerformance tool works in Claude Code at the desk, in Claude on the web when you are away from it, and in a scheduled cloud agent at night. You build it once and you stop copying configs and API keys between places.

For teams: one person builds it, everyone has it

We built Zenitya mainly for teams that want to grow faster with AI. In most teams one or two people are much further with agents than everyone else. They are the ones who should build the tools and write the skills, and everyone else should simply have them in the agent they prefer.

That is the whole point. A power user packages the workflow once and the whole group does the work better and faster, without learning how the workflow was built. Onboarding follows from the same idea: a new hire, or someone moving teams, gets the team's tools and skills the moment they join its group.

Example: marketing and finance in one company

Say a company has a marketing team that writes a weekly performance report and a finance team that checks spend at the end of each month. Both teams already ask agents for help, each person in their own way.

Step 1: the marketing tools

The marketing analyst, the one who already had the good script, turns it into a project called marketing with two tools. campaignPerformance returns spend, conversions and cost per acquisition per campaign for a date range, read from the data warehouse. budgetPacing compares spend so far with the monthly budget for each channel.

marketing/src/index.ts
project.tool("campaignPerformance", {
  title: "Campaign performance",
  description:
    "Spend, conversions and cost per acquisition per campaign between two dates, " +
    "from the warehouse. Use for performance reports and campaign comparisons.",
  schema: s.object({
    from: s.date().describe("First day, YYYY-MM-DD."),
    to: s.date().describe("Last day, YYYY-MM-DD."),
    channel: s
      .enum("search", "social", "display")
      .nullable()
      .describe("One channel, or null for all."),
  }),
  outputSchema: s.array(
    s.object({
      campaign: s.string(),
      channel: s.string(),
      spend: s.number(),
      conversions: s.integer(),
      costPerAcquisition: s.number().nullable(),
    }),
  ),
  hints: { readOnlyHint: true, idempotentHint: true },
  execute: async ({ from, to, channel }, { signal }) => {
    const token = process.env.WAREHOUSE_TOKEN;
    const rows = await queryWarehouse(token, { from, to, channel }, signal);
    return summarisePerCampaign(rows);
  },
});

The tool reads the warehouse with a token an admin set once as a secret (zya secrets set WAREHOUSE_TOKEN --stdin), so nobody else needs the token on their machine. The output is already summed per campaign, so the agent gets a short table instead of thousands of raw rows.

Step 2: the marketing skill

Next the analyst writes down how the team actually reads the numbers. This is the part that usually lives only in one person's head:

marketing/skills/weekly-marketing-report/SKILL.md
---
name: weekly-marketing-report
description: Use when someone asks how campaigns performed, or for the weekly marketing report. Covers which numbers to pull, how to compare them and what to flag.
---

1. Call `marketing.campaignPerformance` for last week and for the four weeks before.
2. Call `marketing.budgetPacing` for the current month.
3. Compare each campaign's cost per acquisition with its four-week average.
   Flag anything more than 20% worse, and any channel pacing over 110% of budget.
4. Write the report as: three lines of summary, a table per channel, then the flags
   with one suggested action each. No campaign with fewer than 10 conversions
   gets a verdict, only a note that the data is too thin.

Step 3: the finance tools and skill

The finance lead does the same in a project called finance: invoiceAging lists unpaid invoices by how overdue they are, and monthlySpend sums spend by cost center from the accounting system. A month-end-check skill says what to compare against the budget, what counts as a variance worth explaining and who to ask about each cost center.

Step 4: groups

Then an admin grants everything in the Zenitya app:

  • Marketing group: marketing.campaignPerformance, marketing.budgetPacing and the weekly-marketing-report skill.
  • Finance group: finance.invoiceAging, finance.monthlySpend and the month-end-check skill.
  • Leadership group: marketing.budgetPacing and finance.monthlySpend, so they can ask about spend without access to invoice details.
  • The #marketing Slack channel: the report tools, so a bot can post the weekly report there.

What it looks like for everyone else

A marketer opens Claude and asks how the campaigns did last week. The agent sees the weekly-marketing-report skill, loads it, calls marketing.campaignPerformance for the two periods, calls marketing.budgetPacing and writes the report the way the team agreed. A colleague who prefers ChatGPT asks the same question and gets the same numbers, because the numbers come from the same tool.

The CFO asks in Cursor whether marketing will stay within budget this month. Their agent sees budgetPacing through the Leadership group and answers from it. They never see the invoice tools.

When the team decides that cost per acquisition should be compared over six weeks instead of four, the analyst changes one line in the skill and deploys it. From the next request every agent in the Marketing group follows the new rule.

What it saves

Packaging a workflow into a tool also costs less than letting each agent work it out. In our own measurement of one task, an agent working through a described workflow on its own (MCP calls, its own scripts, retries) was compared with the same workflow as one custom tool. With the tool it used 31% fewer tokens, cost 23% less, took 26% less time, needed 25% fewer turns and had 55% fewer failed calls. Each figure is the median of 3 runs each way.

The bigger saving for a team is harder to measure: the hours people spend rebuilding what a colleague already has.

Questions people ask

Which agents can use Zenitya?

Any client that supports remote MCP servers over streamable HTTP. The docs have setup steps for Claude Code, Claude on web and desktop, ChatGPT and Codex, Cursor and Pi. People sign in with OAuth, and scripts, bots and cloud agents use a service account key.

Where does the code of a tool run?

Deployed tools run in Zenitya's cloud, in an isolated microVM per project, without internet access unless the project turns it on. While you develop, zya exec --local runs the source on your own machine.

Can I connect MCP servers we already use?

Yes. Owners can connect existing MCP servers such as Linear or Sentry, and their tools are served through the same endpoint and granted through the same groups as your own.

Does everyone on the team need to write code?

Only the people who build tools. Skills are markdown, and a project can publish only skills. Everyone else connects their agent once and uses what their groups give them.

Further reading

Jakub Kotowski is a co-founder and engineer at Zenitya, building the infrastructure that shares tools and skills across a whole team, in any agent or harness.

Jakub Kotowski on LinkedIn