Wrap an AJAX app class as an MCP DPC

Learn how to wrap an existing AJAX app class as a Data Provider Class (DPC) for the Hub MCP Designer, using a sales orders app class as an example.

An AJAX app class uses a single handle_on_ajax entry point that dispatches to internal logic based on an ajax_id value, and exchanges data via public attributes and a single ajax_value. The Hub MCP Designer instead derives tools from individual method signatures. The wrapper class exposes each AJAX operation as a dedicated method with explicit importing and exporting parameters.

Creating the wrapper class also gives you the opportunity to improve on the naming used in the source class without modifying it.

Prerequisites

  • You have an existing AJAX app class implementing /neptune/if_nad_server.

  • You have reviewed the handle_on_ajax implementation to identify which ajax_id values are handled, which public attributes carry input and output data for each, and whether and how ajax_value is used.

Procedure

Define the MCP wrapper class

Create a new ABAP class and declare the MCP DPC interface /neptune/if_dxp_mcp_dpc. For each ajax_id you want to expose as a tool, declare a corresponding public method with the relevant input data — including ajax_value where it is used — as importing parameters, and the relevant output attributes as exporting parameters. Signature typing can refer to public attributes in the AJAX class using like for simplicity.

The following shows the source AJAX class definition and its handle_on_ajax implementation, followed by the corresponding MCP wrapper class definition.

Source AJAX class definition
class ycl_sd_sales_orders_ajax definition
  public
  final
  create public .

  public section.
    interfaces /neptune/if_nad_server.

    types:
      begin of ty_order.
        include type zui5_sd_order_vbak.
      types:
        name1 type kna1-name1,
        kunnr type vbak-kunnr,
      end of ty_order .

    types:
      begin of ty_get_order_list,
        vbeln type vbeln,
        vkorg type vkorg,
        erdat type erdat,
        kunnr type kunnr,
        auart type auart,
        ernam type ernam,
      end of ty_get_order_list.

    data it_order_items    type zui5_sd_vbap_tt .
    data it_order_list     type table of ty_order .
    data it_customer_list  type zui5_sd_customer_list_tt .
    data it_return         type bapiret2_tt .
    data wa_customer       type zui5_sd_customer_list .
    data gv_page_home      type zui5_sd_global_customer .
    data gv_settings       type zui5_sd_settings .
    data wa_get_order_list type ty_get_order_list .

    methods get_customer_list
      importing
        !vkorg type vkorg default '1000' .

    methods save_order .

    methods get_order_list
      importing
        !vbeln type vbeln optional
        !vkorg type vkorg default '1000'
        !erdat type erdat optional
        !kunnr type kunnr optional
        !auart type auart optional
        !ernam type ernam optional .
endclass.
Source AJAX class handle_on_ajax implementation (excerpt)
class ycl_sd_sales_orders_ajax implementation.
  method /neptune/if_nad_server~handle_on_ajax.

    data lv_vkorg type vkorg.

    case ajax_id.
      when 'GET_CUSTOMER_LIST'.
        lv_vkorg = ajax_value.
        get_customer_list( vkorg = lv_vkorg ).

      when 'GET_ORDER_LIST'.
        get_order_list( vbeln = wa_get_order_list-vbeln
                        vkorg = wa_get_order_list-vkorg
                        erdat = wa_get_order_list-erdat
                        kunnr = wa_get_order_list-kunnr
                        auart = wa_get_order_list-auart
                        ernam = wa_get_order_list-ernam ).

      when 'SAVE_ORDER'.
        save_order( ).
    endcase.

  endmethod.
endclass.
MCP wrapper class definition
class ycl_sd_sales_orders_ajax_mcp definition
  public
  final
  create public .

  public section.
    interfaces /neptune/if_dxp_mcp_dpc.

    methods get_customer_list
      importing
        vkorg         type vkorg default '1000'
      exporting
        customer_list like ycl_sd_sales_orders_ajax=>it_customer_list
        page_home     like ycl_sd_sales_orders_ajax=>gv_page_home.

    methods get_order_list
      importing
        vbeln type vbeln optional
        vkorg type vkorg default '1000'
        erdat type erdat optional
        kunnr type kunnr optional
        auart type auart optional
        ernam type ernam optional
      exporting
        it_order_list like ycl_sd_sales_orders_ajax=>it_order_list.

    methods save_order
      importing
        it_order_items like ycl_sd_sales_orders_ajax=>it_order_items
        gv_settings    like ycl_sd_sales_orders_ajax=>gv_settings
        wa_customer    like ycl_sd_sales_orders_ajax=>wa_customer
      exporting
        it_order_list  like ycl_sd_sales_orders_ajax=>it_order_list.

  protected section.
  private section.
endclass.
The method names defined here become the tool names in the Hub MCP Designer, and the parameter names become the JSON schema for those tools. See MCP tool design best practices for naming and parameter design guidance.

Implement each method

For each method, the implementation follows the same pattern:

  1. Instantiate the AJAX class and a dummy /neptune/cl_nad_server instance. Declare dummy structures for request, return, and navigation.

  2. Set the relevant public attributes on the AJAX class instance from the importing parameters of the wrapper method. If ajax_value is used for this call, assign it accordingly.

  3. Call handle_on_ajax on the AJAX class instance with the correct ajax_id for this operation.

  4. Assign the relevant public attributes of the AJAX class instance to the exporting parameters of the wrapper method.

  5. If return or navigation data is used for this AJAX call, implement handling logic accordingly.

class ycl_sd_sales_orders_ajax_mcp implementation.

  method get_customer_list.
    data wrapper         type ref to ycl_sd_sales_orders_ajax.
    data nad_server      type ref to /neptune/cl_nad_server.
    data data_request    type /neptune/data_request.
    data data_navigation type /neptune/ajax_navigation.
    data data_return     type /neptune/ajax_return.
    data ajax_value      type string.

    create object wrapper.
    create object nad_server.

    ajax_value = vkorg.

    wrapper->/neptune/if_nad_server~handle_on_ajax(
      exporting
        applid     = 'SD_SALES_ORDERS'
        ajax_id    = 'GET_CUSTOMER_LIST'
        ajax_value = ajax_value
        server     = nad_server
        request    = data_request
      importing
        return     = data_return
      changing
        navigation = data_navigation
    ).

    customer_list = wrapper->it_customer_list.
    page_home     = wrapper->gv_page_home.
  endmethod.

  method get_order_list.
    data wrapper         type ref to ycl_sd_sales_orders_ajax.
    data nad_server      type ref to /neptune/cl_nad_server.
    data data_request    type /neptune/data_request.
    data data_navigation type /neptune/ajax_navigation.
    data data_return     type /neptune/ajax_return.
    data ajax_value      type string.

    create object wrapper.
    create object nad_server.

    wrapper->wa_get_order_list-vbeln = vbeln.
    wrapper->wa_get_order_list-vkorg = vkorg.
    wrapper->wa_get_order_list-erdat = erdat.
    wrapper->wa_get_order_list-kunnr = kunnr.
    wrapper->wa_get_order_list-auart = auart.
    wrapper->wa_get_order_list-ernam = ernam.

    wrapper->/neptune/if_nad_server~handle_on_ajax(
      exporting
        applid     = 'SD_SALES_ORDERS'
        ajax_id    = 'GET_ORDER_LIST'
        ajax_value = ajax_value
        server     = nad_server
        request    = data_request
      importing
        return     = data_return
      changing
        navigation = data_navigation
    ).

    it_order_list = wrapper->it_order_list.
  endmethod.

  method save_order.
    data wrapper         type ref to ycl_sd_sales_orders_ajax.
    data nad_server      type ref to /neptune/cl_nad_server.
    data data_request    type /neptune/data_request.
    data data_navigation type /neptune/ajax_navigation.
    data data_return     type /neptune/ajax_return.
    data ajax_value      type string.

    create object wrapper.
    create object nad_server.

    wrapper->it_order_items = it_order_items.
    wrapper->gv_settings    = gv_settings.
    wrapper->wa_customer    = wa_customer.

    wrapper->/neptune/if_nad_server~handle_on_ajax(
      exporting
        applid     = 'SD_SALES_ORDERS'
        ajax_id    = 'SAVE_ORDER'
        ajax_value = ajax_value
        server     = nad_server
        request    = data_request
      importing
        return     = data_return
      changing
        navigation = data_navigation
    ).

    it_order_list = wrapper->it_order_list.
  endmethod.

endclass.

Register the class as a DPC and configure tools

In the Hub MCP Designer, create a new MCP server and select your wrapper class as the Data Provider Class. Enable and configure the tools you want to expose on the Tools tab, then validate them in the Inspector tab. See Create an MCP server in the Hub MCP Designer.

Results

  • Your existing AJAX app class logic is exposed as MCP tools without modification to the source class, and is ready to be consumed by AI agents operating within Naia Agent Studio.

  • The MCP server is transportable across SAP environments and can be promoted through development, quality, and production via a transport request.