How to Implement a Plugin for MCP#

Prerequisites

This guide assumes you are familiar with the following concepts:

Overview#

Model Context Protocol (MCP) is an open protocol that standardizes how applications provide context to LLMs. MCP servers allow you to connect your assistant to external tools and services (such as web APIs, search engines, or custom data sources) without writing custom adapters for each integration.

In this guide, you will learn how to:

  • Create a simple MCP Server (in a separate Python file)

  • Connect an Agent/Flow to an MCP Server

Important

This guide will show you how to integrate with WayFlow, which supports MCP Tools. Note that the steps shown in this guide can be applied on any runtime executor that supports MCP.

Prerequisite: Setup a simple MCP Server#

First, let’s see how to create and start a simple MCP server exposing a couple of tools.

Note

You should copy the following server code and run it in a separate Python process.

from mcp.server.fastmcp import FastMCP

PAYSLIPS = [
    {
        "Amount": 7612,
        "Currency": "USD",
        "PeriodStartDate": "2025/05/15",
        "PeriodEndDate": "2025/06/15",
        "PaymentDate": "",
        "DocumentId": 2,
        "PersonId": 2,
    },
    {
        "Amount": 5000,
        "Currency": "CHF",
        "PeriodStartDate": "2024/05/01",
        "PeriodEndDate": "2024/06/01",
        "PaymentDate": "2024/05/15",
        "DocumentId": 1,
        "PersonId": 1,
    },
    {
        "Amount": 10000,
        "Currency": "EUR",
        "PeriodStartDate": "2025/06/15",
        "PeriodEndDate": "2025/10/15",
        "PaymentDate": "",
        "DocumentsId": 3,
        "PersonId": 3,
    },
]

def create_server(host: str, port: int):
    """Create and configure the MCP server"""
    server = FastMCP(
        name="Example MCP Server",
        instructions="A MCP Server.",
        host=host,
        port=port,
    )

    @server.tool(description="Return session details for the current user")
    def get_user_session():
        print("called get_user_session")
        return {
            "PersonId": "1",
            "Username": "Bob.b",
            "DisplayName": "Bob B",
        }

    @server.tool(description="Return payslip details for a given PersonId")
    def get_payslips(PersonId: int):
        return [payslip for payslip in PAYSLIPS if payslip["PersonId"] == int(PersonId)]

    return server


def start_mcp_server() -> str:
    host: str = "localhost"
    port: int = 8080
    server = create_server(host=host, port=port)
    server.run(transport="sse")

    return f"http://{host}:{port}/sse"

# mcp_server_url = start_mcp_server() # <--- Move the code above to a separate file then uncomment

This MCP server exposes two example tools: get_user_session and get_payslips. Once started, it will be available at (by default): http://localhost:8080/sse.

Note

When choosing a transport for MCP:

  • Use Stdio when launching and communicating with an MCP server as a local subprocess on the same machine as the client.

  • Use Streamable HTTP when connecting to a remote MCP server.

For more information, visit https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#stdio

Important

This guide does not aim at explaining how to make secure MCP servers, but instead mainly aims at showing how to connect to one. You should ensure that your MCP server configurations are secure, and only connect to trusted external MCP servers.

Connecting an Agent to the MCP Server#

You can now connect an agent to this running MCP server.

Add imports and configure an LLM#

Start by importing the necessary packages for this guide:


from pyagentspec.agent import Agent
from pyagentspec.flows.edges import ControlFlowEdge, DataFlowEdge
from pyagentspec.flows.flow import Flow
from pyagentspec.flows.nodes import EndNode, StartNode, ToolNode
from pyagentspec.mcp import MCPTool, SSETransport
from pyagentspec.property import StringProperty

mcp_server_url = f"http://localhost:8080/sse" # change to your own URL

Agent Spec supports several LLM API providers. Select an LLM from the options below:

from pyagentspec.llms import OciGenAiConfig
from pyagentspec.llms.ociclientconfig import OciClientConfigWithApiKey

client_config = OciClientConfigWithApiKey(
    name="Oci Client Config",
    service_endpoint="https://url-to-service-endpoint.com",
    auth_profile="DEFAULT",
    auth_file_location="~/.oci/config"
)

llm_config = OciGenAiConfig(
    name="Oci GenAI Config",
    model_id="provider.model-id",
    compartment_id="compartment-id",
    client_config=client_config,
)

Build the Agent#

Agents can use tools exposed by MCP servers using MCPTool.

mcp_client = SSETransport(name="MCP Client", url=mcp_server_url)

get_user_session_tool = MCPTool(
    client_transport=mcp_client,
    description="Return session details for the current user",
    name="get_user_session",
)
get_payslips_tool = MCPTool(
    client_transport=mcp_client,
    description="Return payslip details for a given PersonId",
    name="get_payslips",
)
agent = Agent(
    name="Agent using MCP",
    llm_config=llm_config,
    system_prompt="Use tools at your disposal to assist the user.",
    tools=[get_user_session_tool, get_payslips_tool]
)

Specify the transport to use to handle the connection to the server as well as the name of the specific tool you want to use. Additionally, you can override the tool description (exposed by the MCP server) by specifying the description parameter.

Agent Serialization#

You can export the agent configuration using the AgentSpecSerializer.

from pyagentspec.serialization import AgentSpecSerializer

serialized_assistant = AgentSpecSerializer().to_json(agent)

Here is what the Agent Spec representation will look like ↓

Click here to see the assistant configuration.
{
    "component_type": "Agent",
    "id": "a98dfe0f-2f36-4c4c-937e-ab4394ef7863",
    "name": "Agent using MCP",
    "description": null,
    "metadata": {},
    "inputs": [],
    "outputs": [],
    "llm_config": {
        "component_type": "VllmConfig",
        "id": "2242f59e-d803-4413-8473-c807bc5cbf19",
        "name": "llm",
        "description": null,
        "metadata": {},
        "default_generation_parameters": null,
        "url": "url",
        "model_id": "model_id"
    },
    "system_prompt": "Use tools at your disposal to assist the user.",
    "tools": [
        {
            "component_type": "MCPTool",
            "id": "d0b7948c-74e1-4789-a89a-b7a8a11a1651",
            "name": "get_user_session",
            "description": "Return session details for the current user",
            "metadata": {},
            "inputs": [],
            "outputs": [],
            "client_transport": {
                "$component_ref": "d083a903-d504-41d4-84db-aabf19344c5c"
            }
        },
        {
            "component_type": "MCPTool",
            "id": "2f03453b-def7-4515-b02e-b780c92c81ca",
            "name": "get_payslips",
            "description": "Return payslip details for a given PersonId",
            "metadata": {},
            "inputs": [],
            "outputs": [],
            "client_transport": {
                "$component_ref": "d083a903-d504-41d4-84db-aabf19344c5c"
            }
        }
    ],
    "$referenced_components": {
        "d083a903-d504-41d4-84db-aabf19344c5c": {
            "component_type": "SSETransport",
            "id": "d083a903-d504-41d4-84db-aabf19344c5c",
            "name": "MCP Client",
            "description": null,
            "metadata": {},
            "session_parameters": {
                "read_timeout_seconds": 60
            },
            "url": "http://localhost:8080/sse",
            "headers": null
        }
    },
    "agentspec_version": "25.4.1"
}

Connecting a Flow to the MCP Server#

You can also use MCP tools in a Flow by using the MCPTool in a ToolNode.

Build the Flow#

Create the flow using the MCP tool:


start_node = StartNode(name="start")
user_info_property = StringProperty(title="user_info")
get_user_session_tool = MCPTool(
    client_transport=mcp_client,
    name="get_user_session",
    description="Return session details for the current user",
    outputs=[user_info_property]
)
mcptool_node = ToolNode(
    name="mcp_tool",
    tool=get_user_session_tool,
)
end_node = EndNode(name="end", outputs=[user_info_property])

flow = Flow(
    name="Flow using MCP",
    start_node=start_node,
    nodes=[start_node, mcptool_node, end_node],
    control_flow_connections=[
        ControlFlowEdge(
            name="start->mcptool",
            from_node=start_node,
            to_node=mcptool_node
        ),
        ControlFlowEdge(
            name="mcptool->end",
            from_node=mcptool_node,
            to_node=end_node
        ),
    ],
    data_flow_connections=[
        DataFlowEdge(
            name="user_info",
            source_node=mcptool_node,
            source_output="user_info",
            destination_node=end_node,
            destination_input="user_info",
        )
    ]
)

Similarly to when equipping Agents with MCP Tools, you should specify the client transport as with the MCP ToolBox, as well as the name of the specific tool you want to use.

Flow Serialization#

You can export the flow configuration using the AgentSpecSerializer.

from pyagentspec.serialization import AgentSpecSerializer

serialized_assistant = AgentSpecSerializer().to_json(flow)

Here is what the Agent Spec representation will look like ↓

Click here to see the assistant configuration.
{
    "component_type": "Flow",
    "id": "2849ac60-7154-48a8-a4ef-433ffe85b5ef",
    "name": "Flow using MCP",
    "description": null,
    "metadata": {},
    "inputs": [],
    "outputs": [
        {
            "title": "user_info",
            "type": "string"
        }
    ],
    "start_node": {
        "$component_ref": "1949f7b0-782e-4856-bfe9-cc58964c175a"
    },
    "nodes": [
        {
            "$component_ref": "1949f7b0-782e-4856-bfe9-cc58964c175a"
        },
        {
            "$component_ref": "c4be5127-81a6-4627-8525-bac37214d547"
        },
        {
            "$component_ref": "ab20a178-5658-4c92-bd9a-ce87dd9a1ecd"
        }
    ],
    "control_flow_connections": [
        {
            "component_type": "ControlFlowEdge",
            "id": "d4c33b22-4de1-4e36-bc7f-6e48a7dccfb0",
            "name": "start->mcptool",
            "description": null,
            "metadata": {},
            "from_node": {
                "$component_ref": "1949f7b0-782e-4856-bfe9-cc58964c175a"
            },
            "from_branch": null,
            "to_node": {
                "$component_ref": "c4be5127-81a6-4627-8525-bac37214d547"
            }
        },
        {
            "component_type": "ControlFlowEdge",
            "id": "c6fde850-2bff-45f4-b44b-6cf1c85805c1",
            "name": "mcptool->end",
            "description": null,
            "metadata": {},
            "from_node": {
                "$component_ref": "c4be5127-81a6-4627-8525-bac37214d547"
            },
            "from_branch": null,
            "to_node": {
                "$component_ref": "ab20a178-5658-4c92-bd9a-ce87dd9a1ecd"
            }
        }
    ],
    "data_flow_connections": [
        {
            "component_type": "DataFlowEdge",
            "id": "62ee2e58-19e1-403d-b6ca-eeabb753c20a",
            "name": "user_info",
            "description": null,
            "metadata": {},
            "source_node": {
                "$component_ref": "c4be5127-81a6-4627-8525-bac37214d547"
            },
            "source_output": "user_info",
            "destination_node": {
                "$component_ref": "ab20a178-5658-4c92-bd9a-ce87dd9a1ecd"
            },
            "destination_input": "user_info"
        }
    ],
    "$referenced_components": {
        "c4be5127-81a6-4627-8525-bac37214d547": {
            "component_type": "ToolNode",
            "id": "c4be5127-81a6-4627-8525-bac37214d547",
            "name": "mcp_tool",
            "description": null,
            "metadata": {},
            "inputs": [],
            "outputs": [
                {
                    "title": "user_info",
                    "type": "string"
                }
            ],
            "branches": [
                "next"
            ],
            "tool": {
                "component_type": "MCPTool",
                "id": "f1730e08-491b-4348-96e6-8fb18b0db618",
                "name": "get_user_session",
                "description": "Return session details for the current user",
                "metadata": {},
                "inputs": [],
                "outputs": [
                    {
                        "title": "user_info",
                        "type": "string"
                    }
                ],
                "client_transport": {
                    "component_type": "SSETransport",
                    "id": "96cda25c-5b3e-43cf-97bd-2d1feca83473",
                    "name": "MCP Client",
                    "description": null,
                    "metadata": {},
                    "session_parameters": {
                        "read_timeout_seconds": 60
                    },
                    "url": "http://localhost:8080/sse",
                    "headers": null
                }
            }
        },
        "ab20a178-5658-4c92-bd9a-ce87dd9a1ecd": {
            "component_type": "EndNode",
            "id": "ab20a178-5658-4c92-bd9a-ce87dd9a1ecd",
            "name": "end",
            "description": null,
            "metadata": {},
            "inputs": [
                {
                    "title": "user_info",
                    "type": "string"
                }
            ],
            "outputs": [
                {
                    "title": "user_info",
                    "type": "string"
                }
            ],
            "branches": [],
            "branch_name": "next"
        },
        "1949f7b0-782e-4856-bfe9-cc58964c175a": {
            "component_type": "StartNode",
            "id": "1949f7b0-782e-4856-bfe9-cc58964c175a",
            "name": "start",
            "description": null,
            "metadata": {},
            "inputs": [],
            "outputs": [],
            "branches": [
                "next"
            ]
        }
    },
    "agentspec_version": "25.4.1"
}

Next steps#

In this guide, you learned how to connect MCP Tools to Agent Spec Flows and Agents.

Having learned how to configure agent instructions, you may now proceed to: