MCP App Store
by KeenEthics

Overview

SentinelX lets you manage your Linux, macOS, and Windows servers from ChatGPT — no SSH required. Install a small open-source agent on any Linux, macOS, or Windows host, and ChatGPT can run inspection commands, manage services (systemd, launchd, or Windows services), read/search/edit files, run scripts, upload files, and call out to integrations like Cloudflare DNS, Resend, and Telegram. Every action is constrained by a per-host allowlist that you control. The agent only runs commands and services you've explicitly declared safe, rejects anything outside the policy at the agent boundary, and your OS's file permissions still apply on top. You can connect multiple hosts and label them however you want. Typical uses: check uptime and disk space, restart services, tail logs, edit config files, run quick scripts, manage DNS records, send notifications. The agent is open source on GitHub (github.com/pensados/sentinelx-cloud-core). Authentication uses OAuth 2.0 with PKCE and Dynamic Client Registration, scoped per user.

Tools

cloudflare_access_apps_list

ChatGPT
List the Cloudflare Access applications on an account. Read-only.

cloudflare_access_policies_list

ChatGPT
List the policies on one Cloudflare Access application. Read-only.

cloudflare_dns_create_record

ChatGPT
Create a new DNS record in a Cloudflare zone. Common types: A (IPv4), AAAA (IPv6), CNAME (alias), TXT (text), MX (mail). The proxied flag only applies to A/AAAA/CNAME and routes traffic through Cloudflare's edge. NOTE on TTL and proxied: if proxied=True, Cloudflare overrides the ttl to 1 ("auto") regardless of what you pass. This is documented Cloudflare behavior, not a bug. For non-proxied records, ttl can be 1 (auto) or 60..86400 seconds.

cloudflare_dns_delete_record

ChatGPT
Delete a DNS record from a Cloudflare zone. Destructive: the record is gone immediately and the deletion propagates through Cloudflare's network in seconds. Use cloudflare_dns_list_records first to confirm you have the right record_id.

cloudflare_dns_list_records

ChatGPT
List DNS records in a Cloudflare zone, optionally filtered. Use this to inspect existing records and to get the record id values needed by update_record and delete_record. Returns up to 100 records per call; if a zone has more, narrow down with the type or name filters.

cloudflare_dns_list_zones

ChatGPT
List every Cloudflare zone the saved token has access to. Use this first to discover zone IDs before listing or modifying records. The result includes each zone's id, name, status, and whether it's paused.

cloudflare_dns_update_record

ChatGPT
Partially update an existing DNS record. Change only the fields you pass; everything else stays as it was. This is a PATCH operation: omitted fields are left untouched. This is the safe semantic — "change proxied to true, leave the rest alone" — that matches how users think about edits. Use cloudflare_dns_list_records first to get the record_id. NOTE on TTL: if you set proxied=True (or the record is already proxied), Cloudflare will force ttl=1 even if you pass another value. To change ttl freely, the record must be non-proxied. To change the record's type or name (e.g. A -> CNAME), delete the record and create a new one — there's no in-place type change.

cloudflare_ruleset_get

ChatGPT
Read one Cloudflare ruleset with its rules. Read-only. Includes each rule's expression, which is where a match such as ip.geoip.country ne "FR" becomes visible.

cloudflare_rulesets_list

ChatGPT
List the rulesets on a Cloudflare zone: WAF, rate limiting, redirects. Read-only. Names the rulesets; the rules inside one come from cloudflare_ruleset_get.

cloudflare_security_events

ChatGPT
List recent Cloudflare firewall events on a zone, newest first. Read-only. Answers questions like "what was blocked for visitors from BE yesterday" without turning any protection off.

cloudflare_zone_settings

ChatGPT
Read the security-relevant settings of a Cloudflare zone. Read-only. Security level, challenge TTL, browser check, WAF and TLS.

compute

ChatGPT
Manage the lifecycle of cloud VMs through a saved compute integration. A single tool with an operation selector. Which cloud is driven comes from the integration's saved metadata.driver (currently 'digitalocean').

compute_destroy

ChatGPT
Destroy a VM and its disk. This cannot be undone. Without confirm=True it changes nothing and returns a summary: show it to the user, get their agreement, then call again with confirm=True.

compute_images

ChatGPT
List the operating system images a VM can be created from (slug).

compute_list

ChatGPT
List the VMs (droplets) in a saved compute integration's cloud account.

compute_power_off

ChatGPT
Power off a VM. Everything running on it stops until it is powered on again.

compute_power_on

ChatGPT
Power on a VM.

compute_regions

ChatGPT
List the regions a VM can be created in (slug and name).

compute_sizes

ChatGPT
List the VM sizes available, with monthly and hourly prices.

compute_snapshot

ChatGPT
Take a snapshot of a VM.

list_integrations

ChatGPT
List the saved integrations for the calling user. Use this when you need to know which integrations are available before calling a provider tool (telegram_send_message, resend_send_email, cloudflare_dns_*). All those tools take an integration_name; this is how to discover the valid names. Returns: { "ok": true, "items": [ { "name": "<user-chosen alias>", "provider": "cloudflare" | "telegram" | "resend", "created_at": "<ISO8601>" }, ... ], "count": <int> } The returned data deliberately does NOT include each integration's metadata (e.g. Telegram default_chat_id, Resend default_from) nor the encrypted credentials. Those are managed exclusively from the dashboard UI by the authenticated user, and the LLM cannot read or modify them via tools. If the user has no integrations, returns an empty list with count zero — not an error.

notifications_ack

ChatGPT
Clear an item from the notifications inbox once you have handled it. Clear only items you have read: clearing an unfamiliar job_id, or "all", could remove a result another conversation is still waiting for.

notifications_check

ChatGPT
List what you haven't seen yet: completed background jobs and announcements. Each completed job comes with a short summary, plus a count of jobs still running. The completed jobs it returns are marked as read, so a second call returns only what arrived since.

notifications_get

ChatGPT
Read one notification in full: a background job's result or an announcement.

resend_send_email

ChatGPT
Send a transactional or operational email via Resend. Use this for emails that need to land prolijo: deploy reports, backup summaries, certificate-expiry notices, weekly digests, invoices. For quick alerts where formality doesn't matter, telegram_send_message is faster to consume. The sending address (from_address) defaults to the integration's configured metadata.default_from. You can override it if the integration's API key has access to multiple verified domains and a particular send needs a specific one — but the domain MUST be verified in the Resend account this API key belongs to. The recipient list (to) is always passed in by the caller because email is, by nature, "send to whoever needs to read this." Unlike Telegram (where the bot has a small fixed set of reachable chats), email targets are open-world. At least one of html and text must be provided. If both are, Resend sends a multipart email and the client picks. Plain-text fallback is always good practice.

sentinel_agent_update

ChatGPT
Update a Linux host's SentinelX agent to the latest version, remotely. It runs the official installer with sudo and restarts the agent, which cuts calls in flight: run it when nothing important is in progress, and only with confirm=True. Needs passwordless sudo for the agent's user and script_run enabled; otherwise it stops before changing anything and says why. Linux only. On a failure it reports the stage and how to recover.

sentinel_capabilities

ChatGPT
Get SentinelX capabilities, including allowed commands and rich service definitions. Defaults to detail="summary" for a bounded discovery view (host/version, ops, limits, policy counts) without command/service values or playbook bodies. Pass detail="full" for the legacy full response. Requires agent >= 0.10.0; older agents ignore the selector and return the full response.

sentinel_chmod

ChatGPT
Change the mode bits of a path on the target host. The path must resolve under an rw file_ops entry.

sentinel_chown

ChatGPT
Change the owner and/or group of a path on the target host. The path must resolve under an rw file_ops entry. At least one of owner/group is required. Note: chown to a different owner normally requires root. The agent typically runs as a non-root service user, so this will usually fail with permission_denied — the agent reports that explicitly rather than pretending it worked. It is included for completeness and for the cases where the agent IS privileged.

sentinel_clear_default_host

ChatGPT
Remove the user's default host preference. After this, tool calls without an explicit host_id will fall back to the standard behavior: auto-route if only one host is connected, or ambiguous_host error if multiple are connected. Returns: {"ok": True, "removed": true|false}. removed=false means no default was set in the first place (no-op, not an error — the tool is idempotent).

sentinel_context_archive

ChatGPT
Archive a context: it stays searchable but leaves the active listings. Clears the conversations bound to it. Reversible with sentinel_context_reactivate.

sentinel_context_delete

ChatGPT
Permanently delete a context and all its revisions. This cannot be undone. Prefer sentinel_context_archive for normal cleanup.

sentinel_context_export_md

ChatGPT
Return a saved context as Markdown. It never writes files.

sentinel_context_list

ChatGPT
List saved contexts with compact metadata.

sentinel_context_reactivate

ChatGPT
Bring an archived context back to active and return its state.

sentinel_context_resume

ChatGPT
Restore a saved context's state to continue the work. It restores knowledge, not authorization: revalidate live host, service, Git and job state, and any human approval, before acting on it. Archived contexts are returned read-only; sentinel_context_reactivate brings one back.

sentinel_context_save

ChatGPT
Save operational state so the work can continue later, in this or another chat. Without context_id it creates a new context, and data needs title, objective and summary. With context_id it adds a new revision; pass base_revision (the revision you last read) so a concurrent change is not overwritten. Save concise operational state, never transcripts or secrets. To make a subcontext, set data.parent_context_id; data.related_context_ids links peers.

sentinel_context_settings_get

ChatGPT
Read your continuity preferences: when to save automatically, and Markdown mirroring.

sentinel_context_settings_set

ChatGPT
Change your continuity preferences. Pass only what you want to change.

sentinel_context_status

ChatGPT
Show which context, if any, is bound to this conversation.

sentinel_copy

ChatGPT
Copy a file or directory on the target host. BOTH src and dst must resolve under an rw file_ops entry. The destination is gated exactly like the source — otherwise copy would be an exfiltration primitive (read from an rw path, write the bytes anywhere). Directories are copied recursively.

sentinel_delete

ChatGPT
Delete a file or (with recursive=true) a directory. The path must resolve under an rw file_ops entry. The agent ALWAYS takes a backup before destroying anything: a file is copied to a sibling .bak.<timestamp>, a directory is archived to a sibling .bak.<timestamp>.tar.gz. If the backup cannot be made the delete is refused (backup_failed) — nothing is destroyed without a recovery path. Deleting a directory requires recursive=true explicitly. Without it, a directory is rejected with is_directory. This makes accidental rm -rf-shaped mistakes impossible to trigger by a single confused call.

sentinel_diagnose

ChatGPT
Check SentinelX's own records for the cause of a problem. Run it before filing a report. For a stall, a disconnect loop, a blocked call or an operation that keeps failing. It names the cause when the evidence is conclusive, with the actions to take, and often ends the matter without a report. A result of conclusion "inconclusive" with should_report true is a real answer: file the report rather than picking the nearest-looking cause. The evidence block is always returned.

sentinel_edit

ChatGPT
Edit a file on the connected host using safe, structured operations. Modes: - replace literal old -> new_text - regex pattern -> new_text - replace-block start_marker..end_marker -> new_text - append append new_text to file - prepend prepend new_text to file - write overwrite file with new_text For large content use the chunked variant: sentinel_edit_upload_init, sentinel_edit_upload_file, sentinel_edit_upload_complete. Security: path must resolve under a file_ops entry whose access is rw in the agent's config (the unified r/rw path model). A path that is only readable (access: r), or outside the allowlist, or that escapes it via ../symlink, is rejected with path_not_allowed — edit is a mutation and is gated exactly like move/copy/delete. This is enforced agent-side, after canonicalizing symlinks.

sentinel_edit_upload_complete

ChatGPT
Run the edit using files previously staged via sentinel_edit_upload_file.

sentinel_edit_upload_file

ChatGPT
Stage one role file for an edit upload session. Provide exactly one of content (utf-8 text) or content_base64 (binary). role must be 'old' or 'new'. Defaults filename to <role>.txt.

sentinel_edit_upload_init

ChatGPT
Initialize an edit upload session. Returns an upload_id to use in the follow-up calls (sentinel_edit_upload_file, sentinel_edit_upload_complete).

sentinel_exec

ChatGPT
Execute a command through SentinelX (must be in the allowed commands list). Set background=true for a long-running command: it returns a job_id immediately instead of blocking, and the result lands in the notifications pool — read it later with notifications_check. Under background the wall-clock ceiling is raised to 3600s. notify_telegram / notify_resend request a push when the job finishes (on success AND failure). Each accepts: - false (default): no push. - true: use your default integration of that type (errors if you have none, or several with no clear default — name one instead). - "<integration_name>": use that specific saved integration. Any notify_* implies background=true.

sentinel_file_upload_attachment

ChatGPT
Save one file the user attached in this conversation into a host, at target_path. For clients that pass attached files to tools (ChatGPT). In any other client, use sentinel_file_upload_link instead. target_path must be an absolute path to the file to create, inside a writable (rw) file_ops path of the host, and the agent's OS user must be able to write to that directory. An existing file is not replaced unless overwrite=true. Files of up to 512 MiB. SentinelX fetches the attachment from the client's file storage and streams it to the host; the bytes never go through the conversation. Returns the path, size and sha256. A large file may still be in transfer: then the result says in_progress and notifications_check shows the job when it is done.

sentinel_get_default_host

ChatGPT
Return the user's currently-configured default host (if any). The response carries both the stored host_id AND a flag indicating whether that host is currently connected, so the caller knows whether tool calls without explicit host_id will succeed. Returns: {"ok": True, "default_host_id": "<id> or null", "is_connected": true|false|null} is_connected is null when no default is set.

sentinel_git_apply_patch

ChatGPT
Apply one unified diff to a repository, all or nothing. The repository must be under a file_ops entry with access: rw. The agent checks the patch first; if it does not apply cleanly, nothing changes.

sentinel_git_clone

ChatGPT
Clone a Git repository into a new directory on the host. Refuses a destination that exists and is not empty, so it never writes into another tree. The destination must be under a file_ops entry with access: rw.

sentinel_git_diff

ChatGPT
Show a repository's current changes in one bounded, structured view. Read-only. Per-file status, insertion/deletion counts and the unified patch (within server caps), plus a summary. When a cap applies, truncated.files or truncated.patch is set.

sentinel_git_fetch

ChatGPT
Fetch from a Git remote: updates remote-tracking refs, never the working tree.

sentinel_git_ls_remote

ChatGPT
Read the refs a Git remote has right now, without a working tree. Read-only. Use it to learn the commit a branch is on before a forced push.

sentinel_git_push

ChatGPT
Push a branch to a Git remote. A forced push must pass expected_remote_sha, the commit you believe the remote branch is on: if someone pushed since you looked, the push is refused and nothing is lost. An unconditional force is not available on purpose.

sentinel_help

ChatGPT
Get the help section exposed by SentinelX capabilities. Defaults to the bounded topic="index" view. Selectors can drill into topic (e.g. "playbooks" or a help section), path (one exact leaf), or playbook (one playbook), with offset/limit paging where supported. Pass topic="all" for the legacy full response. Requires agent >= 0.10.0; older agents ignore the selectors and return the full response.

sentinel_list

ChatGPT
List entries in a directory on the target host. Output is structured (each entry has name/type/size/mtime), unlike sentinel_exec("ls -la") which returns opaque text. Always skips common noise directories (.git, __pycache__, node_modules, .venv, .pytest_cache, dist, build, etc.) regardless of show_hidden.

sentinel_list_hosts

ChatGPT
List the authenticated user's hosts: connected, offline and disabled. Each host entry includes: - host_id: stable unique id, generated at install time - hostname: system hostname reported by the agent at handshake - label: user-defined alias (null if none set; see sentinel_set_host_label) - session_id: internal session identifier (null for a host currently served by another hub worker) - connected_at: ISO timestamp of when the agent connected - agent_version: version reported by the agent - capabilities: ops the agent supports - operational: whether this host may currently RUN operations. A host that is connected but beyond the plan's active-host limit is listed with operational=false plus a "status" and "note" explaining why; tool calls routed to it return upgrade_required until a slot frees (disconnect/disable another host) or the plan is upgraded. The top-level "slots" block summarises the plan: limit, how many hosts hold an active slot, how many are parked, and how many slots are available. Other tools' host_id parameter accepts any of host_id, label, or hostname. Resolution priority is exact host_id -> label -> hostname. Enrolled hosts that are NOT connected are not part of hosts/count; they are listed apart, so a missing host is never mistaken for a deleted one: - offline: enrolled, currently disconnected, with last_connected_at. It moves back into hosts on its own when its agent reconnects. - disabled: refused at connect, with disabled_at and disabled_by ("user": disabled from the dashboard, re-enable it there; "admin": disabled by SentinelX support). There is no tool to re-enable a host. Operations cannot target offline or disabled hosts. Each group holds at most 20 entries, most recent first; offline_total / disabled_total appear when there are more. Returns {"ok": true, "hosts": [...], "count": N, "slots": {...}, "offline": [...], "disabled": [...]}; offline and disabled only when non-empty.

sentinel_local_api

ChatGPT
Talk to a tool on the host that already speaks a structured protocol. Use this instead of sentinel_exec when the target exposes a socket or JSON-RPC endpoint, because the answer comes back as data rather than as text meant for a terminal. Docker is the common case: State is the machine value "running" rather than something to infer from "Up 7 hours (healthy)", and ports are a structured list rather than a comma-laden string. Only endpoints and actions the host has declared are reachable. The host's config is the allowlist and neither the model nor the hub can widen it.

sentinel_mint_enrollment

ChatGPT
Connect a new host to this account: returns the install command with a one-time token. Use it whenever the user wants to add a server, including their first one when the account has no hosts yet, and for unattended provisioning. The returned install_hint has one command per OS (linux, macos, windows): give the user the one for their server's OS to run on that machine; the host appears once the agent connects. It creates nothing by itself and never touches an existing host. Do not use it to re-enroll an existing host that lost its credential. The token works once and expires; minting is rate-limited.

sentinel_move

ChatGPT
Move or rename a file or directory on the target host. BOTH src and dst must resolve under a file_ops entry whose access is rw in the agent's config. Resolving happens after canonicalizing symlinks, so .. traversal and symlink-escape are rejected. You cannot move data out of a writable subtree into a location the operator didn't declare.

sentinel_ping

ChatGPT
Simple health check (does not call SentinelX core internals).

sentinel_project_snapshot

ChatGPT
One-call deterministic project/repository orientation. Aggregates git + filesystem facts into a single bounded response so you don't need several read/list/search/exec(git ...) round-trips to orient in a repository: git state (branch, head, detached, dirty, ahead/behind), change stats (staged/unstaged/untracked, insertions/deletions), tracked-file count, top-level directories, and file-extension counts. Read-only. For a non-git but readable directory it returns a plain filesystem summary (kind="directory") instead of failing. The extension counts let you infer the project type yourself (e.g. many .kt + build.gradle -> Android/Kotlin) without a curated manifest list.

sentinel_read

ChatGPT
Read the contents of a file on the target host. The path must fall under one of the agent's configured file_ops.allowed_read_paths — directories like /etc/nginx, /var/log, /opt, etc. that the host's operator has chosen to expose. Paths outside that list, or path-traversal attempts via .., are rejected with path_not_allowed.

sentinel_read_media

ChatGPT
Read a media or binary file from a host as native MCP content. Use this instead of sentinel_read when the file is not text: images, PDFs and audio come back as content the model can actually look at or listen to, rather than as bytes or an unreadable transcription.

sentinel_remove_host_label

ChatGPT
Remove the label attached to a host. The host_id is unaffected; only the alias is forgotten. Returns {"ok": true, "removed": bool}.

sentinel_report

ChatGPT
Send SentinelX a bug report, a malfunction, a feature request or a suggestion. For problems that may be SentinelX's own; ordinary host or application failures are not, unless evidence points to SentinelX (use "malfunction" when ownership is unclear). Run sentinel_diagnose first. The host, agent version and timestamps are recorded from the session: do not send them. Keep observed facts separate from hypotheses, and never include secrets. The whole report must stay under 48 KB. To add to a report already filed, use sentinel_report_followup instead of filing it again.

sentinel_report_followup

ChatGPT
Add to a report already filed: answer a question, say whether a fix worked, add evidence. It reopens a closed report and puts it back in front of the SentinelX team. Do not file the same report again instead: a matching new report counts as another occurrence and its text is not kept.

sentinel_report_status

ChatGPT
Read a report's current state and the full exchange about it, oldest first.

sentinel_request_api_key

ChatGPT
Mint a short-lived REST API key and return it with a ready-to-use contract. Use this when a task is better done as a batch/aggregation loop than as many separate MCP calls -- e.g. grep a huge log and return only a count, check a metric across N hosts and report only the outliers, or a fetch->filter-> summarize pipeline. Mint a key, then curl `POST {base_url}/op` from your sandbox; only the final summary needs to re-enter your context. The key carries YOUR access, scoped down and short-lived. It is never more than you already have over MCP: every op still passes the target agent's allowlist, and every call is audited exactly like an MCP call. Treat it as a secret -- anyone holding it has that access until it expires.

sentinel_restart

ChatGPT
Restart an allowed service through SentinelX.

sentinel_script_run

ChatGPT
Run a one-off bash or python3 script on the connected host. The script content is written to a temporary workdir, executed, and (by default) cleaned up afterward. Set cleanup=False to keep the workdir for debugging — its path is returned in the response.

sentinel_service_reload

ChatGPT
Reload a service's configuration without a full restart, where the service supports it.

sentinel_service_start

ChatGPT
Start a service on a host.

sentinel_service_status

ChatGPT
Read a service's status: its full status, whether it is running, and whether it starts at boot. Read-only. Each part is returned as the agent answered it; a part this host's allowlist does not permit comes back as its own error, and the rest are still returned.

sentinel_service_stop

ChatGPT
Stop a service on a host. Whatever it serves is down until it is started again.

sentinel_set_default_host

ChatGPT
Designate host_id as the default target when host_id is omitted. After calling this, any tool that takes a host_id parameter will, if not given one explicitly, route to this host. Useful when you have multiple hosts connected and almost always work with one of them. The host_id must be the EXACT identifier (not a label or hostname). Use sentinel_list_hosts to discover available host_ids. We require the exact id deliberately — labels can be changed or removed, and hostnames can collide between hosts. The default should pin to a specific, stable identity. A default that points to a host which later disconnects is NOT an error at set-time; resolve_session will just fall back to ambiguous_host with a clear "your default is offline" message when the next tool call happens. To switch defaults, just call this again with the new host_id. To remove the default entirely, use sentinel_clear_default_host. Returns: On success: {"ok": True, "host_id": "<id>", "is_connected": bool}. The is_connected flag tells you whether your new default is actually online right now — useful feedback if you pinned a host that's currently offline.

sentinel_set_host_label

ChatGPT
Attach a human-friendly label (alias) to one of the user's hosts. The label can then be passed in any tool's host_id parameter as a convenient alternative to the long host_id. Labels are also surfaced in sentinel_list_hosts output.

sentinel_state

ChatGPT
Get SentinelX internal state.

sentinel_transfer_file

ChatGPT
Move a file directly between two hosts you've enrolled, without routing the bytes through this chat. Files up to 512 MiB are supported. The file streams source -> SentinelX hub -> destination one chunk at a time (the hub never holds the whole file, and it never goes peer-to-peer, so neither host needs an inbound port). The destination is verified by sha256 against the source before the transfer is reported complete.

sentinel_upload_chunk

ChatGPT
Send one chunk of a chunked upload. index is 0-based; chunks can be sent out of order — the agent reassembles by index when complete is called.

sentinel_upload_complete

ChatGPT
Reassemble all chunks into the target file. If sha256 is provided, the agent verifies the assembled file matches it. Cleans up temp data on success.

sentinel_upload_file

ChatGPT
Upload a file to the connected host's upload base directory. Provide exactly one of: - content_base64: file content inlined as base64 - file_url: an http(s) URL the agent will fetch target_path is relative to the configured upload base on the host (path traversal is rejected). Set overwrite=True to replace existing files.

sentinel_upload_init

ChatGPT
Begin a chunked upload. Returns an upload_id to use in upload_chunk and upload_complete. total_size is optional; if provided, the agent verifies the assembled file matches.

telegram_send_message

ChatGPT
Send a text message to a Telegram chat using a saved bot. The target chat is taken from the integration's stored configuration (metadata.default_chat_id), set by the authenticated user via the dashboard. This tool deliberately does NOT accept a chat_id parameter — the LLM cannot redirect messages to chats it picks. If you need to reach different chats with the same bot token, create one integration per target chat in the dashboard. Use this for operational notifications: "deploy finished", "backup failed", "container unhealthy", "user requested this summary". It is NOT a chat interface — the bot does not receive replies, and there is no inbound message handling.

Capabilities

Writes

Example Prompts

Click any prompt to copy it.

App Stats

90

Tools

3

Prompts

ChatGPT

Platforms

Works with

ChatGPT

Data refreshed daily