npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ebitex/content-mcp

v0.5.106

Published

An MCP server for ebitex Content: build and publish a content model from an AI agent.

Downloads

1,831

Readme

@ebitex/content-mcp

An MCP server for ebitex Content. Point an AI agent at it and it can build a content model end to end — Contracts and their fields, Templates, Components, the Experience tree — and publish it.

It runs locally, over stdio, authenticated by a Content management key you mint yourself. Nothing is hosted by ebitex, so your write-capable key never leaves your machine.

Configure it

{
  "mcpServers": {
    "ebitex-content": {
      "command": "npx",
      "args": ["-y", "@ebitex/content-mcp"],
      "env": { "EBITEX_CONTENT_MANAGEMENT_KEY": "frm_live_..." }
    }
  }
}

| Variable | | |---|---| | EBITEX_CONTENT_MANAGEMENT_KEY | Required. Mint one in Content under Settings → API Keys → Management keys | | EBITEX_CONTENT_API_BASE | Defaults to https://api.ebitex.io | | EBITEX_CONTENT_MCP_READ_ONLY | Set to 1 to hide every write tool regardless of the key's scopes | | EBITEX_CONTENT_TARGET_MANAGEMENT_KEY | A second key, for content_transfer to import into |

Mint the key deliberately

A management key is bound to one organization and one authoring environment, and acts as one role. That binding is the real safety boundary here, and it is the one this server cannot supply for you:

  • Bind it to a non-production authoring environment. This server has no way to tell which of your environments is production — that is your own topology, and a management key deliberately cannot see it. A heuristic would be worse than nothing, because it would be believed.
  • Leave the authoring scope off unless the agent needs to write. Without it, the write tools are not merely refused; they are not offered at all.
  • Give it a role with the access it needs and no more. Branch access rules and workflow gating apply to a key exactly as they do to a person.

On startup the server prints, to stderr, which organization and environment the key reached and which role it acts as. Read it once; if it is not what you expected, stop.

The tools

Ten, shaped around what an agent does rather than around REST routes.

| | | |---|---| | content_whoami | Where this key is scoped: organization, environment, role, scopes, this server's version, and which tools were withheld and why. Needs no scope, so a key that can do almost nothing can still ask why | | content_describe | What can exist here: every field type with its own settings schema, plus this environment's Contracts and Templates | | content_find | Locate entities by kind, search or external id, with one paging contract across both listings | | content_get | Read one entity in full | | content_write | Create or update one entity | | content_delete | Delete one, behind an explicit confirmation | | content_publish | Plan, read the blockers, then publish | | content_operation_status | Poll a job | | content_transfer | Move a whole model between environments, atomically. identityMode picks how items are matched: externalId (the default, by natural key), preserve (by id), or fresh (everything new) | | content_topology | Where this environment sits: the delivery environments a publish lands in, and its promotion and inheritance neighbours. One hop only |

Which of them appear depends on your key's scopes: a read-scoped key gets a server with no write tools at all, rather than tools that always fail. content_whoami is the exception and always appears — it reports which tools were withheld and what each would need, so an absent tool is explained rather than merely missing.

Every result also names the organization and environment it was answered in, and an empty one says so explicitly. A key reads and writes exactly one authoring environment, so "no Contracts" always means "none here" — an agent that reads it as "none anywhere" creates duplicates.

Why it cannot drift

The server encodes no knowledge of the content model. It does not know what field types exist, what a Contract may contain, or what makes a document valid. All three are answered at runtime: content_describe returns each field type's own declared schema, and every write is validated by the server that stores it. There is nothing here to fall out of step, because nothing is duplicated.

That also shapes how errors work. A refusal is relayed whole, with its field paths intact and no summarizing, because for an agent the error is the control loop: try, read the error, fix the one field it names, call again.

Resources

Alongside the tools, the server offers the Content documentation as MCP resources — start with ebitex-content://help/agent-authoring, which explains what Contracts, Templates, Presentations, Adapters and the Experience tree are for, and the order to create them in.

Embedding it

import { buildServer, readConfig } from '@ebitex/content-mcp'

const { server, banner } = await buildServer({ config: readConfig() })
console.error(banner) // never stdout — on stdio, that stream is the protocol

A note on zod

This package pins zod to ^3.25.76 rather than ^4, even though @modelcontextprotocol/sdk accepts either. The reason is type identity, not capability: the SDK's schema types are written against whichever zod resolves for it, and a second copy at a different major produces a type mismatch on every tool registration. Pinning to the version the SDK resolves keeps one zod in the tree. This matters at build time only; at runtime the SDK handles both.

Licence

Apache-2.0 — © ebitex software LLC.

Full guide: developers.ebitex.io.