Skip to main content
Custom tools let you add capabilities beyond the built-in MeshAgent toolkits. A Toolkit groups related Tools together so they can be registered in a room and used by people or agents. In this guide you’ll:
  • Write custom tools
  • Create a toolkit to group your related tools
  • Register a toolkit in a room
  • Invoke tools using the MeshAgent CLI, MeshAgent Studio UI, and code
  • Give a process agent access to the toolkit
  • Let a process agent dynamically discover annotated room toolkits

Creating a custom toolkit

Step 1: Writing custom tools

Let’s create a simple toolkit with two tools, one that can add two numbers, and one that can subtract two numbers. First write the logic for the add and subtract tools. Then bundle them into a Toolkit that a SingleRoomAgent can expose for room calls. Save this example as tools-adder.py:
import asyncio
from meshagent.api import TOOL_SEARCH_ANNOTATION
from meshagent.agents import SingleRoomAgent
from meshagent.tools import FunctionTool, ToolContext, Toolkit
from meshagent.otel import otel_config

otel_config(service_name="math_tools")


class Add(FunctionTool):
    def __init__(self):
        super().__init__(
            name="add",
            title="adding tool",
            description="a tool that adds two numbers",
            input_schema={
                "type": "object",
                "additionalProperties": False,
                "required": ["a", "b"],
                "properties": {
                    "a": {"type": "integer"},
                    "b": {"type": "integer"},
                },
            },
        )

    async def execute(self, context: ToolContext, *, a: int, b: int):
        result = {"result": a + b}
        print(result)
        return result


class Subtract(FunctionTool):
    def __init__(self):
        super().__init__(
            name="subtract",
            title="subtracting tool",
            description="a tool that subtracts two numbers",
            input_schema={
                "type": "object",
                "additionalProperties": False,
                "required": ["a", "b"],
                "properties": {
                    "a": {"type": "integer"},
                    "b": {"type": "integer"},
                },
            },
        )

    async def execute(self, context: ToolContext, *, a: int, b: int):
        result = {"result": a - b}
        print(result)
        return result


class MathToolkit(Toolkit):
    def __init__(self):
        super().__init__(
            name="math-toolkit",
            title="math-toolkit",
            description="a toolkit for adding and subtracting numbers",
            annotations={TOOL_SEARCH_ANNOTATION: "true"},
            tools=[Add(), Subtract()],
        )


class MathAgent(SingleRoomAgent):
    async def get_exposed_toolkits(self) -> list[Toolkit]:
        return [MathToolkit()]


async def main() -> None:
    agent = MathAgent(title="math-agent")
    await agent.run()


if __name__ == "__main__":
    asyncio.run(main())

Step 2: Register the toolkit in a room

Create the room and start the toolkit locally. This guide uses gettingstarted, the same room created in the CLI quickstart, so you can reuse a room you already own.
meshagent setup # authenticate to MeshAgent
meshagent rooms create gettingstarted --if-not-exists
meshagent room connect --room=gettingstarted --identity=math-tools -- python3 tools-adder.py
This command runs the local Python agent and registers the math-toolkit toolkit into gettingstarted. The toolkit is available while that terminal session is still running. SingleRoomAgent.run() creates the room connection, starts the agent, and unregisters the exposed toolkit when the process stops.

Step 3: Invoke and inspect the toolkit

Invoking tools programmatically

While the agent is running, invoke the toolkit from another terminal or from code. Run the Python and .NET examples through meshagent room connect so MeshAgent injects the room connection environment. The Python tab can be saved as tools-calling.py and run directly. For .NET, add the C# tab to a .NET project that references Meshagent.Api, then run the project through meshagent room connect.
meshagent room agents invoke-tool \
  --room=gettingstarted \
  --toolkit=math-toolkit \
  --tool=add \
  --arguments='{"a": 5, "b":7}'
Invoking the tools using the RoomClient will give you the following result:
The result from adding the numbers is: Json: json={"result": 3}
The result from subtracting the numbers is: Json: json={"result": -1}

Inspecting available toolkits

You can also verify which toolkits are registered in the room. Run the Python and .NET discovery examples through the same meshagent room connect pattern.
meshagent room agents list-toolkits --room=gettingstarted
The output should include math-toolkit, its add and subtract tools, and this annotation:
"annotations": {
  "meshagent.tool_search": "true"
}

Invoking tools in MeshAgent Studio

  1. Go to studio.meshagent.com and login
  2. From the Sessions tab enter gettingstarted
  3. From the menu in the upper left, click Toolkits
  4. Find the tool you want to run and click Invoke
  5. Enter any required values and click Ok
The tool will execute and display the result in the Studio UI. From the “Developer Console” on the bottom half of the screen you’ll be able to see logs, traces, and metrics from tool calls as they happen in the room. Because this example is running locally through meshagent room connect, the toolkit is only available while that terminal session is still running.

Step 4: Give a process agent access to the toolkit

There are two common ways to make a room toolkit available to a process agent.

Option A: Require the toolkit by name

Use --require-toolkit when the agent should always have access to a specific room toolkit. This is the simpler path when you already know which toolkit the agent should use. Leave the terminal running meshagent room connect --room=gettingstarted --identity=math-tools -- python3 tools-adder.py; that process is hosting math-toolkit in the room. In a second terminal, start a chat agent that requires math-toolkit:
bash
meshagent process join \
  --room gettingstarted \
  --agent-name math-helper \
  --channel chat \
  --model gpt-5.5 \
  --require-toolkit math-toolkit
Open the Studio link printed by the command and ask the agent an arithmetic question, such as:
Use the available math tool to add 389 and 457.
If you deploy the process agent with the same required toolkit, the agent will request that toolkit by name whenever it handles a turn in the room.

Option B: Let the agent discover annotated room toolkits

Use --tool-search room when the agent should be able to dynamically discover annotated toolkits that are already present in the room. This is useful when you do not want to configure every toolkit directly on the agent. This option uses OpenAI Responses tool search behind the scenes, so it only applies to OpenAI-backed process-agent models. The sample toolkit sets the meshagent.tool_search annotation. Start a chat agent with room tool search enabled:
bash
meshagent process join \
  --room gettingstarted \
  --agent-name math-helper \
  --channel chat \
  --model gpt-5.5 \
  --tool-search room \
  --log-llm-requests
Open the Studio link printed by the command and ask the agent an arithmetic question:
Use the available math tool to add 389 and 457.
--tool-search room adds annotated room toolkits to the model’s tool-search candidate set. In the process-agent logs, math-toolkit should appear as a deferred toolkit available to the model.

Next Steps

If you want the toolkit to stay available after your local terminal session ends, package and deploy it as a MeshAgent service.