ReNile-MCP
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ReNile-MCPshow me the latest sensor readings for my greenhouse devices"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ReNile-MCP
A remote MCP server that exposes the ReNile IoT platform over Streamable HTTP. Clients connect by URL and sign in with their own ReNile account through OAuth; each user sees only their own devices.
Tools
Tool | Purpose |
| Lists every device ( |
| Latest sensor readings. Omit |
Each reading carries sensor, value, unit, lower_limit, upper_limit,
status (normal/high/low/unknown), timestamp, age_seconds, and a
derived is_stale flag.
is_stale matters: the platform serves last-known values indefinitely, so a
reading can report status: normal while being over a year old. Anything older
than STALE_AFTER_SECONDS (default 1 hour) is flagged so it is not mistaken for
a current condition.
An unmatched or ambiguous device returns matched: false plus the valid device
names, rather than failing — so the model can correct itself in the same turn.
Related MCP server: Smart Irrigation MCP Server
How authentication works
The server is an OAuth 2.1 resource server. It issues nothing and stores no credentials:
A client connects to
/mcpwith no token and gets401plusWWW-Authenticate: Bearer ..., resource_metadata="...".It follows that to
/.well-known/oauth-protected-resource/mcp, which names the ReNile authorization server, and runs the OAuth flow there.It retries with the user's access token. The server forwards that token verbatim to the ReNile API.
The server does not validate tokens — no signature check, no audience check.
The ReNile API is the sole authority and answers 401 if a token is bad. The
token's sub, iss and exp claims are read (unverified), for two reasons
documented in src/core/auth.py: to bind an MCP session to one principal, so a
session id is not a usable credential for a different user; and to reject an
expired token at the door, where the client still gets a re-auth challenge.
Opaque (non-JWT) tokens work too — the session is bound to a hash of the token instead — but expiry can then only be discovered upstream.
What the ReNile backend must provide
/.well-known/oauth-authorization-server(RFC 8414)/authorizeand/token:authorization_codewith PKCES256, plusrefresh_tokenDynamic Client Registration (RFC 7591) — without it, every client product must be pre-registered by hand
The
resourceparameter (RFC 8707), so tokens are audience-bound/api/v1/devices/names/and/api/v1/snapshot/accepting those access tokens, and scoped to the authenticated user401for an expired token, kept distinct from403for a permission failure
Setup
uv sync
cp .env.example src/.env # then set the two required URLs
chmod 600 src/.env
uv run uvicorn src.app:app --host 0.0.0.0 --port 8000Variable | Default | |
| — | Required. The ReNile authorization server. No trailing slash. |
| — | Required. The exact public URL clients use, including |
| (empty) | Comma-separated. Must include the public hostname or requests are rejected with 421. Each entry also matches that host on any port. |
| (empty) | Comma-separated. |
|
| |
|
| See "Scaling" below. |
|
| Scheme used when forwarding the token upstream. The platform uses |
|
| |
|
| |
|
| |
|
| |
|
| Total attempts per request; |
|
| Shared upstream pool size. |
|
| How much of an upstream error body to quote back. |
|
| |
|
| Age past which a reading is flagged |
Deployment
docker build -t renile-mcp .
docker run -p 8000:8000 --env-file deploy.env renile-mcpRoutes: /mcp, /.well-known/oauth-protected-resource/mcp, and /healthz
(unauthenticated, liveness only — it makes no upstream call because it has no
token to make one with).
Serve it over HTTPS. The access token is a bearer credential on every
request. Terminate TLS at a proxy and keep --proxy-headers on.
Two settings break the first deploy if they are wrong:
RENILE_RESOURCE_SERVER_URLmust byte-match the URL clients actually use. It is what the 401 challenge points at; get it wrong and OAuth discovery dead-ends silently.ALLOWED_HOSTSmust contain the public hostname. DNS-rebinding protection is always on, and an unlisted host is answered with421 Invalid Host header. A bare hostname also matches that host on any port, solocalhostcoverslocalhost:8000.
Scaling
Sessions are held in a per-process dict, so stateful serving needs one worker per
process and sticky routing at the load balancer. For several replicas behind a
round-robin balancer, set STATELESS_HTTP=true — but note that this also removes
the session-ownership check, which only matters for older clients (2025-era
protocol versions); newer ones are per-request either way.
Connecting a client
Add https://mcp.renile-iot.com/mcp as a remote MCP server (Claude, ChatGPT and
Cursor all take a URL) and complete the ReNile sign-in when prompted.
Development
uv run pytest # unit + HTTP protocol tests
uv run uvicorn src.app:app --reload # local run
curl -i localhost:8000/mcp # expect 401 + WWW-AuthenticateThe test suite drives the real ASGI app in-process — no uvicorn subprocess, no
port to race on. tests/test_http.py covers the assertions that are easy to
break silently: the 401 challenge carries resource_metadata, the caller's token
reaches the upstream API verbatim, two concurrent callers never cross tokens, and
one user's session id is refused to another.
Layout
src/app.py ASGI entrypoint: transport security, uvicorn target
src/server.py MCP wiring: tools, lifespan, auth settings, errors
src/core/auth.py the pass-through token verifier
src/core/config.py pydantic-settings; the only reader of the environment
src/core/logging.py stderr logging
src/services/processing.py payload shaping: matching, staleness, responses
src/services/renile_client.py async httpx client; the token is a per-call argumentTool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
An authenticated remote MCP server for user-owned devices and one-shot capability invocation.
Query, browse, and automate OmegaAI workspaces from any MCP client. Streamable HTTP with OAuth 2.0.
Remote MCP server for training, nutrition, wellness, and performance data with OAuth 2.0.
NOAA and ECMWF weather forecast MCP for discovery, validation, and GribStream OAuth queries.
Related MCP Servers
AlicenseNot gradedqualityDmaintenanceEnables to retrieve device information, images, media, location, thumbnails, and events from the Safie API through MCP.6MIT- AlicenseNot gradedqualityCmaintenanceExposes real-time soil sensor metrics as MCP Resources and irrigation valve controls as MCP Tools, enabling AI-driven agronomic decisions with built-in safety guardrails.Apache 2.0
- AlicenseAqualityCmaintenanceMCP server for the Withings Health API with per-user OAuth2, enabling users to securely access their own health data (measures, activity, sleep, workouts, heart rate, devices, and goals) and optionally add measurements.12Apache 2.0
- FlicenseNot gradedqualityBmaintenanceEnables read-only access to Amazfit/Zepp fitness data via the unofficial Zepp cloud API, exposing normalized health and workout metrics to MCP clients.-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/mohamedelsayadrenile/IOT-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server