banner
Lumos

Hi,Lumos

念念不忘,终有回响

MCP, FunctionCall Popular Science

Tip

Tips
The following will collectively refer to MCP (mainly referring to the server side) and FunctionCall (mainly referring to the function calls of the OpenAI chat specification) as "plugins" for quick understanding.

  • The model itself does not have the capability to call functions or the MCP Server.
  • Both inform the remote model of the additional capabilities that the client possesses (such as weather plugins, database plugins, drawing plugins), and the model determines based on the current context (the current statement) whether certain plugins should be executed, what the parameters are, and returns a special response to send the results back to the client.
  • The model itself only returns various "texts."
  • When the client (such as CherryStudio, NextChat, openwebui) observes that the model has returned a certain special response text, the client executes the plugins indicated in the model's response text; of course, the client can completely ignore the model's special response.

A simple process is as follows
image.png

FunctionCall#

Taking the local weather as an example

The request structure is as follows:
By informing the model through functions or tools (the latest alias for functions), the current client has the capability to obtain weather information.

{
    "messages": [
        {
            "role": "system",
            "content": "You are a helpful assistant."
        },
        {
            "role": "user",
            "content": "What is the weather like in Shanghai today? What is the humidity?"
        }
    ],
    "functions": [
        {
            "name": "get_localtion_weather",
            "description": "get_localtion_weather, obtain the current weather conditions of a specific location",
            "parameters": {
                "type": "object",
                "properties": {
                    "localtion": {
                        "type": "string",
                        "description": "localtion, location"
                    },
                    "need_humidity":{
                        "type":"boolean",
                        "description":"Whether to return humidity, default is false"
                    }
                },
                "required": [
                    "localtion"
                ]
            }
        }
    ],
    "function_call": "auto",
    "temperature": 0.5,
    "stream":false,
    "model": "gpt-4o"
}
curl --location 'https://api.xxxxx.com/v1/chat/completions' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer sk-xxxxx' \
--data '{
    "messages": [
        {
            "role": "system",
            "content": "You are a helpful assistant."
        },
        {
            "role": "user",
            "content": "What is the weather like in Shanghai today? What is the humidity?"
        }
    ],
    "functions": [
        {
            "name": "get_localtion_weather",
            "description": "get_localtion_weather, obtain the current weather conditions of a specific location",
            "parameters": {
                "type": "object",
                "properties": {
                    "localtion": {
                        "type": "string",
                        "description": "localtion, location"
                    },
                    "need_humidity":{
                        "type":"boolean",
                        "description":"Whether to return humidity, default is false"
                    }
                },
                "required": [
                    "localtion"
                ]
            }
        }
    ],
    "function_call": "auto",
    "temperature": 0.5,
    "stream":false,
    "model": "gpt-4o"
}'

The response structure is as follows:
image.png

The client executes the local get_localtion_weather function.

The overall process is illustrated in the diagram (the diagram is extracted from OpenAI's documentation, translation from immersive translation).
image.png

MCP#

Simply put: functionCall is something everyone writes for themselves, there is no unified convention, while MCP is a gentleman's agreement. The mcpServer (weather query plugin) is developed following the MCP protocol and is called by the mcpClient (Cursor). What originally required writing functions by oneself has now become calling someone else's library.

image.png

The focus of MCP is how the MCP client (Cherry Studio) discovers the MCP server ("plugin"), understands the capabilities of the "plugin," calls the "plugin," and obtains the response results from the "plugin."

As for:

  • Sending the currently available plugin functions to the model (described in functions (alias tools), prompt word method)
  • How the MCP client (Cherry Studio) determines whether to execute the "plugin" based on the model's response and which plugins to execute is defined by the client itself.
  • The MCP client can also define how to return the plugin execution results to the model.

The following section only describes the application domain, illustrating the dialogue process combined with MCP without detailing the "gentleman's agreement" of MCP.

Example of Cherry Studio#

The configuration of mcpServers is as follows, with only one server for obtaining HeFeng Weather.
Source: HeFeng Weather MCP Server | Glama

{
  "mcpServers": {
    "hefeng-weather": {
      "isActive": true,
      "command": "npx",
      "args": [
        "hefeng-mcp-weather@latest",
        "--apiKey=key-123132131321"
      ]
    }
  }
}

The dialogue is as follows
image.png

  1. Check the first request intercepted locally, which can be found to be described through tools, informing the model of the "plugins" available locally and their capabilities.
{
  "model": "gpt-4o",
  "messages": [
    {
      "role": "user",
      "content": "What is the weather like in Shanghai today?"
    }
  ],
  "temperature": 0.7,
  "max_tokens": 2000,
  "stream": true,
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "fd71edc4f65924613b9fd8330e78eb243",
        "description": "Obtain weather forecasts within China",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "Comma-separated latitude and longitude information (e.g., 116.40,39.90)"
            },
            "days": {
              "type": "string",
              "enum": [
                "now",
                "24h",
                "72h",
                "168h",
                "3d",
                "7d",
                "10d",
                "15d",
                "30d"
              ],
              "description": "Forecast days, now for real-time weather, 24h for 24-hour forecast, 72h for 72-hour forecast, 168h for 168-hour forecast, 3d for 3-day forecast, and so on."
            }
          }
        }
      }
    }
  ]
}
  1. Check the first response, where the model determines whether to execute the triggered plugin call.
    The model determines that it needs to use the "weather plugin," and the model itself only makes the judgment.

image.png

  1. The MCP client (Cherry Studio) executes the "weather plugin," which can be simply seen as calling a package or API written by someone else.
  2. The execution result is returned to the model, which is then added to the dialogue context.
{
  "model": "gpt-4o",
  "messages": [
    {
      "role": "user",
      "content": "What is the weather like in Shanghai today?"
    },
    {
      "role": "assistant",
      "tool_calls": [
        {
          "id": "call_M4eYNv6oPaLunpZLe1iWdfiK",
          "function": {
            "name": "fd71edc4f65924613b9fd8330e78eb243",
            "arguments": "{\"days\":\"now\",\"location\":\"121,31\"}"
          },
          "type": "function"
        }
      ]
    },
    {
      "role": "tool",
      "content": "[{\"type\":\"text\",\"text\":\"Location: 121,31\\nObservation Time: 2025-03-27T16:51+08:00\\nWeather: Overcast\\nTemperature: 13°C\\nFeels Like: 12°C\\nWind Direction: Northeast Wind\\nWind Force: Level 1\"}]",
      "tool_call_id": "call_M4eYNv6oPaLunpZLe1iWdfiK"
    }
  ],
  "temperature": 0.7,
  "max_tokens": 2000,
  "stream": true,
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "fd71edc4f65924613b9fd8330e78eb243",
        "description": "Obtain weather forecasts within China",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "Comma-separated latitude and longitude information (e.g., 116.40,39.90)"
            },
            "days": {
              "type": "string",
              "enum": [
                "now",
                "24h",
                "72h",
                "168h",
                "3d",
                "7d",
                "10d",
                "15d",
                "30d"
              ],
              "description": "Forecast days, now for real-time weather, 24h for 24-hour forecast, 72h for 72-hour forecast, 168h for 168-hour forecast, 3d for 3-day forecast, and so on."
            }
          }
        }
      }
    }
  ]
}
  1. The model responds based on the context (the dialogue history sent).
    Here is an excerpt from one part.
    image.png

Cherry Studio determines which "plugin" functions should be executed through the functionCall method.

Custom Protocol (Using System Prompt Method)#

You are an intelligent assistant, and you have MCP functionality. MCP can be understood as a local functional plugin. When a user's statement requires calling a plugin, you should strictly return according to the following regulations:
<plug>
	<pn>Plugin Name</pn>
	<fn>Function Name (Functionality Name)</fn>
	<arg1>Parameter</arg1>
	<arg2>Parameter2<arg2>
	<arg3>Parameter3<arg3>
<plug/>.
When a local plugin is executed, the result should be returned in the following format:
<tool_res>
	<plug>
		<pn>Plugin Name</pn>
		<fn>Function Name (Functionality Name)</fn>
		<res>Execution Result<res/>
	<plug/>
<tool_res/>

Current local plugins:
1. Plugin Name: get_localtion_weather
	Description: Query weather plugin for a specific location
	 Function:
	 - query_now_weather:
	 	args:
	 		location:string, required, query location
	 		need_humidity: boolean, optional, default is false, whether to return humidity

The image shows ChatBox, and other clients will process <xx><xx/> so that it does not display.

image.png

image.png

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.