Agent documentation
Run local services through airmsh.
Add a server as a device, register its local database, MCP, or API service, then control access with an owner-managed policy.
Start here if the service is on your device and an approved person or tool needs to use it. For a private website or API address, follow the Endpoint guide. For a coding assistant, use the AI plugin guide.
Install the CLI
Use the Linux installer, then confirm its background service is running.
Bring the device online
Sign in with your own account and check that the server appears in Devices.
Register local services
Map a stable agent ID and tag to a database, MCP server, or HTTP API on this device.
Enforce a policy
The organization owner chooses callers, resources, actions, groups, limits, and sensitive-data behavior for this agent.
remote caller
-> authenticated user and source device
-> target device ID + agent tag
-> resource and action policy
-> request limits
-> destination-local service authentication
-> request PII handling
-> database, MCP, or API
-> response limits and PII handling
-> signed auditServer setup
Use an interactive password prompt. Never put an account password or access token in a shell command, service file, or log.
Install on a Linux server
First inspect the installer. It chooses and checks the right Linux build, keeps an existing login, sets up private device access, and enables the background service. Replace the email with your own account; enter the password only when prompted.
curl -fsSL https://airmsh.com/install-cli.sh | sudo sh -s -- --email you@example.comConfirm the installed build and active service below. The server should then appear online in Devices. For manual packages, use Downloads.
Check the background service
The installer enables airmsh-cli.service. If it could not prompt for a first login, sign in separately and start the service. Do not run another interactive tunnel at the same time.
sudo airmsh-cli --version
sudo systemctl is-active airmsh-cli
# Only if first login was skipped:
sudo airmsh-cli resource login you@example.com
sudo systemctl start airmsh-cliThe service should say active. If it does not, run sudo journalctl -u airmsh-cli -n 50 --no-pager to see the error.
Add agents
Run these commands on the destination server. Definitions are stored locally, and the running service reloads changes automatically. Local addresses and credentials stay on that server.
Databases
sudo airmsh-cli agent add db reports MongoDB mongodb://127.0.0.1:27017 analytics db:reports
sudo airmsh-cli agent add db cache Redis redis://127.0.0.1:6379 - db:cache
sudo airmsh-cli agent add db analytics MySQL mysql://127.0.0.1:3306 analytics db:analytics
sudo airmsh-cli agent add db warehouse Postgres postgres://127.0.0.1:5432 warehouse db:warehouse
sudo airmsh-cli agent add db cloud Neon postgres://ep-example.neon.tech/app app db:neon
sudo airmsh-cli agent add db local SQLite sqlite:///srv/app/data.sqlite - db:localUse filedb:///absolute/path.db as an alias for SQLite. Database passwords are configured separately and stored only on the destination device.
read -r -s -p 'Database password: ' AIRMSH_AGENT_SECRET; echo
export AIRMSH_AGENT_SECRET
sudo --preserve-env=AIRMSH_AGENT_SECRET airmsh-cli agent auth reports password reporter
unset AIRMSH_AGENT_SECRETMCP over HTTP
sudo airmsh-cli agent add mcp tools LocalMCP http://127.0.0.1:9000/mcp mcp:tools
sudo airmsh-cli agent pin toolsThe pin command records the approved MCP tool-schema digest. A later schema change is denied until the owner reviews and pins it again.
HTTP API bridge
sudo airmsh-cli agent add api python PythonAPI http://127.0.0.1:8080 api:pythonBind the local service to loopback. Remote clients route to the device and tag; they do not receive the loopback port or destination credentials.
# After exporting AIRMSH_AGENT_SECRET with the secure prompt above
sudo --preserve-env=AIRMSH_AGENT_SECRET airmsh-cli agent auth python bearer
# Other supported HTTP authentication
sudo --preserve-env=AIRMSH_AGENT_SECRET airmsh-cli agent auth python api-key X-API-Key
sudo --preserve-env=AIRMSH_AGENT_SECRET airmsh-cli agent auth python basic service-useragent listagent update ...agent delete <id>Run and test requests
On the calling device, connect to the destination device, open Agents, choose the agent shown under that device, and run one of these payloads. The app fills the signed-in user, source device, target device, and agent tag.
Where curl fits
Use curl on the destination device to confirm that a local HTTP service works before registering it. Airmsh then carries the same HTTP intent through its authenticated device channel.
# Run on the destination device
curl -i 'http://127.0.0.1:8080/users?limit=10' \
-H 'Accept: application/json'
# Equivalent Airmsh API-agent payload
{
"method": "GET",
"path": "/users",
"query": {"limit": 10},
"headers": {"accept": "application/json"}
}The response includes the status, content type, and body returned by the service. Test the local web address with curl; use Airmsh to reach it from another device.
MCP examples
Select protocol MCP. Use action tools/list to discover tools or tools/call to invoke one.
// List tools
{"method":"tools/list","params":{}}
// Call the ping tool
{
"method": "tools/call",
"params": {"name": "ping", "arguments": {}}
}Database examples
Select protocol Database and action query. The destination daemon converts the payload to the database’s native wire protocol.
MongoDB
{"command":{"ping":1}}Redis
{"args":["PING"]}MySQL
{"query":"SELECT 1 AS ok"}PostgreSQL / Neon
{"query":"SELECT current_database()"}SQLite / FileDB
{"query":"SELECT name FROM sqlite_master LIMIT 10"}Remote SDK request shape
The app creates this automatically. Integrations identify the destination device and agent; Airmsh checks their identity and permissions before opening the service.
{
"endpoint": "d-target-device.airmsh:51821",
"target_device_id": "target-device-id",
"agent_tag": "db:warehouse",
"protocol": "database",
"action": "query",
"resource_id": "local-database",
"payload": {"query": "SELECT 1 AS ok"}
}The full SDK request also includes the authenticated source identity. Copy those IDs from the signed-in device rather than inventing them. The destination verifies the source, target device, agent tag, action, resource, policy, and signature before execution.
Access policy
Only the organization owner can change an agent policy. Other members can use agents when allowed, but cannot edit these controls.
Always on
Base checks
Authenticated device-and-tag routing, payload bounds, and destination-local credentials apply before a service is called.
Owner enabled per agent
Enforced policy
Adds the selected callers, actions and resources, request limits, sensitive-data decisions, and audit checks for this agent.
Policy fields
Specific airmsh user IDs. Empty means any authenticated user in the tenant.
Device IDs allowed to originate the request. Empty means any tenant device.
Agent IDs allowed to call this agent. Empty means any authenticated source agent.
One or more tenant group IDs. A user may match through any listed group.
Roles such as operator or viewer that must match group membership.
Logical targets such as mysql-prod, local-mcp, or local-api.
Operations such as query, tools/call, request, read, or write.
Example: reporting agent may query production MySQL
Target device: server-device-id
Target agent: analytics
Allowed users: user-vineet-id
Source devices: laptop-device-id
Source agents: reporting-agent
Allowed groups: reporting-group-id
Group roles: operator
Resources: mysql-prod
Allowed actions: query
Requests per minute: 10
Concurrent requests: 2
Maximum rows: 1000
Maximum response: 10 MB
Execution timeout: 30 seconds
Sensitive data: maskOpen Agents, choose the destination agent, select Policy, enter these values, turn on Enforce policy for this agent, and save. Empty selector fields are wildcards, so fill user, device, group, resource, and action fields when access must be narrow.
What the policy checks
tenant
user
source device
source agent
group and group role
target device
target agent
resource
actionThe target device and target agent must match exactly. A network address is only a transport path and is never accepted as agent identity.
Verify the setup
airmsh> status
airmsh> devices
airmsh> agent listThe tunnel is running and the server device is online.
The destination service is listening only on 127.0.0.1.
The adapter appears in agent list with the expected ID and tag.
The calling device is connected and allowed by the destination policy.
An allowed action succeeds and a different user, resource, or action is denied.
The audit view records the source identity, decision, limits, and result.
Troubleshooting
Device is offline
A saved login is not a running client. Start airmsh-cli, enter online, and keep that process alive.
Agent is listed but unreachable
Confirm the local service is listening on loopback, its credentials are valid, and the CLI process that owns the adapter is still running.
Policy denies a valid user
Check the exact user ID, source device, source agent, group role, target agent, resource, and action. IDs are matched exactly.
MCP schema changed
Review the current tools and inputs on the destination server. If the change is expected, the tenant owner pins the new schema.
TUN permission denied
Verify cap_net_admin on Linux or start through the operating system administrator flow on desktop.
airmsh