# Custom plugins

> This document guides you through creating, debugging, and using custom plugins to integrate the APIs you need.

## Workflow <span id="ea374d1871atk" /> <span id="5b7812b7b9zip" />

1. <strong>Createa plugin:</strong> Define the plugin's basic information.
2. <strong>Add a tool:</strong> Configure the specific API path, request parameters, and response data for the plugin.
3. <strong>Debug and publish:</strong> Test the API connectivity online and publish the tool after confirming it works as expected.
4. <strong>Use in an application:</strong> Associate the plugin with an agent and call it through conversational testing or API integration.

## Create a custom plugin <span id="8ac660e6803i9" /> <span id="ab47cd6914sqo" />

<Tabs>
  <Tab title="Create a custom plugin">
    ### Step 1: Create a plugin <span id="d0b31e0c6430t" /> <span id="73cc0cbbc1d5t" />

    1. Go to the [<strong>Plugins</strong>](https://modelstudio.console.alibabacloud.com/?tab=app#/component-manage) page and click <strong>Create Plugin</strong>.
    2. Enter the plugin information.

       <table style={{ display: "table", tableLayout: "fixed", width: "100%" }}>
         <colgroup>
           <col style={{ width: "100%" }} />
         </colgroup>

         <tbody>
           <tr>
             <td>
               <strong>Plug-in Name</strong>: Enter a descriptive name. Chinese and English are supported.

               > Example: Dormitory Agreement Query Tool Test
             </td>
           </tr>

           <tr>
             <td>
               <strong>Plug-in Description</strong>: Briefly describe the plugin's features and purpose in natural language. This description helps the model decide when to use the plugin.

               > Example: Queries the content of a specific dormitory agreement entry based on the input numeric index.
             </td>
           </tr>

           <tr>
             <td rowSpan={2}>
               <strong>Plug-in URL</strong>: The access endpoint of the plugin.

               > Example:[https://domitorgreement-plugin-example-icohrkdjxy.cn-beijing.fcapp.run](https://domitorgreement-plugin-example-icohrkdjxy.cn-beijing.fcapp.run)

               - Model Studio treats different paths under the same domain as different APIs. These paths correspond to the <strong>Tool Path</strong> you configure when creating a tool.
               - Tools within the same plugin share a domain name, but each tool's path maps to a unique API.

                 For example, a plugin contains two APIs:

                 Query: [https://xxx.com/query](https://xxx.com/query)

                 Delete: [https://xxx.com/delete](https://xxx.com/delete)

                 In this example, `https://xxx.com` is the <strong>Plug-in URL</strong>, while `/query` and `/delete` are the <strong>Tool Path</strong> values. This indicates that the plugin contains two tools.
             </td>
           </tr>
         </tbody>
       </table>

       If authentication is required, enable the <strong>Enable Authentication</strong> switch and enter the authentication settings.

       <Accordion title="Authentication parameters">
         <table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "29.537954%" }} /><col style={{ width: "70.462046%" }} /></colgroup><tbody><tr><td><p><strong>Headers</strong> (Optional)</p></td><td><p>If authentication is required, you can pass authentication information in a custom header.</p></td></tr><tr><td><p><strong>Enable Authentication</strong> (Optional)</p></td><td><p>Determines whether an application must provide authentication to call your custom plugin. This depends on your API provider's security policy.</p></td></tr><tr><td><p><strong>Authentication Type</strong></p></td><td><p>There are two authentication methods: <strong>service-level authentication</strong> and <strong>user-level authentication</strong>.</p> <ul><li><p><strong>Location</strong>: You can place the authentication information in the request header or query string.</p> <ul><li><p><strong>Header</strong>: This option places the authentication information in the <code>Authorization</code> header of the HTTP request, keeping it hidden from the URL.</p></li> <li><p><strong>Query</strong>: This option places the authentication information in the URL. For example: <code>[https://example.com?api\_key=123456](https://example.com?api_key=123456)</code>.</p></li></ul></li> <li><p><strong>Parameter Name</strong>: If you place the authentication information in the query string, specify the parameter name used for authentication, such as <code>api\_key</code>. If you place it in the header, the parameter is <code>Authorization</code> by default.</p></li> <li><p><strong>Type</strong>:</p> <ul><li><p><strong>basic</strong>: Does not add any prefix to the token you provide.</p></li> <li><p><strong>bearer</strong>: Adds the <code>Bearer</code> prefix to the token.</p></li> <li><p><strong>appcode</strong>: Adds the <code>APPCODE</code> prefix to the token.</p></li></ul> <p>The prefix is included in the authentication field. For example, if you select <code>bearer</code>, the <code>Authorization</code> header becomes <code>Authorization: Bearer \<YOUR\_TOKEN></code>.</p></li> <li><p><strong>Token</strong> (for service-level authentication): The authentication token from the API provider, such as an API key.</p></li></ul></td></tr></tbody></table>
       </Accordion>
    3. After completing the form, click <strong>Confirm Create Plug-inCreate Tool</strong> or click <strong>Continue to Add Tool</strong>.

    ### Step 2: Create a tool <span id="6bb35787f8cc9" /> <span id="0e9553ee5als9" />

    1. Enter the tool information, configure input and output parameters, and define any advanced settings.

       In this example, enter "Dormitory Rules Query Tool" for <strong>Tool Name</strong> and "Queries the content of a specific dormitory rule based on the input numeric index" for <strong>Tool Description</strong>. Set the <strong>Tool Path</strong> to `/article`, select <strong>POST</strong> for the <strong>Request Method</strong>, and select <strong>application/json</strong> for the <strong>Submission Method</strong>. For the input parameter, set the parameter name to `article_index`, the parameter description to "index", and the type to <strong>Number</strong>. This parameter is passed in the <strong>Body</strong>, is required, and its passing method is <strong>LLM recognition</strong>. For the output parameter, set the parameter name to `article`, the parameter description to "dormitory rule content", and the type to <strong>String</strong>. In the advanced settings, the user input query is "Query the content of the corresponding dormitory rule based on the input index value", and the value of the `article_index` input parameter is `5`.

       <Accordion title="Tool parameters" defaultOpen>
         <Accordion title="Tool information">
           <table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "21.775544%" }} /><col style={{ width: "78.224456%" }} /></colgroup><tbody><tr><td><p><strong>Tool Name</strong></p></td><td><p>Enter a descriptive name. Chinese and English are supported.</p></td></tr><tr><td><p><strong>Tool Description</strong></p></td><td><p>A brief description of the tool's features and use cases.</p> <p>This helps the model decide when to call the tool. Use natural language and provide examples where possible.</p></td></tr><tr><td><p><strong>Tool Path</strong></p></td><td><p>The relative path to the <strong>Plug-in URL</strong>.</p> <p>The path must start with a forward slash (<code>/</code>).</p> <p>The system appends this path to the <strong>Plug-in URL</strong> to construct the full request URL.</p></td></tr><tr><td><p><strong>Request Method</strong></p></td><td><p>Select GET or POST as the request method for calling the API.</p></td></tr><tr><td><p><strong>Submission Method</strong></p></td><td><p>The encoding type for the request body.</p> <ul><li><p><strong>application/json</strong>: The body content is JSON-formatted data.</p></li> <li><p><strong>application/x-www-form-urlencoded</strong>: Encodes form data as key-value pairs.</p> <ul><li><p>This encoding method applies to POST requests. It encodes form data into key-value pairs, separates pairs with ampersands (<code>&</code>), and separates keys from values with equal signs (<code>=</code>). The data is then URL-encoded, which converts special characters into a percent sign (<code>%</code>) followed by two hexadecimal digits. For example, a space is encoded as <code>%20</code>, <code>&</code> as <code>%26</code>, and <code>=</code> as <code>%3D</code>.</p></li> <li><p>Example: <code>name=John Doe\&age=25</code> is encoded as <code>name=John%20Doe\&age=25</code>.</p></li></ul></li></ul></td></tr></tbody></table>
         </Accordion>

         <Accordion title="Configure input and output parameters" defaultOpen>
           <table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "21.908127%" }} /><col style={{ width: "78.091873%" }} /></colgroup><tbody><tr><td rowSpan={5} style={{ verticalAlign: "top" }}><p><strong>Configure Input Parameters</strong></p></td><td style={{ verticalAlign: "top" }}><p>Click <strong>Add Input Parameter</strong> to configure parameters.</p></td></tr><tr><td style={{ verticalAlign: "top" }}><p><strong>Parameter Name</strong>: Use a descriptive name to help the model understand what the parameter represents. For example, <code>city</code>.</p></td></tr><tr><td style={{ verticalAlign: "top" }}><p><strong>Parameter Description</strong>: A concise and accurate description of the function of the input parameter. This helps the model better understand how to retrieve the parameter value. For example, for a parameter named <code>date</code>, you can describe it as a date and also specify its format, such as <code>yyyy-MM-dd</code>.</p></td></tr><tr><td style={{ verticalAlign: "top" }}><p><strong>Type</strong>: The data type of the parameter.</p> <div><p>Sub-properties of an <code>Object</code> type cannot be empty. Click the <Image src="https://help-static-aliyun-doc.aliyuncs.com/assets/img/en-US/6153267371/p905454.png" alt="image" className="inline" noZoom /> icon at the end of the object's row to add a sub-property.</p></div></td></tr><tr><td style={{ verticalAlign: "top" }}><p><strong>Passing Method</strong>: Defines how the parameter value is passed. This setting is critical for correct operation.</p> <ul><li><p><strong>LLM Recognition</strong>: The model extracts the parameter value from the user's input.</p></li> <li><p><strong>Business Pass-through</strong>: The system passes the parameter value directly from an external source without processing or modification.</p> <p>When you call an application by using the DashScope SDK or an HTTP API, the system passes input parameters of the <code>business pass-through</code> type to the application by using <code>biz\_params</code> and <code>user\_defined\_params</code>. For more information, see <a href="/help/en/model-studio/pass-through-of-application-parameters">Pass parameters to an application</a>.</p></li></ul></td></tr><tr><td style={{ verticalAlign: "top" }}><p><strong>Configure Output Parameters</strong></p></td><td style={{ verticalAlign: "top" }}><p>Click <strong>Add Output Parameters</strong> and configure the parameters. All parameters are <strong>required</strong>.</p> <p>The model uses the output parameter definitions to filter and restructure the API response based on the user's query, and then returns the final answer.</p> <p>Like input parameters, output parameters must be described concisely and accurately, with minimal nesting.</p> <div><p>Both GET and POST request methods support the <code>Object</code> type for parameters. However, sub-properties of an <code>Object</code> type cannot be empty. Click the <Image src="https://help-static-aliyun-doc.aliyuncs.com/assets/img/en-US/6153267371/p905454.png" alt="image" className="inline" noZoom /> icon at the end of the object's row to add a sub-property.</p></div></td></tr></tbody></table>
         </Accordion>

         <Accordion title="Advanced configuration (Optional)">
           <table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "22.452504%" }} /><col style={{ width: "77.547496%" }} /></colgroup><tbody><tr><td rowSpan={2}><p><strong>Advanced Configuration</strong></p></td><td><p>Provide call examples to help the model avoid missed or incorrect tool calls.</p> <p>If input parameters are complex and the model might construct them incorrectly, providing examples improves the call accuracy.</p></td></tr><tr><td><p><strong>Value</strong>: Specifies the invocation parameters that you expect the model to generate from a user's query. For example, for the user input "What is the weather in Hangzhou tomorrow?", the expected parameters are <code>\{"city": "Hangzhou", "date": "2025-04-25"}</code>.</p></td></tr></tbody></table>
         </Accordion>
       </Accordion>
    2. After completing the configuration, click <strong>Save Draft</strong>.
    3. Debug the tool online to verify that the API is callable.

       <table style={{ display: "table", tableLayout: "fixed", width: "100%" }}>
         <colgroup>
           <col style={{ width: "100%" }} />
         </colgroup>

         <tbody>
           <tr>
             <td>
               Click <strong>Test Tool</strong>. If you enabled authentication, enter the authentication information and input parameter values. Then, click <strong>Start Running</strong>.

               > If the run fails, adjust the configuration based on the error message in the <strong>Run Result</strong> section and test again until the run succeeds.

               You can enter input parameter values manually or as code. For complex parameters, use <strong>Code Editing</strong>. In the code editor, you can submit the complete JSON-formatted input parameters and their corresponding values.
             </td>
           </tr>
         </tbody>
       </table>
    4. After the test passes, click <strong>Publish</strong>. Applications can only call tools that are <strong>Published</strong>.
  </Tab>
</Tabs>

## Use a plugin <span id="dc72f6c2b41we" /> <span id="7b85452289j7t" />

<Tabs>
  <Tab title="Console">
    - <strong>Method 1</strong>: Publish the plugin as an MCP service, and then add the service to an agent application.

      <strong>Step 1: Publish the plugin as an MCP service</strong>

      1. On the <strong>Plugins</strong> page, hover over the target plugin card and click <strong>Publish as MCP Service</strong>.

         > If the plugin has already been converted to an MCP service, the button changes to <strong>View MCP Service</strong>. Click it to go to the MCP Management page and view the service details.
      2. After successful publication, you can view the details of the MCP service on the <strong>MCP Management</strong> page, including the service name, description, and ID.

      <strong>Step 2: Add the MCP service to an agent application</strong>

      1. Go to the orchestration canvas of the <strong>Agent Application</strong> application. In the <strong>MCP</strong> block, click <strong>+</strong>.
      2. In the <strong>Select MCP Service</strong> panel, switch to the <strong>Custom MCPS</strong> tab, find the MCP service converted from the plugin, and click <strong>Add All</strong> to add it to the application.

         > You can also click <strong>Convert from Plugin to MCP</strong> to directly publish a plugin that has not yet been converted.
      3. Test whether the plugin works as expected.

         - No authentication: Chat with the model in the input box to test the plugin's functionality.
         - `user-level authentication` or `service-level authentication`: Before you start a conversation, click <Image src="https://help-static-aliyun-doc.aliyuncs.com/assets/img/en-US/6153267371/p905403.png" alt="image" className="inline" noZoom /> to configure the authentication token. You only need to configure the token once per session on this page.
         - If the <strong>Passing Method</strong> for a tool's input parameter is set to <strong>Business Pass-through</strong>, you must click <Image src="https://help-static-aliyun-doc.aliyuncs.com/assets/img/en-US/6153267371/p905403.png" alt="image" className="inline" noZoom width={30} /> to configure the variable value before you start a conversation. You only need to enter the value once per session on this page.
      4. After completing the test, <strong>Publish</strong> the application.
    - <strong>Method 2</strong>: On the [<strong>Application Management</strong>](https://modelstudio.console.alibabacloud.com/?tab=app#/app-center) page, go to the orchestration canvas for your <strong>Agent Application</strong> application, add the MCP service from the <strong>MCP</strong> block, test its functionality, and then <strong>Publish</strong> the application.
  </Tab>

  <Tab title="API">
    <strong>Get the tool ID</strong>

    The tool ID identifies a specific tool. When you call a tool via an API, you must pass the correct tool ID to ensure the system correctly identifies the request.

    1. In the <strong>Plugins</strong> list, find the plugin that contains the tool and click <strong>View Details</strong>.
    2. Hover the pointer over the <Image src="https://help-static-aliyun-doc.aliyuncs.com/assets/img/en-US/6153267371/p902180.png" alt="image" className="inline" noZoom /> icon next to the tool name.
    3. Click the <Image src="https://help-static-aliyun-doc.aliyuncs.com/assets/img/en-US/6153267371/p902183.png" alt="image" className="inline" noZoom /> icon to copy the tool ID.

    - When you call an application by using an API, if the application's plugin uses `business pass-through` parameters or requires <strong>User-level Authentication</strong>, you must use the `biz_params` parameter to pass the authentication information or pass-through parameter information. For more information, see [DashScope API Reference for Workflows and Legacy Agent Applications](/help/en/model-studio/agent-and-workflow-application-api-reference).
  </Tab>
</Tabs>

## Manage plugins and tools <span id="bb1d6f02f1sax" /> <span id="abe0ff5b84pkm" />

<Accordion title="Delete a plugin">
  <Tip>
    Deleting a plugin also deletes all its tools, causing any applications that call the plugin to fail. This action is irreversible.
  </Tip>

  In the <strong>Plugins</strong> list, find the target plugin and click <strong>...</strong> > <strong>Delete</strong>.
</Accordion>

<Accordion title="Edit a plugin">
  1. In the <strong>Plugins</strong> list, find the target plugin and click <strong>View Details</strong>.
  2. In the upper-right corner, click <strong>Modify Plug-in</strong>, modify the plugin information, and save the changes.

     Changes take effect immediately. If you modify the plugin URL, headers, or authentication information, tool calls might fail. You must test and publish the tools again.
</Accordion>

<Accordion title="Edit a tool">
  After you modify a tool, you must test and publish it again for the changes to take effect.

  1. In the <strong>Plugins</strong> list, find the plugin that contains the tool and click <strong>View Details</strong>.
  2. In the row that contains the tool, click <strong>Modify</strong>, modify the tool information, and then click <strong>Save Draft</strong>.
  3. Click <strong>Test Tool</strong> to debug the tool online.
  4. After the run succeeds, click <strong>Publish</strong>.
</Accordion>

<Accordion title="Delete a tool">
  <Tip>
    Deleting a tool causes any applications that call it to fail. This action is irreversible.
  </Tip>

  1. In the <strong>Plugins</strong> list, find the plugin that contains the tool and click <strong>View Details</strong>.
  2. In the row that contains the tool, click <strong>Delete</strong>.
</Accordion>

## Error codes <span id="0d7f0f3a9302i" /> <span id="539e0e09684pk" />

The following table describes common error messages that can occur when you publish a tool.

<table style={{ display: "table", tableLayout: "fixed", width: "100%" }}><colgroup><col style={{ width: "20.43%" }} /><col style={{ width: "23.48%" }} /><col style={{ width: "56.09%" }} /></colgroup><thead><tr><th><p><strong>Error code</strong></p></th><th><p><strong>Error message</strong></p></th><th><p><strong>Description</strong></p></th></tr></thead><tbody><tr><td style={{ verticalAlign: "top" }}><p><strong>130040</strong></p></td><td style={{ verticalAlign: "top" }}><p>The parameter description for xx is missing.</p></td><td style={{ verticalAlign: "top" }}><p>Cause: The description for the <code>xx</code> parameter is missing.</p> <p>Solution: Add the parameter description and publish the tool again.</p></td></tr><tr><td style={{ verticalAlign: "top" }}><p><strong>130022</strong></p></td><td style={{ verticalAlign: "top" }}><p>Failed to save the tool information. Check whether the sample parameters are correct.</p></td><td style={{ verticalAlign: "top" }}><p>Possible cause 1: An input or output parameter of the <code>Object</code> type has an empty sub-property.</p> <p>Solution: Click the <Image src="https://help-static-aliyun-doc.aliyuncs.com/assets/img/en-US/6153267371/p905454.png" alt="image" className="inline" noZoom /> icon at the end of the object's row to add a sub-property.</p> <p>Possible cause 2: The request method is GET, but an input parameter is of the <code>Object</code> type.</p> <p>Solution: GET requests do not support the <code>Object</code> type for input parameters. Select a different data type.</p></td></tr></tbody></table>