xyte-mcp
OfficialClick 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., "@xyte-mcpwhich devices in the Tel Aviv office went offline this week?"
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.
xyte-mcp
An MCP server for the Xyte platform API. It gives an AI agent typed, validated access to the public Xyte REST API — endpoint discovery plus a generic call tool — over a local stdio transport.
Reads and writes are both available by default; XYTE_MCP_READ_ONLY=1 makes it a
read-only server.
Xyte is a device management platform: connected device fleets, the spaces they live in, their telemetry and incidents, service tickets, commands, models and warranties. This server puts that API in front of an agent as three tools instead of 77 hand-written ones — it can discover the right endpoint, read its exact contract, and call it with arguments validated against that contract before a request goes out.
Useful for asking an agent to investigate a fleet ("which devices in the Tel Aviv office went offline this week, and what do their open tickets say"), to script routine operations, or to work against the Xyte API without you writing the client.
It runs locally as a subprocess of your MCP host and talks to hub.xyte.io directly — there
is nothing to deploy and no third party in the path.
Install
# In an MCP host, e.g. Claude Code:
claude mcp add xyte -e XYTE_ORG_API_KEY=<your-key> -- npx -y @xyteai/mcpOr configure a host directly:
{
"command": "npx",
"args": ["-y", "@xyteai/mcp"],
"env": { "XYTE_ORG_API_KEY": "<your-key>" }
}Requires Node.js 22 or newer.
MCP servers are loaded when a session starts, so restart your host — or open a new session — after adding it.
Related MCP server: Jamf Pro MCP Server
Getting an API key
Create one in the Xyte portal under Settings → API Keys; see Core API Keys for the walkthrough. An organization key acts as that organization, a partner key as the partner — set whichever scopes you need, or both.
The key is all the tenancy there is: it is bound to its tenant server-side, so there is no tenant or URL to configure.
Documentation
Platform documentation — concepts, portal guides, how the pieces fit together. | |
The REST API this server wraps: authentication, pagination, every endpoint. | |
The whole documentation set as Markdown, plus the endpoints as OpenAPI — written for agents. Worth pointing your agent at alongside this server. | |
This server's source, issues and releases. |
Everything below is about running the server itself.
Configuration
Variable | Purpose |
| Organization-scoped API key. |
| Partner-scoped API key. Set either or both. |
| Set to |
| Override the hub base URL. Defaults to |
| Override the entry base URL. |
| Per-request timeout. Defaults to |
The last three are escape hatches for non-production hubs; the defaults are what you want.
XYTE_MCP_ALLOW_WRITES from 0.1.x is still honoured with its original meaning: if it is set
at all, it decides, so a server pinned shut with XYTE_MCP_ALLOW_WRITES=0 stays shut across
the upgrade. Where the two disagree, the restrictive one wins. New configuration should use
XYTE_MCP_READ_ONLY.
Tools
Tool | What it does |
| Discover endpoints. Filter by |
| Full contract for one endpoint: path params, query params, body shape, required credential. |
| Invoke an endpoint by key with |
The intended sequence is list → describe → call. Endpoint keys are stable identifiers such
as organization.devices.getDevices; the server rejects unknown keys with suggestions
rather than guessing.
Arguments are validated against the endpoint spec before any request is sent, so a wrong parameter name produces a precise message instead of an opaque HTTP 4xx.
Write policy
Default:
GET/HEAD/POST/PUT/PATCHare all permitted.DELETE: additionally requiresconfirmset to the endpoint key verbatim. This holds even with writes enabled — an irreversible call is the one that cannot be walked back.XYTE_MCP_READ_ONLY=1: onlyGET/HEADcan be called. Anything else is refused before a request is built, and the model is told an operator alone can lift it.
xyte_api_call's MCP annotations (readOnlyHint, destructiveHint) follow the live
configuration, so a host prompts according to what the server can actually do.
Worth knowing before you point it at a live fleet. The caller is a model, and read tools return content a third party can influence — device names, ticket bodies, notes. Nothing stops a model from treating text it just read as an instruction, so the server tells it outright that fleet content is untrusted and that mutating intent must come from you. That is a mitigation, not a guarantee. Prefer read-only when the agent runs unattended, when it is working through content you do not control, or when you simply want to look around:
claude mcp add xyte-ro -e XYTE_ORG_API_KEY=<key> -e XYTE_MCP_READ_ONLY=1 -- npx -y @xyteai/mcpBoth can coexist — register a read-only server for exploration and a writable one for the sessions where you want changes to land.
API keys are never echoed back: output is filtered both by field name (api_key, token,
authorization, …) and by literal secret value.
The endpoint catalog
src/catalog/endpoints.generated.json holds 77 endpoints (63 organization, 14 partner). It
is generated from hub's Bruno collection — hub/docs/api/Xyte Public/ — which is the
upstream source the public API reference is built from, and
committed so this repo has no dependency on a hub checkout at runtime.
Device API endpoints are deliberately excluded: they authenticate as a device with a device access token, not as an operator.
To refresh after an API change:
npm run catalog:generate -- --hub-path ../hub
git diff src/catalog/endpoints.generated.json # review, then commitCI cannot regenerate this (it has no hub checkout), so refreshing it is a maintainer step
in the release checklist. --check verifies a committed file matches a fresh generation:
node scripts/generate-catalog.mjs --hub-path ../hub --checkVerifying a real setup
To check the server, your credential and production connectivity in one step — independently of any MCP host wiring:
npm run smoke:live -- --key-stdin # paste the key; keeps it out of shell history
# or
XYTE_ORG_API_KEY=<key> npm run smoke:liveIt spawns the built server and drives real MCP requests against the live API. The child is
started with XYTE_MCP_READ_ONLY=1 regardless of your environment, only GET endpoints are
exercised, and the key is never printed — this runs against production, so it cannot mutate
anything. A pass means the whole path works; if this passes but your host still shows
nothing, the problem is the host registration, not the server.
Development
npm install
npm run typecheck
npm test # builds, then runs unit + protocol tests
npm run lint
npm run inspect # build and open the MCP InspectorTwo invariants are enforced by lint rather than convention, because both erode silently:
Nothing but JSON-RPC may reach stdout. On stdio, stdout is the protocol channel; one stray
console.logcorrupts the stream and the host disconnects.no-consoleis an error insrc/; usesrc/log.ts, which writes to stderr.Tools take
(args, ctx)and nothing else. No environment reads, no transport imports. Credential resolution and transport wiring live insrc/transports/.
That second rule is what keeps the door open for a remote transport (see below).
Releasing
A release is a pushed semver tag. .github/workflows/publish.yml then packs the tarball,
installs and runs it on Linux, macOS and Windows, re-checks the gates, and publishes to npm
with provenance. The npm token lives on the repo's ci GitHub environment, so it is not
reachable from a run on an arbitrary branch.
Checklist, from main with a clean tree:
# 1. Refresh the endpoint catalog. CI cannot do this — it has no hub checkout —
# so a stale catalog is the one release defect nothing else will catch.
npm run catalog:generate -- --hub-path ../hub
git diff src/catalog/endpoints.generated.json # review, commit if changed
# 2. Verify everything the publish job will verify, locally.
npm run typecheck && npm run lint && npm test
npm run smoke:pack-install # packs, installs, runs the binary
# 3. Bump the version and tag it. The publish job refuses to ship a tag that
# disagrees with package.json.
npm version 0.1.0 --no-git-tag-version
git commit -am "Release v0.1.0" && git push origin main
git tag v0.1.0 && git push origin v0.1.0node scripts/generate-catalog.mjs --hub-path ../hub --check exits non-zero when the
committed catalog is stale, if you would rather assert than diff.
Then verify from a machine that has never seen the repo:
npx -y @xyteai/mcp --version
claude mcp add xyte --scope user -e XYTE_ORG_API_KEY=<key> -- npx -y @xyteai/mcp
claude mcp list | grep -i xyte # expect: ✔ ConnectedMCP servers load at session start, so confirm the tools in a new session.
Why stdio only, and what about OAuth
MCP's OAuth 2.1 authorization applies to HTTP transports; for stdio the specification
directs servers to take credentials from the environment, which is what this server does.
Supporting OAuth is therefore not an additive feature — it means running as a remote HTTP
service, which additionally needs an authorization server (Xyte has none today; hub's
oauth2 gem is a client for Zoho/Salesforce/Zoom), a hosted deployment, and a decision
about whether hub accepts OAuth tokens directly or this server holds customer API keys.
That is a separate program, so v1 ships stdio. The tool layer is written to be
transport-agnostic so it can be reused unchanged: adding src/transports/http.ts plus a
resource-server layer would not touch any tool.
Security notes
Read tools return fleet data (device names, notes, ticket text) that a third party can influence, and that data enters the model's context. Treat it as untrusted input — see Write policy for what the server does about it and where
XYTE_MCP_READ_ONLYis the right call.The API key sets the blast radius, and it is the one control the model cannot talk its way around. Scope it to what the agent needs.
Prefer passing keys through your host's secret handling rather than committing them into a shared
.mcp.json.
License
Apache-2.0
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
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/xyte-io/xyte-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server