# Run AgentOS MCP tools over plain HTTP

> Agno AgentOS can now run any tool on its MCP Server Card from a single HTTP POST, so you can test a tool with curl or an operator UI and skip writing an MCP client.

- Published: 2026-10-22
- Author: Sannya Singal
- Categories: Changelog
- Canonical: https://www.agno.com/blog/run-agentos-mcp-tools-over-plain-http
- Markdown: https://www.agno.com/blog/run-agentos-mcp-tools-over-plain-http.md

Agno AgentOS serves `POST /mcp/server/tools/{tool_name}/run`, which takes the tool's arguments as JSON and answers with the `isError`, `content` and `structuredContent` fields that `tools/call` returns, plus `durationMs`. The Server Card already lists every tool with its input schema, so an operator UI can build a form from the card and send the filled form to this route.

```python
from fastapi.testclient import TestClient

from agno.agent import Agent
from agno.os import AgentOS, MCPConfig

def word_count(text: str) -> dict:
    """Count the words in a piece of text."""
    return {"words": len(text.split())}

agent_os = AgentOS(
    agents=[Agent(id="support-agent")],
    mcp=MCPConfig(tools=[word_count]),
)

with TestClient(agent_os.get_app(), base_url="http://localhost") as client:
    response = client.post(
        "/mcp/server/tools/word_count/run",
        json={"arguments": {"text": "run any published tool over HTTP"}},
    )
    print(response.status_code, response.json())
    # 200 {'isError': False, 'content': [{'type': 'text', 'text': '{"words":6}'}],
    #      'structuredContent': {'words': 6}, 'durationMs': 1}
```

![Real output from an AgentOS with a word_count tool. The request POST /mcp/server/tools/word_count/run with a text argument returns HTTP 200 with isError false, structuredContent words 6 and durationMs 2. Below it, a wrong argument type returns 400 invalid_arguments, an unknown tool returns 404 tool_not_found, and a tool that ran and failed returns 200 tool_error.](https://www.agno.com/images/v3-1-9-mcp-tool-runner.png)

Every failure comes back in that same shape with an `error` code, and the HTTP status tells you whether the tool ran at all. Passing `42` as `text` returns 400 `invalid_arguments` with the pydantic message in `details`, and a name the card does not list returns 404 `tool_not_found`. Asking `run_agent` for an agent that does not exist returns 200 with `isError: true`, because the tool ran and reported the failure. A call that outlives `tool_run_timeout_seconds` (120 by default) is cancelled and returns 504 `timeout`.

The runner sits behind the same gates as `/mcp`. On an AgentOS with a security key, a request that leaves the key out gets 401. Under JWT authorization each tool still checks its RBAC scopes, so a token holding only `sessions:read` that calls `run_agent` gets `Insufficient permissions. Required scope(s): agents:run`. With `mcp_auth`, only a token the provider verified counts as a caller, and a `?user_id=` query parameter never does.

`MCPConfig(tool_run_endpoint=False)` removes the route, which then returns 404 while the Server Card keeps working. `/info` reports `tool_run_endpoint` either way, so a UI can hide its Run button up front. All of the output above comes from this release under FastAPI's `TestClient`.

See the [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/05_agent_os/14_mcp/inspect_tools.py), and learn more about the [AgentOS MCP server](https://docs.agno.com/agent-os/mcp/mcp) in the documentation.
