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.
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:
Uddihas no uniqueness check → always reportsexists:falsewithcheckedOnServer: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, notEXT_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 insrc/http-invoker.js(RemoteInvocation) andsrc/java-serialization.js(java.lang.String, and the enum descriptors). - Enum gotcha (already handled): the
java.lang.Enumsuper descriptor must be flaggedSC_ENUMtoo (0x12), else the server throwsInvalidClassException: 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
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
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.
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.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
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.
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.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
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.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.