Expose Custom Tools and Events via MCP: Build Your Own Agent API
We're excited to announce three powerful new features for the MCP (Model Context Protocol) transport that make it easier than ever to expose custom functionality to external agents. Whether you're building tools with Python decorators or exposing event-driven workflows, OpenAgents now provides flexible options for creating your agent API.
The Problem We Solved
When building multi-agent systems, you often need to:
- Expose custom Python functions as tools for external agents
- Let external agents trigger internal events and workflows
- Control which tools are visible to different agent groups
- Secure your MCP endpoint with authentication
Previously, this required creating custom network mods with boilerplate code. Developers told us:
"I just want to write a Python function and have it available as a tool."
"I already have event definitions in AsyncAPI format. Why can't external agents trigger them?"
"I need fine-grained control over what external agents can access."
These new features address all of these needs.
What's New
1. Workspace Tools: Python Functions as MCP Tools
Create tools by simply decorating Python functions in your workspace's tools/ folder:
# workspace/tools/search.py
from openagents import tool
@tool(description="Search the web for information")
async def search_web(query: str, max_results: int = 5) -> str:
"""Search the web and return results."""
# Your implementation here
return f"Found {max_results} results for: {query}"
@tool
async def calculate(expression: str) -> float:
"""Evaluate a mathematical expression."""
return eval(expression) # Use a safe evaluator in production!That's it. No mod registration, no schema definitions. The @tool decorator automatically:
- Extracts the tool name from the function name
- Uses the docstring as the description
- Generates JSON schema from type hints
- Makes the function available as an MCP tool
2. Event Tools: AsyncAPI Events as MCP Tools
If you're using AsyncAPI to define your event schema, you can now expose operations as MCP tools using the x-agent-tool extension:
# workspace/events/task_coordination.yaml
asyncapi: '3.0.0'
info:
title: Task Coordination Events
version: '1.0.0'
operations:
delegateTask:
action: send
channel:
$ref: '#/channels/task~1delegate'
summary: Delegate a task to a specific agent
x-agent-tool:
enabled: true
name: delegate_task
description: "Delegate a task to a worker agent"When an external agent calls delegate_task, it emits the corresponding event to your network. This enables:
- Fire-and-forget task delegation: External agents can trigger internal workflows
- Event-driven orchestration: Coordinate multiple agents through events
- Schema reuse: Use your existing AsyncAPI definitions
3. External Access Config: Authentication & Tool Filtering
Control what external agents can see and do with the new external_access configuration:
# network.yaml
external_access:
# Assign all MCP clients to the "guest" agent group
default_agent_group: "guest"
# Require authentication (optional)
auth_token: "your-secret-token"
# Or use an environment variable
auth_token_env: "MCP_AUTH_TOKEN"
# Only expose these tools (whitelist)
exposed_tools:
- search_web
- delegate_task
# Hide these tools (blacklist)
excluded_tools:
- admin_reset
- debug_dumpThis gives you fine-grained control over:
- Authentication: Require a bearer token for MCP access
- Tool visibility: Whitelist or blacklist specific tools
- Agent groups: Assign external agents to permission groups
Tool Collection Architecture
Tools are now collected from three sources, merged, and filtered:
┌─────────────────────────┐
│ NetworkToolCollector │
└───────────┬─────────────┘
│
┌───────┼───────┐
│ │ │
▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐
│ Mods │ │tools/ │ │events/│
│ │ │ *.py │ │ *.yaml│
└───┬───┘ └───┬───┘ └───┬───┘
│ │ │
└─────────┼─────────┘
▼
┌───────────────┐
│ Merge + Check │
│ Conflicts │
└───────┬───────┘
▼
┌───────────────┐
│ filter_tools │ ◄── external_access
└───────┬───────┘
▼
┌───────────────┐
│ MCP Tools │
└───────────────┘
Tool names must be unique across all sources. If conflicts are detected, the network fails at startup with a clear error message.
Use Cases
Building a Task Orchestration API
Combine workspace tools and event tools to create a complete orchestration API:
workspace/
├── network.yaml
├── tools/
│ ├── file_ops.py # @tool: download_file, upload_file
│ └── analysis.py # @tool: analyze_document, summarize
├── events/
│ └── tasks.yaml # x-agent-tool: delegate_task, complete_task
External agents can:
- Call
download_fileto fetch documents - Call
delegate_taskto assign work to internal agents - Receive completion events via subscriptions
Securing a Multi-Tenant Network
Use external access config to isolate tenants:
external_access:
auth_token_env: "TENANT_API_KEY"
default_agent_group: "tenant_basic"
exposed_tools:
- list_documents
- search
- create_ticket
excluded_tools:
- admin_*
- internal_*Getting Started
Step 1: Create a Tools Folder
mkdir -p workspace/toolsStep 2: Add a Tool
# workspace/tools/hello.py
from openagents import tool
@tool
async def greet(name: str) -> str:
"""Greet someone by name."""
return f"Hello, {name}!"Step 3: Configure MCP Transport
# network.yaml
network:
transports:
- type: "mcp"
config:
port: 8800Step 4: Start the Network
openagents runYour tool is now available at http://localhost:8800/mcp!
What's Next
We're continuing to enhance the MCP transport:
- Request-reply events: Wait for event responses instead of fire-and-forget
- Tool streaming: Stream results from long-running tools
- Rate limiting: Per-agent rate limits for tool calls
- Audit logging: Track all tool invocations for compliance
Thank You
These features were shaped by feedback from our community. If you have ideas for improvements:
- Join our Discord community
- Open an issue on GitHub
- Follow us on Twitter for updates
Happy building!