cms-mcp

cms-mcp

An MCP server that reproduces CoreNeo CMS calls for generating OIDs, exception IDs, screen names, and checking definition-name availability, using HTTP Basic auth and Java serialization.

Category
Visit Server

README

cms-mcp

An MCP (Model Context Protocol) server that reproduces the CMS calls made by the CoreNeo Eclipse plugin's New Query / Service / Exception / Screen / ESB actions — generating OIDs / exception ids and checking definition-name availability — implemented purely in Node.js.

It talks to the CMS the same way the plugin's CmsHttpClient does: Spring HttpInvoker over HTTP with HTTP Basic auth. Because HttpInvoker uses Java's native binary serialization, this project ships a small, focused implementation of the Java Object Serialization Stream Protocol (src/java-serialization.js).

Tools

Tool CMS method Notes
generate_oid generateOid(String platform) Returns the OID as a string (Java long). Used by Query/Service/Screen/ESB.
get_next_exception_id getNextExceptionId() Used by the New Exception action.
generate_screen_name generateComponentScreenName(CmsNeoComponent) New FBML/XAML Screen wizard. Returns <module><number> (e.g. ANALYTICS20001). Side-effecting: increments the module screen counter.
list_components getComponentList() Lists components; needed to pick a component for name checks / screen names.
check_definition_name existsQueryDefinition / existsServiceDefinition / existsRegionDefinition / existsPopupDefinition / existsDadDefinition The wizard's "Check Name" button. Supports query/service/region/popup and esb.

How check_definition_name works (capture-replay)

The existsXxxDefinition methods take a CmsNeoComponent object argument. Instead of hand-modelling that entity's serialized form (fragile: field order + every serialVersionUID), the client first calls getComponentList(), captures the real serialized component objects the server sends, and replays the chosen one as the argument — reusing the server's own class descriptor. So name checks stay correct even if the entity changes shape, as long as getComponentList works.

ESB name checks

type: "esb" maps to existsDadDefinition(component, name, GLOBAL_SCOPE, code) — the same call NewESBConfigurationPage makes. Pass configType (Map/GroovyWsdl/GroovyRest/Xslt/Uddi); its code (1–5) becomes the definition type. Notes matching the plugin:

  • Uddi has no uniqueness check → always reports exists:false with checkedOnServer:false (no server call).
  • ESB scope is always GLOBAL_SCOPE (name unique across all components).
  • ESB names are not normalized (kept as-is), and the stored name includes the file extension — e.g. check EXT_SWIFT.cfg, not EXT_SWIFT.

Configuration

By default the server reads the same files the Eclipse plugin uses — no env vars needed:

File Values read
~/.symphony/cms_eclipse_config.xml serviceUrl (the HttpUserService HttpInvoker bean)
~/.symphony/cms_eclipse.properties cmsUserName, cmsPassword (AES-decrypted), cmsDBEnvironment (default platform)

cmsPassword is AES-128/ECB/PKCS5 encrypted with the fixed key from AESConverter — the server decrypts it in memory exactly like the plugin does.

Overrides (all optional)

Environment variables override the files when set:

Var Meaning
CMS_URL Full remoting URL.
CMS_HOST / CMS_PORT / CMS_CONTEXT Build a URL when no CMS_URL/xml URL. Defaults 8081 / cms_server.
CMS_USERNAME / CMS_PASSWORD Plain (already-decrypted) credentials.
CMS_PLATFORM Default platform for generate_oid (else cmsDBEnvironment, else DEV).
CMS_TIMEOUT_MS Per-call timeout (default 60000).
SYMPHONY_DIR .symphony directory (default ~/.symphony).
CMS_CONFIG_XML / CMS_PROPERTIES Point at specific config files (e.g. cms_eclipse_config_kaspi.xml).

On startup the server logs (to stderr) the resolved target, user, platform, and which file each value came from.

Register in Claude Code

Nothing extra needed — it picks up ~/.symphony automatically:

claude mcp add cms -- node C:/workspaces/cms/cms-mcp/src/index.js

To target a different environment file:

claude mcp add cms --env CMS_CONFIG_XML=C:/Users/you/.symphony/cms_eclipse_config_kaspi.xml \
  -- node C:/workspaces/cms/cms-mcp/src/index.js

Or in your MCP client config (.mcp.json / client settings):

{
  "mcpServers": {
    "cms": {
      "command": "node",
      "args": ["C:/workspaces/cms/cms-mcp/src/index.js"]
    }
  }
}

Run / test

npm test          # offline unit + wire + MCP-handshake tests (no live CMS needed)
npm start         # start the stdio server (reads ~/.symphony by default)

Test against the live CMS

scripts/live-check.mjs exercises the real calls directly (reads ~/.symphony, no MCP client needed):

node scripts/live-check.mjs                                  # generate_oid + list_components
node scripts/live-check.mjs oid                              # generate_oid
node scripts/live-check.mjs exid                             # get_next_exception_id
node scripts/live-check.mjs screenname "<component>"         # generate_screen_name
node scripts/live-check.mjs components                       # list_components
node scripts/live-check.mjs check query "<component>" "<NAME>"   # check_definition_name
node scripts/live-check.mjs esbcheck Map "<component>" "<NAME.cfg>"  # ESB name check

Debugging aids: scripts/dump-response.mjs <method> writes a raw serialized response to tmp/<method>.bin; scripts/parse-bin.mjs <file> parses it and reports where (if anywhere) deserialization derails.

Status

Verified end-to-end against the live CMS: generate_oid, get_next_exception_id, list_components (720 components), and check_definition_name for query/service/region/popup and esb (correct true/false both ways). The full getComponentList response also re-serializes byte-for-byte identically, which proves the codec is faithful to the JVM for the real CmsNeoComponent graph.

Notes / gotchas

  • Component descriptors are captured from getComponentList, not constructed, so they can't drift. Constructed descriptors that must stay correct live in src/http-invoker.js (RemoteInvocation) and src/java-serialization.js (java.lang.String, and the enum descriptors).
  • Enum gotcha (already handled): the java.lang.Enum super descriptor must be flagged SC_ENUM too (0x12), else the server throws InvalidClassException: cannot bind non-enum descriptor to an enum class.
  • Field-type signature strings in a class descriptor may be back-references, so the reader resolves them via readContent (not a fresh string read).

Layout

src/
  java-serialization.js  JOSP reader + writer (handles, classdesc, enum, array, block-data)
  http-invoker.js        RemoteInvocation build + POST (Basic auth) + RemoteInvocationResult parse
  values.js              node -> JS conversions; entity field / collection extraction
  cms-client.js          generateOid, getNextExceptionId, getComponentList, existsDefinition
  symphony-config.js         reads ~/.symphony config xml + properties; AES password decrypt
  index.js               MCP server + tool definitions
test/                    serialization / wire / mcp-handshake tests

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured