MCP Tool Development Guide
This article describes how to develop MCP tools, covering the complete development workflow from defining functions and writing tool descriptions to registering and publishing tools.
1. Development Workflow
DolphinDB MCP tool development follows this workflow:
- Define functions: Implement the core business logic of the tool.
- Write the description: Provide detailed instructions for the large language model on how to call the tool.
- Register the tool: Use
addMCPToolorupdateMCPToolto register the tool with the MCP Server. - Publish the tool: Use
publishMCPToolsto publish the tool so that clients can call it.
2. Define Functions
2.1 Supported Parameter Types
The large language model passes parameters to the MCP Server in JSON format. The following types are currently supported:
| DolphinDB Type | JSON Type | Description |
|---|---|---|
| STRING | string | String |
| TEMPORAL (DATE, etc.) | string | Temporal type; pass it as a string and then convert it. |
| DOUBLE | number | Numeric type |
| BOOL | boolean | Boolean type |
| STRING[] | array\ | String array |
| TEMPORAL[] | array\ | Temporal array |
| DOUBLE[] | array\ | Numeric array |
| BOOL[] | array\ | Boolean array |
You cannot pass a dictionary directly as a function parameter. Instead, pass
it as a JSON string, and then use parseExpr().eval() in the
function to parse it into a dictionary object.
2.2 Parameter Design
- Intuitiveness: Parameter names must have clear natural-language meanings. For example, use stockCodes instead of codes.
- Explicitness: If a parameter accepts only a limited set of values, list all possible values in the description.
- Session management: If you need to save intermediate results from a tool call, include the sessionId and resultTableName parameters for shared in-memory table management.
2.3 Return Value Design
- Return size: We recommend using
toStdJson(t[0:min(10, t.size())])to return the first 10 rows. - Status information: Return key information such as the operation result, shared table name, and data volume.
- Conciseness: Avoid returning excessive data to prevent the context from becoming too long.
2.4 Sample Function Code
def get_stock_basic_info(stockCodes, resultTableName, sessionId){
// 1. Load data and filter stock information
t = select * from loadTable("dfs://basic_factor", "stock_basic")
where ts_code in stockCodes or symbol in stockCodes
// 2. Session management
if (trim(sessionId) != "") {
if (trim(resultTableName) != "") {
resultName = resultTableName + "_" + sessionId
share(t, resultName)
return "Query succeeded:shared table name " + resultName +
"\nfirst 10 rows:\n" + toStdJson(t[0:min(10, t.size())])
}
}
// 3. Return results
return "Query succeeded:first 10 rows:\n" + toStdJson(t[0:min(10, t.size())])
}
3. Write Tool Descriptions
Tool descriptions are essential for helping the large language model understand and correctly call MCP tools. They must include the following sections.
3.1 Description Template
description_xxx = '
[Overview] - A one-sentence description of the tool’s core functionality.
Parameters:
- parameter1: Type, description
- parameter2: Type, description (if the parameter accepts only specific values, list all possible values)
- sessionId: STRING. A unique identifier for the current session, used to generate a unique shared table name. If empty, the in-memory table will not be shared and the query result will be returned directly.
- resultTableName: STRING. The name of the shared in-memory table used for subsequent analysis. It is recommended to use a meaningful name such as "xxx".
Returns:
- Operation result information, including the shared table name (if any) and sample data from the first 10 rows.
Example Code:
// Example 1 - Full usage with intermediate table management
functionName([parameter values], "table_name", "session123")
// Example 2 - Simplified usage without shared in-memory tables
functionName([parameter values], "", "")
'
3.2 Key Points for Writing Descriptions
Feature overview
- State the tool's purpose directly in one sentence.
- Example: "Load basic information for specified stock codes from the DolphinDB stock_basic table."
Parameter description
- Each parameter must include a name, type, and detailed description.
- Use STRING[], DATE[], and similar notation for list types.
- For parameters that accept only a limited set of values, explicitly list all possible values.
- Example:
- stockCodes: STRING[], stock code list - dates: DATE[], date list
Return description
- Clearly describe the format of the returned content and the information it contains.
- Example: "Operation result information, including the shared table name (if any) and sample data from the first 10 rows."
Sample code
- Provide at least two examples that cover the main use cases.
- Use comments to describe the scenario for each example.
3.3 Complete Example
description_select_stocks_by_factors = '
Select stocks from the DolphinDB table day_factor based on user-specified factors and filtering conditions. The filtering is performed using data from the most recent trading day.
Parameters:
- factors: STRING[]. A list of factors specified by the user. Supported factors include existing indicators such as "pe" and "pb".
- conditions: STRING[]. A list of filtering conditions, where each condition is a string expression (e.g., "pe < 15", "pb > 1").
- resultTableName: STRING. The name of the shared in-memory table for subsequent analysis. It is recommended to use a meaningful name such as "selected_stocks".
- sessionId: STRING. A unique identifier for the current session, used to generate a unique shared table name. If empty, the in-memory table will not be shared and the query result will be returned directly.
Returns:
- Operation result information, including the shared table name (if any) and sample data from the first 10 rows.
Examples:
// Select stocks by the "pe" and "pb" indicators, using the filter conditions "pe < 15" and "pb > 1"
select_stocks_by_factors(["pe", "pb"], ["pe < 15", "pb > 1"], "selected_stocks", "session123")
// Simplified call without sharing the in-memory table
select_stocks_by_factors(["rev_yoy", "profit_yoy"], ["rev_yoy > 10", "profit_yoy > 5"], "", "")
'
4. Register and Publish Tools
After you develop an MCP tool, you must register it before publishing it for clients to use.
4.1 Register Tools
Use addMCPTool or updateMCPTool to register a function as an MCP tool.
We recommend using the following template to register tools:
if (`tool_name in (exec name from listMCPTools())) {
updateMCPTool(`tool_name, tool_function,
`param1`param2`param3,
["TYPE1", "TYPE2", "TYPE3"],
description_tool_name)
} else {
addMCPTool(`tool_name, tool_function,
`param1`param2`param3,
["TYPE1", "TYPE2", "TYPE3"],
description_tool_name)
}
To update an existing MCP tool, use updateMCPTool. Its parameters are similar to those of addMCPTool.
4.2 Publish Tools
Use publishMCPTools() to publish registered tools so that clients can call them.
After publishing, you can select and enable the tools from the tool list in clients.
publishMCPTools(`tool_name)
