MCP in action¶
Every method is also a tool for AI agents. Any framework that speaks MCP gets all of amoorion this way: Claude, CrewAI, Google’s ADK, LangChain, nanobot and others. Tools that only read are marked, so clients may let them run and ask before the rest.
from amoorion import Amoorion
# The same methods as tools for agents; started as `amoorion mcp`.
server = Amoorion().mcp()
# What an agent sees on connecting.
tools = await server.list_tools()
# Read-only ones an agent may use freely; the others deserve a confirmation.
for tool in tools[:6]:
print(f"{tool.name:10} read-only={tool.annotations.read_only_hint}")
accounts read-only=True
compose read-only=False
delete read-only=False
inbox read-only=True
notify read-only=False
plugins read-only=True
What an agent sees for one tool:
# A tool's parameters, generated from the method's `Params`.
next(tool for tool in tools if tool.name == "search").input_schema[
"properties"
].keys()
dict_keys(['text', 'platform', 'limit'])
A client’s configuration:
{"mcpServers": {"amoorion": {"command": "uv", "args": ["run", "amoorion", "mcp"]}}}
Publishing reaches real accounts, so keep the asking on for tools that change things.
Tools and resources of your own¶
Amoorion’s server is the official MCPServer, named and versioned, so tools and resources are added the way the MCP documentation shows. Its own tools come from the methods; these are next to them.
server = Amoorion().use("dryrun").mcp()
print(server.name)
@server.tool()
def add(
a: int,
b: int,
) -> int:
"""Add two numbers."""
return a + b
@server.resource("greeting://{name}")
def greeting(name: str) -> str:
"""Greet someone by name."""
return f"Hello, {name}!"
amoorion
A client, as a member of the simulated party would be¶
Client takes the server itself, in memory, or a URL such as http://localhost:8000/mcp.
from mcp import Client
async with Client(server) as client:
# A tool of ours.
answer = await client.call_tool(
"add",
{
"a": 1,
"b": 2,
},
)
print(answer.structured_content)
# A resource of ours.
print((await client.read_resource("greeting://party")).contents[0].text)
# What every amoorion server has by itself.
print(
(await client.read_resource("amoorion://methods"))
.contents[0]
.text[:80],
"…",
)
# And the methods, as tools.
done = await client.call_tool(
"publish",
{
"text": "hello from a member",
"to": ["dryrun"],
},
)
print(done.is_error)
print(
(await client.read_resource("amoorion://inbox/5"))
.contents[0]
.text[:80],
"…",
)
{'result': 3}
Hello, party!
[{"name": "accounts", "description": "Which platforms have their secrets in the …
False
[] …