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.
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.
POST /mcp— a spec-compliant MCP endpoint (JSON-RPC 2.0). Connect Claude, Cursor, or any MCP client. Handlesinitialize,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.
| Tool | Params | Purpose |
|---|---|---|
list_business_units | – | Discover business units (with tenant/workspace) and their IDs. |
list_sources | – | List data sources (applications) for the configured business unit. |
list_events | sourceId | List events available for a source. |
ingest_profile | sourceId, eventId, confirm?, customData? | Generate schema-aware mock data; preview (confirm:false) or ingest (confirm:true). |
Credentials are resolved per-request, in this order: request headers → env vars.
- From the UI: enter
userKey,secret,baseUrl,businessUnitIdin 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.
{ "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" } } } }
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.
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
- 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).