mcp-mikrotik
mcp-mikrotik is an MCP server for managing MikroTik RouterOS devices over stdio, providing extensive read-only monitoring tools and a small set of guarded write operations.
Read-only tools – query device state without any risk:
list_devices,system_info,interfaces,ip_addresses,ip_routes,neighbors,logs,ping,traceroutearp_table,bridge_hosts,dhcp_leases,simple_queues,address_lists,firewall_nat,firewall_filterscheduler,ip_pools,wireless_registrations,dns_cache,system_health,interface_trafficpoe_status,lte_status,lte_interfaces,containers,container_config,usb_devices,list_write_operations
Guarded write tools – require MIKROTIK_ALLOW_WRITE=true and a two-step confirm=false (preview) → confirm=true (apply) flow:
set_identity– set the device hostnameenable_interface/disable_interface– toggle a network interfaceset_wifi_ssid– change a wireless SSID (ROS6/ROS7 compatible)set_client_bandwidth– create/update a Simple Queue to limit client bandwidthadd_static_dhcp_lease/ (no silent duplicates) – create a static DHCP leaseremove_simple_queue– remove a queue by name or targetadd_to_address_list/remove_from_address_list– manage firewall address-list entriesset_poe_out– set PoE output mode (auto-on/forced-on/off) for remote power cyclingstart_container/stop_container– manage OCI containers by name or tag
Security model:
Write-disabled by default; only an explicit allowlist of reviewed operations is permitted (no generic command execution)
All writes show a before/after diff before applying; named-resource writes fail if the resource doesn't exist (preventing typos from creating stray config)
Passwords and secrets are never returned in responses; all device communication uses a structured API (no command injection)
Production hardening:
Audit journal (structured JSON lines) for every write operation (preview, applied, or failed)
Correlation IDs on every tool call for end-to-end traceability
Automatic read retries on transient network errors
Per-device in-memory circuit breaker to fail fast on unresponsive devices
TLS/SSL support with optional CA cert or
tls_verify: falsefor self-signed certificates
Manages MikroTik RouterOS devices: reads device state (interfaces, routes, neighbors, logs, ping) and allows a limited set of guarded write operations such as setting the device identity.
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., "@mcp-mikrotikshow system info for device office-router"
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.
mcp-mikrotik
A Model Context Protocol server for managing MikroTik RouterOS devices - read device state (interfaces, routes, neighbors, logs, ping) and, for a small, explicit set of write operations, change it, from an MCP client such as Claude Code.
This is a from-scratch implementation, not a fork. It exists to correct a set
of concrete failures found in an earlier project during a security audit:
an unrestricted generic "run any API command" tool, an HTTP transport bound
to 0.0.0.0 with no auth, command injection via string-built SSH calls, and
no tests. See "Security model" below for how each of those is avoided here.
Status
v0.7: everything from v0.6 (the core read-tool inventory, ping/
traceroute diagnostics, a set of guarded write tools - set_identity,
enable_interface/disable_interface, set_wifi_ssid,
set_client_bandwidth, add_static_dhcp_lease, remove_simple_queue,
add_to_address_list/remove_from_address_list, set_poe_out - all going
through the same write-guard mechanism, plus the production-hardening
layers around it: audit journal, correlation ids, read retry, circuit
breaker; physical layer / L2 observability - interface_traffic,
poe_status), plus an LTE/5G + containers + USB round: lte_status/
lte_interfaces (cellular WAN signal/status), containers/
container_config (RouterOS's container subsystem), usb_devices (USB
ports + attached storage), and two new guarded write tools,
start_container/stop_container - the first writes whose RouterOS
operation is an ACTION command rather than an update/add/remove set; see
"How start/stop extends the guard" in CHANGELOG.md for how that new shape
was added without weakening the guard. See "LTE/5G monitoring", "Container
management", and "USB" below. None of this changes the security model - see
"Production features" and "Security model" below. See CHANGELOG.md for
what changed since v0.1.0, and src/mcp_mikrotik/guard.py for how to add
the next write tool.
Related MCP server: vyos-mcp
Installation
Requires Python >= 3.11.
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"Configuration
Configuration comes from environment variables plus an optional
devices.yaml file.
Copy the examples:
cp devices.yaml.example devices.yaml cp .env.example .envEdit
devices.yamlwith your real devices and credentials. This file is git-ignored - it is never meant to be committed.Edit
.env(or export the variables another way) to control server-wide behaviour:Variable
Default
Meaning
MIKROTIK_DEVICES_FILEdevices.yamlPath to the devices YAML file
MIKROTIK_ALLOW_WRITEfalseEnable write tools (see Security model)
MIKROTIK_LOG_LEVELINFOLog level for the server process (stderr); invalid values fall back to
INFOwith a warningMIKROTIK_TIMEOUT10Fallback connect timeout (seconds) for devices without their own
timeoutMIKROTIK_AUDIT_LOG(unset)
File path for the JSON-lines write-audit journal; unset logs each event via
logging(stderr) instead. See "Production features" below.MIKROTIK_READ_RETRIES2Extra retry attempts for read operations on a transient network error
MIKROTIK_BREAKER_THRESHOLD3Consecutive connection failures before a device's circuit breaker opens
MIKROTIK_BREAKER_COOLDOWN30Seconds a device's circuit stays open before a trial reconnect is allowed
Each device entry supports its own port and use_ssl, since a fleet is
commonly a mix of plain API (8728) and api-ssl (8729) devices, and possibly a
mix of RouterOS 6.x and 7.x. It can also override timeout (seconds; falls
back to MIKROTIK_TIMEOUT, then 10s - useful for devices behind a slow
link) and, when use_ssl: true, tls_verify (see "TLS verification for
api-ssl" below).
Running
The server speaks MCP over stdio - it is meant to be launched by an MCP client (e.g. configured as a command in Claude Code), not run as a network service:
mcp-mikrotik
# or, without installing the console script:
python -m mcp_mikrotik.serverThere is no HTTP transport in v0. If one is added later, it must default to
binding 127.0.0.1 (never 0.0.0.0) and require a bearer token from an
environment variable - see the TODO(http-transport) note at the top of
src/mcp_mikrotik/server.py.
Tools
Read-only
Tool | Description |
| List configured devices (passwords never included). |
| RouterOS identity + resource info (board, version, uptime, CPU/memory). |
| List interfaces; |
| List IPv4 addresses. |
| List the IPv4 routing table; optional |
| List neighbors discovered via CDP/MNDP/LLDP. |
| List DHCP server leases (address, mac, host-name, status, server, comment). |
| List Simple Queue entries (name, target, max-limit, limit-at, bytes counters, disabled) - see who already has a bandwidth limit and how much traffic they've moved. |
| List firewall address-list entries (list, address, timeout, dynamic, disabled) - see who's currently in which named list. |
| List IPv4 firewall NAT rules (chain, action, to-addresses, etc). Read-only - does not add/modify/remove rules. |
| List scheduled tasks (name, on-event, interval, next-run, disabled). |
| List IP pools (name, ranges). |
| List wireless clients currently associated to the device. Tries the ROS7 wifi registration table first, falls back to the ROS6 wireless one; returns an empty list (not an error) for a device with no radio. |
| List cached DNS records (name, type, data, ttl). |
| List IPv4 firewall filter rules (chain, action, etc). Read-only - does not add/modify/remove rules. |
| System health metrics (voltage, temperature, ...), if the device exposes any; empty list otherwise. |
| Recent log entries; |
| Ping an address from the device; |
| Traceroute to an address from the device; returns the list of hops. |
| List the IPv4 ARP table (address, mac-address, interface, dynamic, complete) - cross-reference IP↔MAC for a statically-addressed device that doesn't show up in |
| List |
| Current rx/tx rate of one |
| PoE configuration + live consumption for every PoE-capable ethernet port on the device (voltage/current/power/ |
| Signal/status of one LTE/5G modem |
| List LTE/5G modem interfaces (name, running, disabled, apn-profiles). Empty list (not an error) with no LTE hardware. |
| List containers (name/tag, status, ram-usage, root-dir, interface, os). Empty list (not an error) with no container package. See "Container management" below. |
| Container subsystem configuration (registry-url, tmpdir, ram-high). Empty dict (not an error) with no container package. |
| USB ports ( |
| List every guarded write operation and the RouterOS path/action it maps to (metadata only, no gate). |
Write (guarded)
Every write tool below requires MIKROTIK_ALLOW_WRITE=true and is called
twice: once with confirm=false (the default) to get a before/after
preview, and again with confirm=true to actually apply it. See "Security
model" below for the full guard mechanism.
Tool | Description |
| Set a device's RouterOS identity (hostname). |
| Enable a network interface by name ( |
| Disable a network interface by name ( |
| Set a wireless interface's SSID. Detects whether the interface lives under the ROS7 wifi package or the ROS6 wireless package and writes to whichever one matches; errors if the interface name isn't found under either. |
| Limit a client's bandwidth via a Simple Queue targeting an IP/subnet ( |
| Create a static DHCP lease pinning an IP |
| Remove a Simple Queue by |
| Add an IP/subnet |
| Remove the |
| Set a PoE-capable ethernet port's |
| Start a container by |
| Stop a container by |
Not yet exposed, deliberately: device reboot and firewall rule writes. See "Roadmap / non-goals" below for why.
Limiting a client's bandwidth (v0.3)
The typical flow to find and limit a client that's consuming too much of the link:
simple_queuesanddhcp_leases/wireless_registrationsto see who's on the network and whether they already have a limit.Optionally,
add_static_dhcp_leaseto pin a chatty client's IP so itstargetdoesn't drift to a different address on DHCP renewal.set_client_bandwidthwithconfirm=falsefirst to preview themax-limit/limit-atit would set (and whether it would create a new queue or update an existing one), thenconfirm=trueto apply it.remove_simple_queue(bytargetorname) to lift the limit later.
FastTrack gotcha: RouterOS's own quick-set wizards commonly add a
FastTrack rule to /ip/firewall/filter for performance. Fasttracked
connections bypass the whole queueing subsystem, including Simple Queue -
so a queue created by set_client_bandwidth can silently have zero effect
on a client whose traffic is already being fasttracked. If a limit doesn't
seem to be taking effect, check firewall_filter for a FastTrack rule and
adjust/disable it for the traffic you're trying to limit. mcp-mikrotik
does not modify firewall rules itself (see "Roadmap / non-goals" below).
Blocking/allowing a client via address lists (v0.4)
add_to_address_list/remove_from_address_list manage entries in a named
/ip/firewall/address-list - nothing more. Adding an address to a list has
no effect on traffic by itself. It only blocks or allows anything if a
/ip/firewall/filter (or NAT) rule on the device already references that
same list name, e.g.:
/ip firewall filter add chain=forward src-address-list=blocked-clients action=dropmcp-mikrotik does not create, modify, or inspect that rule for you (see
"Roadmap / non-goals" below for why firewall filter writes aren't exposed at
all yet) - use firewall_filter to check whether a rule referencing your
list already exists on the device before relying on add_to_address_list to
actually block or allow anyone. The typical flow:
Confirm (once, out of band - e.g. via WinBox/CLI, or just by reading
firewall_filter) that a filter rule referencing your list name exists, e.g.src-address-list=blocked-clients action=dropon theforwardchain.dhcp_leases/wireless_registrations/neighborsto identify the client's IP.add_to_address_listwithconfirm=falsefirst to preview the entry it would add, thenconfirm=trueto apply it. An optionaltimeout(e.g."1d") auto-expires the entry instead of blocking/allowing permanently.address_liststo check current membership;remove_from_address_listto lift a block/allow later.
Physical layer & PoE control (v0.6)
Three tools for the physical/L2 layer, aimed at fleets where devices are powered over PoE from a managed switch (e.g. a MikroTik CRS318-16P-2S+ feeding antennas at different PoE levels - 48V "high" and 24V "low"):
arp_table/bridge_hosts(/ip/arpand/interface/bridge/host- see the read-tools table above) to cross-reference an IP to a MAC, and a MAC to the physical bridge port it's on.interface_trafficfor a live rx/tx reading on one interface.poe_statusfor per-port PoE configuration and live consumption (voltage/current/power/poe-out-status) across every PoE-capable port - empty, not an error, on hardware with no PoE at all.set_poe_outto change a port's PoE output mode.
The killer use case: remote power-cycle a locked-up antenna/camera/AP. Rather than a truck roll to physically unplug/replug a device, if it's powered over PoE from a MikroTik switch:
bridge_hosts(orarp_table) to confirm which physical port the stuck device is on, if not already known.poe_statusto see its currentpoe-out/poe-out-statusand confirm it's actually drawing power (voltage/current > 0) before assuming a PoE cycle will help.set_poe_outwithpoe_out="off",confirm=falsefirst to preview, thenconfirm=trueto actually cut power to the port.Wait a few seconds -
poe_statusagain to confirmpoe-out-statusshows the port is no longer powered.set_poe_outwithpoe_out="auto-on"(preview, then confirm) to restore power.forced-onis also available for ports/devices that need power regardless of RouterOS's own PoE detection/negotiation.
Like every other write tool, set_poe_out never creates or coerces
anything: it raises ResourceNotFoundError if interface_name doesn't
exist on the device at all, or if it exists but has no poe-out field (not
PoE-capable hardware, e.g. an SFP+ cage) - see "Security model" below.
LTE/5G monitoring (v0.7)
For devices with a cellular WAN modem (LTE/5G):
lte_interfacesto see which LTE interfaces exist on the device (name, running, disabled, apn-profiles).lte_statusfor one interface's live signal/status - operator (current-operator), technology (access-technology: 3G/LTE/5G), signal quality (rsrp/rsrq/sinr/rssi),band,registration-status, andcell-id. Built the same "monitor-once" way asinterface_traffic/poe_status(/interface/lte/monitor <interface> once=yes) - a single instantaneous reading, not a stream.
Both return empty (an empty list/dict, never an error) on a device with no
LTE hardware or package at all - the same convention poe_status/
system_health already use for optional hardware.
Container management (v0.7)
RouterOS 7's container package runs OCI containers directly on the device (e.g. a lightweight metrics agent or a small web dashboard, without a separate host). The typical flow:
containersto see what's deployed (name/tag, status, ram-usage, root-dir, interface, os) andcontainer_configfor the subsystem-wide settings (registry-url, tmpdir, ram-high).start_container/stop_containerwithconfirm=falsefirst to preview, thenconfirm=trueto actually apply it.containermatches against a container'snameif it has one, falling back to itstag(the image reference, e.g."grafana/grafana:latest") otherwise - RouterOS only populatesnamewhen the container was created with one explicitly.
Unlike enable_interface/set_poe_out (which flip a field synchronously),
starting/stopping a container fires a RouterOS action command
(/container/start//container/stop) that transitions asynchronously -
the preview's after.status reflects the immediate transitional state
("starting"/"stopping"), not a guaranteed final one. Call containers
again afterward to see the settled "running"/"stopped" status. See
CHANGELOG.md's "How start/stop extends the guard" for how this new
action-command shape was added to the write guard without weakening it.
Like every other write tool, start_container/stop_container never
create a container: an unmatched container raises
ResourceNotFoundError.
USB (v0.7)
usb_devices reads /system/routerboard/usb (physical USB ports, on
boards that expose them) and /disk (attached storage - USB flash drives,
and USB LTE/5G modems that surface as a disk rather than under
routerboard/usb) and returns both as {"usb_ports": [...], "disks": [...]}, since which of the two a given USB device shows up under depends
on the hardware. Either or both lists come back empty (never an error) on a
board with no USB hardware at all.
Security model
Three independent controls apply to every write tool, all centralized in
src/mcp_mikrotik/guard.py:
Read-only by default.
MIKROTIK_ALLOW_WRITEdefaults tofalse. With writes disabled, any write tool returns a clear error and never touches the device - the gate is checked before any read or write call is made.Central allowlist, no generic command tool. There is no tool that accepts an arbitrary API path or command. Each write operation is a dedicated, named function (e.g.
set_identity,enable_interface) mapped to exactly one API path and action inguard.ALLOWLIST. There is no code path by which a caller can reach an API path outside that table. As of v0.7,actionisn't limited toupdate/add/remove:start_container/stop_containerusestart/stopto represent RouterOS's/container/start//container/stopACTION commands - but the dispatch mechanism (getattr(client, op.action)) and the fixed, individually-reviewedMikrotikClientmethod it can ever reach are unchanged; seeCHANGELOG.md's "How start/stop extends the guard".set_wifi_ssidandset_client_bandwidthare the two exceptions to "one tool, one allowlist entry": because RouterOS exposes wifi under different paths depending on generation (ROS7/interface/wifivs ROS6/interface/wireless),set_wifi_ssidis backed by two fixed, reviewed allowlist entries (set_wifi_ssid_ros7/set_wifi_ssid_ros6), and the guard function picks between them by checking which path actually has a matching interface name on the device. Likewise,set_client_bandwidtheither updates an existing Simple Queue or creates a new one, so it is backed byset_client_bandwidth_update/set_client_bandwidth_add, and the guard function picks between them by checking whether a queue already targets the giventarget. In both cases the choice is made entirely by the guard function reading the device - never by accepting a path or an add-vs-update decision from the caller.Explicit confirm with before/after preview. Every write tool takes a
confirm: boolparameter. Withconfirm=False(the default), the tool computes and returns what would change - abefore/afterstructure - without applying anything. Onlyconfirm=Trueapplies the change.
On top of the write guard:
Never creates the target. Write tools that operate on a named resource (
enable_interface/disable_interface/set_wifi_ssid/remove_simple_queue/remove_from_address_list/set_poe_out/start_container/stop_container) look it up by name first. If no interface/wireless network/queue/ address-list entry/container with that name (ortarget,list_name+addresspair, orname/tag) exists on the device, the tool raises a clear error instead of creating one - a typo can never silently provision something new.set_poe_outadditionally requires the matched interface to actually have apoe-outfield (i.e. be PoE-capable hardware) - a name that exists but isn't a PoE port raises the same clear error rather than doing nothing silently.Never silently duplicates.
add_static_dhcp_leasechecks for an existing lease on the givenmac_addressfirst, andadd_to_address_listchecks for an existing entry with the samelist_name+addresspair first, each raisingResourceAlreadyExistsErrorinstead of creating a second one - both forconfirm=falsepreviews andconfirm=trueapplies.Structured API, not shell commands. All device communication goes through
librouteros's structured API (path().select()/.add()/.update()/.remove(), and the callable form for one-off commands like ping). Nothing in this codebase builds a command by concatenating strings from user input, so command injection is ruled out by construction rather than by input filtering.Input validation on top, for its own sake.
ping'saddressis still validated against an IPv4/IPv6/hostname pattern before use, purely to reject garbage input early with a clear error - not as an injection defense (see previous point).No secrets in output.
Device.to_public_dict()is the only device representation ever returned to a tool caller, and it omits the password field entirely. Passwords are never logged.Structured errors. All errors raised inside the package derive from
MikrotikMCPError(seesrc/mcp_mikrotik/exceptions.py) and are caught at the tool boundary inserver.py. The exception is deliberately re-raised, not turned into an{"error": ...}result dict: MCP itself turns an exception propagating out of a tool into a properisErrortool result carrying just that exception's (already-safe) message, and letting the framework do that keeps every tool's declared return type honest (a successfullogscall always returnslist[dict], never sometimes a dict-shaped error instead). Unexpected exceptions are logged server-side and re-raised as a generic internal-error message, never as a raw traceback.
Production features: audit log, correlation IDs, retries, circuit breaker
v0.5 adds a set of layers around the write-guard mechanism above, aimed at
running mcp-mikrotik unattended against a real fleet. None of them can
weaken or bypass the read-only gate, the central allowlist, or the
confirm/preview flow - every write still goes through guard.py exactly as
described in "Security model", and the circuit breaker in particular never
skips guard.py's read-only gate/allowlist check: that check runs first,
entirely before MikrotikClient ever attempts a connection.
Audit journal. Every guarded write call (
guard.py, one of theALLOWLISToperations) emits exactly one structured JSON-lines event - whether it previewed (confirm=false), applied (confirm=true), or failed at any point, however early (even a write blocked by the read-only gate before the device is ever touched). Each event has atimestamp,correlation_id,device_name,tool,operation(theALLOWLISTkey),action(add/update/remove/start/stop- see v0.7'sstart_container/stop_container),confirm,outcome(preview/applied/error), and asummaryof the before/after change (or the error). Never includes a device password or any field that looks like a secret - seesrc/mcp_mikrotik/audit.py's_sanitize(). Destination isMIKROTIK_AUDIT_LOG(a file path, appended to) if set, otherwise a plainINFO-level line via the standard logger (stderr). Writing the journal is always best-effort: a bad path or a permissions error is logged as a warning and never blocks or fails the write it is describing. Read tools are never journaled - only guarded writes are.Correlation IDs. Every MCP tool call (read or write) gets a short, unique id (
uuid4().hex[:12]) for its duration - seesrc/mcp_mikrotik/correlation.py. It is bound once per call inserver.py's_safewrapper, appears in every audit journal entry a write call produces, and is prefixed onto the server-side log line if the call fails - so one id lets you grep everything one tool call did, end to end, without changing the shape of any error message returned to the caller.Read retry.
path/ping/traceroute(every read primitive insrc/mcp_mikrotik/client.py) automatically retry on a transient network error - a fresh connection attempt failing, or an in-flight command failing because of an underlyingOSError(a dropped socket, a timeout) - with a short backoff (0.5s, then 1s). Up toMIKROTIK_READ_RETRIESextra attempts (default 2). A command rejected by RouterOS itself (aLibRouterosError, not anOSError) is never retried - it would just be rejected again. Writes never retry, regardless of this setting:update/add/remove/start/stoparen't guaranteed idempotent, so retrying one could duplicate or reapply a change.Circuit breaker. Each device gets its own in-memory, thread-safe breaker (
client.CircuitBreaker, one instance per pooledMikrotikClientsee
ClientPool). AfterMIKROTIK_BREAKER_THRESHOLDconsecutive connection failures (default 3), the circuit opens: for the nextMIKROTIK_BREAKER_COOLDOWNseconds (default 30), any call to that device - read or write - fails immediately with a clearcircuit open for '<device>', retry after <t>serror, without attempting a connection at all. A single successful connection resets the failure count and closes the circuit. This is scoped purely to the connection step - it never decides whether a write is allowed (that's the read-only gate/allowlist inguard.py, always checked first) - it exists to stop a dead device (e.g. an antenna that fell over) from costing a full connect timeout on every single tool call.
TLS verification for api-ssl
RouterOS's api-ssl typically serves a self-signed certificate, so the
default tls_verify: true (which validates against the system trust store,
or an explicit tls_ca_cert if given) will fail out-of-the-box for most
fleets. Two ways to make an SSL device work:
Set
tls_ca_cert: /path/to/ca.pemon the device entry, if you provision RouterOS with a certificate you can pin, keeping full verification.Set
tls_verify: falseon that specific device to skip certificate/hostname validation entirely. This is a deliberate, explicit, per-device trade-off (it drops MITM protection on that connection) - it is never the default, and it is opt-in per device, not global. Seedevices.yaml.example.
Development
pip install -e ".[dev]"
pytestThe test suite never talks to a real router: tests/fakes.py provides an
in-memory fake that implements the same minimal interface MikrotikClient
expects from a librouteros connection, and it is injected via a
client_factory parameter on build_server().
CI (.github/workflows/ci.yml) runs the full suite on every push/PR against
Python 3.11 and 3.12.
Roadmap / non-goals
Two write operations are deliberately not exposed yet, each because the standard guard/confirm/preview mechanism isn't sufficient protection on its own - see the comment above
ALLOWLISTinguard.py:Reboot (
system/reboot): there's no meaningful before/after preview for a reboot, and a bad batch reboot across a fleet has no dry-run or rollback. Needs its own confirmation/cooldown policy first.Firewall filter writes (
ip/firewall/filter): a single wrong rule (e.g. one that blocks the API port itself) can lock out all remote management access to the device, with no way to recover it over the same connection. Needs staged/rollback support (e.g. RouterOS safe mode) before it belongs in the allowlist.
Further write tools should be added by extending
guard.ALLOWLISTwith one new named operation and function each - see the comment block at the top ofguard.py. Do not add a generic write tool.A second entrypoint that periodically polls devices and pushes metrics to Firebase is planned to reuse
MikrotikClient/get_clientfromclient.py. Not implemented yet - see theTODO(collector)note at the bottom ofclient.py.
License
MIT - see LICENSE.
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
- 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/thalisantunes/mcp-mikrotik'
If you have feedback or need assistance with the MCP directory API, please join our Discord server