Public
Remixed
Remote MCP server for SAP CDP ingestion + a web tester UI
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.

CDP MCP — Remote Server + Tester

A remote MCP server for SAP Customer Data Platform (CDP) data ingestion, plus a built-in web UI to test the tools and inspect results. This is the Val Town port of the original stdio MCP implementation — same logic, exposed over HTTP (Streamable HTTP transport) so any MCP client can connect remotely.

What you get

  • POST /mcp — a spec-compliant MCP endpoint (JSON-RPC 2.0). Connect Claude, Cursor, or any MCP client. Handles initialize, tools/list, tools/call.
  • A nice tester UI at / — pick a tool, fill in args, run it, and see results rendered as tables / JSON payloads (not just raw text).
  • 4 stateless tools: list_business_units, list_sources, list_events, ingest_profile.

Tools

ToolParamsPurpose
list_business_unitsDiscover business units (with tenant/workspace) and their IDs.
list_sourcesList data sources (applications) for the configured business unit.
list_eventssourceIdList events available for a source.
ingest_profilesourceId, eventId, confirm?, customData?Generate schema-aware mock data; preview (confirm:false) or ingest (confirm:true).

Configuration

Credentials are resolved per-request, in this order: request headers → env vars.

  • From the UI: enter userKey, secret, baseUrl, businessUnitId in the Connection panel (stored only in your browser's localStorage).
  • From an MCP client: pass headers X-CDP-userKey, X-CDP-secret, X-CDP-baseUrl, X-CDP-businessUnitId.
  • As val env vars (defaults): userKey, secret, baseUrl, businessUnitId.

Connect an MCP client

{ "mcpServers": { "cdp-ingest": { "url": "https://<your-val>.web.val.run/mcp", "headers": { "X-CDP-userKey": "YOUR_USER_KEY", "X-CDP-secret": "YOUR_SECRET", "X-CDP-baseUrl": "https://universe.cdp.gigya.com", "X-CDP-businessUnitId": "YOUR_BU_ID" } } } }

Architecture

Rendering mermaid diagram...

Both the MCP layer and the UI API call the exact same tool handlers, so the tester reflects precisely what an MCP client sees. The UI additionally renders a structured payload that MCP clients ignore.

File structure

index.ts                       ← Hono entry: /mcp, /api/*, serves UI
server/
  mcp.ts                       ← MCP JSON-RPC over Streamable HTTP
  tools.ts                     ← tool definitions + handlers (shared)
  cdp.ts                       ← authenticated CDP client + services
  mock.ts                      ← schema-aware mock data generator
frontend/
  index.html / index.tsx       ← UI shell + React entry
  lib.ts                       ← client API + config store
  components/
    App.tsx                    ← layout + MCP URL + connect docs
    ConfigPanel.tsx            ← credentials form
    ToolRunner.tsx             ← tool picker + dynamic args form
    ResultView.tsx             ← table / JSON result rendering

Differences from the stdio implementation

  • Transport: stdio → HTTP (Streamable HTTP / JSON-RPC). Same tool contract.
  • Config persistence: no filesystem on Val Town, so config is passed per request (headers / UI / env) instead of ~/.cdp-mcp/config.json.
  • Tenant/workspace selection: collapsed into list_business_units, which returns business unit IDs directly (tenant + workspace shown for context).
  • Mock data: deterministic schema-aware generator (no LLM dependency).