Darwinium can turn JSON-RPC requests passing through your CDN into journey events. For an MCP server, this lets you distinguish which tool was called, what arguments were supplied, and what the server returned, even when every call uses the same HTTP endpoint.
Use this guide to configure a catalogue-search tool, verify its data in Investigations, and extend the same pattern to cart and checkout tools. The screenshots show a sample commerce integration. Substitute your own host alias, endpoint, tool names and response schema.
This guide covers observing and protecting your application's MCP traffic. To use an AI assistant to operate Darwinium Portal itself, see Portal MCP assistant.
Start with the traffic path
Your HTTP MCP endpoint must pass through a Darwinium deployment. Start with your CDN integration: Cloudflare, CloudFront, or Akamai. Confirm the mapping and response-body requirements against your target before enabling them.
This walkthrough uses HTTP POST requests containing JSON-RPC and ordinary JSON responses. MCP also supports other transport behavior, including SSE responses and local stdio. A local stdio connection does not pass through your CDN. Validate streaming traffic separately; a JSON response mapping is not evidence that an SSE stream is being decoded. See the MCP transport specification.
Before starting, have:
- Access to Workflows and the correct test node.
- A host alias included in your deployment target, with the MCP endpoint routed through that target.
- A sample request and response from a non-destructive tool, such as a catalogue search.
- Permission to map the selected fields into event data. Choose fields needed for investigation; avoid collecting credentials or whole conversations by default.
1. Create a step for a tool call
Open Workflows, then open your .journey.yaml file from Explorer to use the journey editor. Open the Add Step dropdown and choose JSON-RPC Event. Give the step a recognizable name, such as catalog_search.
In Triggers, configure:
| Field | Example | Purpose |
|---|---|---|
| Host | Your deployed host alias | Select the protected host. The screenshot uses craigsbayhost. |
| JSON-RPC Method | tools/call |
Match the method inside the JSON-RPC message. |
| Custom Predicate (optional) | @["params"]["name"] == "search_shop_catalog" |
Select this tool from the other tools/call requests. |
| Url | /mcp |
Match your MCP HTTP endpoint. |
| Url Match Type | Exact |
Match this endpoint precisely. |

The custom predicate examines the JSON-RPC message. Enter the expression shown, without wrapping it in a JSONPath $[?(...)] filter. The body-extraction paths in the next section use a different syntax.
A tools/list step can record discovery of available tools. A tools/call step with a tool-name predicate records a particular operation. Repeat the latter for tools such as create_cart, update_cart and complete_checkout, rather than treating all requests to /mcp as the same business activity.
2. Map the request arguments
This example request searches the catalogue:
{
"jsonrpc": "2.0",
"id": "search-42",
"method": "tools/call",
"params": {
"name": "search_shop_catalog",
"arguments": { "query": "walking shoes" }
}
}
Open Data Mappings → Request → Body Mappings. Add a JSONPath mapping with Extract to Attribute:
| JSONPath | Destination attribute |
|---|---|
$["params"]["arguments"]["query"] |
custom.general_purpose['query'] |

The request-body mapping waits for Request Body Processed. Review the editor's dependency and body-size messages. In this example the editor reports that extraction applies to the first 1 MB of the cached request body. Test realistic payload sizes, not just a small sample.
For other tools, map the business fields that explain the action: a product ID, cart ID, quantity or checkout ID. Use data mappings and the attribute data model to choose suitable destinations.
Correlate requests without confusing identifiers
Darwinium exposes the JSON-RPC request ID as request_body.query_id and uses the matching response ID when applying JSON-RPC response-body mappings. That ID identifies a request, not a customer or a journey.
To connect multiple tool calls into a journey, configure an appropriate session tie. The sample commerce integration maps params._meta.sessionId to primary_session_tie; that field is an application convention, not a required MCP field or proof of identity. Use a stable value with a defined trust boundary. If a browser checkout and an agent call should share a journey, explicitly design how the same trusted correlation value reaches both. See journeys, steps and events.
3. Map the server's result and errors
An example response is:
{
"jsonrpc": "2.0",
"id": "search-42",
"result": {
"content": [{ "type": "text", "text": "One product found" }],
"structuredContent": {
"products": [{ "id": "shoe-101", "name": "Walking shoe" }],
"pagination": { "hasMore": false }
},
"isError": false
}
}
Open Data Mappings → Response → Body Mappings. Map the fields present in your server's response:
| JSONPath | Example destination | What it tells you |
|---|---|---|
$["result"]["structuredContent"]["products"] |
custom.general_purpose['products'] |
Products returned by this example tool. |
$["result"]["isError"] |
custom.general_purpose['tool_error'] |
Whether the tool reports an execution error. |
$["error"]["code"] |
custom.general_purpose['rpc_error_code'] |
A JSON-RPC protocol error, when present. |

structuredContent is useful when the server supplies it. Some tools return text in result.content; a text value containing serialized JSON is still a string, so a nested JSONPath will not automatically extract its inner fields. Match your actual schema. Tool errors and top-level JSON-RPC errors are distinct, and HTTP 200 alone does not establish that a tool succeeded. See MCP tool results.
Response inspection has target-specific buffering, size and latency implications. For example, CloudFront may need to fetch the origin response in Lambda to inspect a POST response body. Resolve the editor's diagnostics and test those implications before deployment. An assessment that needs the origin's response cannot prevent that same request from reaching the origin.
4. Deploy and verify the event
Follow the deployment lifecycle: review the changed files, commit and push as required by your repository workflow, build, then deploy to the intended test target. Saving a file alone does not make the mapping live.
Send the catalogue-search request through the protected hostname using your MCP client's normal authentication. Then open Investigations, select the same node and a time range containing the request, and filter to your journey and catalog_search step.
Check the event details:
- The expected journey and step matched.
request_body.query_idcontainssearch-42.custom.general_purpose['query']containswalking shoes.- The response mapping contains the expected product data, or the appropriate error field for a failed call.
- If you configured a session tie, subsequent calls appear in the intended journey.
Also send a different tool name: it should not match the search step. Test a failed tool call and a JSON-RPC error so that your investigation view distinguishes them. If your application uses JSON-RPC batches, test response correlation with responses in a different order. Batch behavior belongs to JSON-RPC; do not assume every MCP protocol version or client uses batches.
See Investigations for event search and Customize the event table for displaying mapped attributes.
5. Turn visibility into an operational view
Once events are flowing, build views around the questions your team needs to answer:
| Question | Configure |
|---|---|
| Which tools are used most? | Separate steps by tool, then use a Top X widget grouped by step. |
| Are tool errors increasing? | Map error fields, filter to error events, and chart their volume over time. |
| How does a search lead to checkout? | Map a stable session tie and inspect the journey timeline. |
| Which calls require investigation? | Add rules or models using the available context, then filter by their signals or results. |
Widgets can be used in dashboards and investigations. Counts reflect your configured steps and filters: one HTTP request is not necessarily one event when multiple messages or matching steps are involved.
6. Add policy when you are ready
Use features, rules and signals and a decision strategy to assess the tool call. Examples include an unexpected sequence of checkout operations or a change in behavior across an account's recent interactions. The relevant identifiers and history must be mapped first.
Choose where enforcement occurs:
- In your application: consume the assessment and enforce authorization, transaction limits or additional verification there.
- At the edge: configure a proxy action using information available before the operation must be stopped. Set the dependencies needed by that action.
- After the event: raise an incident or call an external system using a Marketplace integration.
See From risk assessment to action for the complete action path. A decision result alone does not block a request. Likewise, removing a tool from tools/list does not authorize or prevent a direct tools/call; enforce the policy on the call itself.
Treat an agent's declared identity or signature-key URL as an input to verification, not proof of authenticity. Use authenticated identity and verified authorization from your integration. Missing browser profiling is also not, by itself, evidence that a legitimate machine client is malicious.
Troubleshooting
| Symptom | Check |
|---|---|
| No event | Correct node and time range; deployed target and host alias; endpoint route; JSON-RPC method and predicate. Confirm the new configuration was deployed. |
| Search arguments are absent | Request body is JSON, the paths match its schema, and extraction/body-size diagnostics have been addressed. |
| Response fields are absent | Matching JSON-RPC ID, actual response structure and content type, response mapping dependencies, and target response-inspection limits. Check whether the server returned SSE instead of JSON. |
| Calls form separate journeys | The selected session tie is populated consistently and is intended to persist across those calls. A request ID changes per call. |
| A rejected assessment still reaches the server | Verify the action configuration and timing. The decision result and enforcement are separate parts of the integration. |