# Giving a LangChain Agent Real-World Facility-Management Tools via MCP

> Source: <https://dev.to/telesherpa/giving-a-langchain-agent-real-world-facility-management-tools-via-mcp-4g1i>
> Published: 2026-09-28 19:36:16+00:00

Most "give your agent tools" tutorials hand it a calculator or a weather API. Useful for learning the mechanics, but it doesn't tell you what happens when an agent gets access to a real operational system — one with access control, multi-tenancy, and objects that map to actual physical things (buildings, vehicles, machines).

This post walks through connecting a LangChain agent to [Telesherpa](https://www.telesherpa.com), an ontology-based platform for facility, fleet and field-service management, over the [Model Context Protocol](https://modelcontextprotocol.io) (MCP). By the end, the agent can query and modify real ontology objects — not toy data — using nothing but its own reasoning and the tools MCP hands it.

Two things make this a useful example rather than a marketing demo:

`public` caller sees a handful of self-registration tools, an authenticated caller with the right scope sees object CRUD, reports, automation triggers, structured image filing, and more. That's a realistic shape for enterprise software, and a good stress test for whether an agent framework's tool-loading actually scales.`register()`, `activate()` (a 7-digit email code), and `login()` are all public MCP tools. An agent can go from nothing to an authenticated session without a human ever opening a browser.
LangChain's official [`langchain-mcp-adapters`](https://github.com/langchain-ai/langchain-mcp-adapters) package speaks MCP's Streamable HTTP transport natively, including custom headers — which is what you need for Bearer-token auth against a remote server:

``` python
from langchain_mcp_adapters.client import MultiServerMCPClient

client = MultiServerMCPClient({
    "telesherpa": {
        "transport": "http",
        "url": "https://mcp.telesherpa.com",
        "headers": {"Authorization": f"Bearer {token}"},
    }
})

tools = await client.get_tools()
```

That's the entire integration surface. `tools` is now a list of LangChain-compatible tools, generated directly from the server's live tool catalog — no manual schema mapping, no maintaining a wrapper per endpoint. If Telesherpa adds a tool next week, your agent sees it next week too.

Before that snippet works you need `token`. Since every step is itself an MCP tool call, an agent can do this on its own:

```
# 1. register — creates an account, requires accept_terms=true
await call_tool("register", {"email": "...", "accept_terms": True, ...})

# 2. activate — redeem the 7-digit code emailed to that address
await call_tool("activate", {"code": "1234567"})

# 3. login — exchange client credentials for a bearer token
result = await call_tool("login", {"client_id": "...", "client_secret": "..."})
token = result["token"]          # valid ~10h
refresh_token = result["refresh_token"]
```

`auth_status` is worth calling first in any new session — it tells you plainly whether your token is valid, which roles it carries, and how many of the total tools are currently visible to you. Cheaper than guessing from a 401.

With tools loaded, a standard LangChain agent can now reason over real ontology objects:

``` python
from langchain.agents import create_agent

agent = create_agent("openai:gpt-4.1", tools)

response = await agent.ainvoke({
    "messages": "List the buildings in my current scope and flag any "
                "that are missing a structured image category."
})
```

Under the hood this typically resolves to a couple of tool calls — something like `onto_type_show("building")` to enumerate objects, then `onto_file_structured(object_id)` per building to check which image categories are filled. The agent picks the sequence; you didn't hardcode it.

What makes this more than a search-and-summarize demo is that the same tool surface supports *writes*: creating objects, executing defined actions on them (check-in/check-out, service-order creation, form submission), setting properties, and — critically for anything touching real operations — a role-based access model that determines what an agent is even allowed to attempt. The interesting engineering problem isn't "can the agent call a tool," it's "does the permission boundary hold when the caller is non-human."

The same MCP server works the same way with CrewAI, LlamaIndex, and Microsoft's Agent Framework, since MCP is transport- and framework-agnostic by design — the tool definitions and auth flow don't change, only the client-side plumbing does. Working examples for each (some verified, some flagged as in-progress) are in [`telesherpa/telesherpa-quickstarts`](https://github.com/telesherpa/telesherpa-quickstarts). The full capability reference — object model, scopes, automation, structured image filing, forms — is in [`telesherpa/skill-telesherpa-com`](https://github.com/telesherpa/skill-telesherpa-com).

If you're building agents that need to do something in the physical world — not just answer questions about it — this is roughly the shape that "agent-ready" enterprise software needs to take: a documented, self-registering, role-scoped MCP surface, not a REST API with an OpenAPI spec bolted on after the fact.
