AppCrane
AppCrane
The self-hosted home for the apps your AI builds and your AI deploys.
Vibe-code an app with Claude Code or Cursor, then have your AI agent deploy it — over MCP — to a server you own. Docker isolation per app, SAML/OIDC SSO, per-user audit that distinguishes agents from humans, per-tenant data isolation, and a middleware hard-wall so the platform operator can't read your app secrets.
MCP-first. AI agents connect once via claude mcp add ... /api/mcp and operate the platform through 44 appcrane_* tools — create, deploy, read logs, set env, roll back. No curl, no separate scripts. appcrane_get_guide(topic="onboarding"|"operations") returns the current playbook on demand.
Why AppCrane
Tools for AI-built internal apps split cleanly along two axes, and one corner is empty:
Ungoverned | Governed | |
Vendor-hosted | v0, Bolt.new | Lovable, Replit, Retool, Superblocks — SSO and audit, but your app data, DB connections and API keys live on their multi-tenant cloud |
Self-hosted | Coolify, Dokku, CapRover, Dokploy — your infra, but no SSO, no RBAC, no per-user audit, no tenancy model | AppCrane |
You can have governance, or you can have your own infrastructure. Every other option makes you pick. That gap is the entire reason this exists — it was built for a company that needed both and found nothing that did both.
Why it matters now. Three things changed in 2026:
The bottleneck moved from writing software to operating it. In Anthropic's Claude Code study (~400k sessions), "operating software" — deploying, configuring, running pipelines — grew from 14% to 21% of sessions while fixing broken code fell from 33% to 19%. Non-engineers now ship deployable code within 7 points of professional engineers. The scarce thing isn't the app any more; it's somewhere safe to run it.
Shadow AI became measurable. The 2026 Verizon DBIR reports shadow-AI detections up 4×, AI use on corporate devices rising 15% → 45% in a year with 67% through non-corporate accounts — and source code as the most commonly submitted data type. Bans make it worse; a sanctioned platform is the answer that works.
Governance-by-console is the failure mode. Platforms that gate every app behind a human clicking through an approval UI stall once there are hundreds of apps. AppCrane's answer is different in kind: the agent drives the governed lifecycle over MCP, and the platform records and constrains it — rather than a person mediating each step.
Against self-hosted PaaS
Feature | AppCrane | Coolify | Dokploy |
Agent-first / MCP-native | ✅ | ~ thin | ~ 508 flat tools |
MCP rollback (undo, not just redeploy) | ✅ | ❌ | ✅ |
Enterprise SSO (SAML/OIDC/SCIM) | ✅ | ~ | ❌ paid tier |
Per-user audit, agent vs human attributed | ✅ | ~ | ❌ |
Per-tenant DB + storage isolation | ✅ | ❌ | ❌ |
Secret hard-wall (operator can't read) | ✅ | ❌ | ❌ |
Managed repo (no GitHub account needed) | ✅ | ❌ | ❌ |
Self-hosted, your infra | ✅ | ✅ | ✅ |
Open source | ✅ AGPL-3.0 | ✅ Apache-2.0 | ✅ Apache-2.0 |
Honest scope: Coolify has a far larger template marketplace, a bigger community, and multi-server orchestration. If you want one-click Postgres and 280 app templates, use Coolify. Choose AppCrane when the apps are AI-built, the agent should do the deploying, and you need to prove afterwards who did what.
Full matrix vs AWS Copilot / App Runner / Lightsail / CodeDeploy / Vercel → glick.run/comparison.html
Related MCP server: Nexlayer MCP
Features
Docker container isolation — every app runs in its own container; no shared dependencies, no runaway processes
Enterprise SSO — SAML 2.0, OIDC, and SCIM provisioning; connect to Okta, Azure AD, Google Workspace
Identity forwarded to apps as headers —
X-AppCrane-User-Role,X-AppCrane-App-Role, etc. are injected by the proxy afterforward_authverifies the user; deployed apps read identity directly off the request without a callback (oauth2-proxy / IAP pattern)/api/meendpoint — canonical "who is the caller" for proxied apps; accepts thecc_tokencookie, Bearer, orX-API-Key; returns global role + per-app role (?app=<slug>orReferer-inferred)Headless app type — set
auth_mode: 'headless'to bypassforward_authentirely on an app; right tool for telemetry ingest, public webhooks, status pages, and single-purpose unauthenticated servicesTCP (layer-4) ingress — for apps that aren't HTTP at all (a forward/CONNECT proxy hands back a raw tunnel no reverse proxy can express), a platform admin can publish the container's port directly on the host, with Caddy out of the path. No SSO, no identity headers, no TLS from AppCrane — the app owns authentication completely
AppStudio AI pipeline — AI proposes code improvements on a schedule; you review and approve before anything ships
Real-time presence — see who's active on each app, which environment, and when they last deployed
Dual environments per app: production + sandbox, always-on, separate ports
Auto-HTTPS via Caddy reverse proxy with Let's Encrypt
GitHub webhook auto-deploy on push (HMAC-verified)
Zero-downtime deploys (start new, health check, swap, drain old)
Rollback in seconds (symlink-based, keeps last 5 releases)
Encrypted env vars (AES-256-GCM) — admin cannot read them by design
Health checks with auto-restart and email notifications
Audit log for every action
MCP server at
/api/mcpexposing 44appcrane_*tools — agents operate the platform without ever touching curl, gh, or shell
Quick Start
One command on a fresh Ubuntu server installs and wires up everything — Node, Caddy (with automatic HTTPS), Docker, the systemd service, an encrypted-secrets key, and your admin user:
curl -fsSL https://raw.githubusercontent.com/gitayg/appCrane/main/install.sh | sudo bashIt prompts for just two things — your domain and admin email — and is safe to re-run. When it finishes, point your domain's DNS at the server and you're live.
Prerequisites: a fresh Ubuntu server (root / sudo) and a domain whose DNS A
record points at it — Caddy provisions TLS automatically on first request.
Non-interactive (CI / automation) — no prompts:
sudo CRANE_DOMAIN=crane.example.com ADMIN_EMAIL=admin@example.com bash install.sh
# flags also work: --domain / --admin-email / --admin-name / --tls-cert / --tls-keyEverything below is done for you, idempotently, by the one command above:
Node.js 20 + AppCrane, with the
craneCLI linked globallyCaddy — the reverse proxy that routes
<domain>/<slug>to each app, runs the SSO auth, injects theX-AppCrane-*identity headers, and auto-provisions TLS — plus the group, file permissions, and asudoersrule so AppCrane can reload Caddy on every deployDocker + a systemd
appcraneservice (Restart=always— survives crashes and reboots, and powers one-click self-update)A
.envwith a freshly generatedENCRYPTION_KEY— back this up; losing it makes every stored secret unrecoverable — and your admin user (crane init)
Installing by hand means reproducing all of that — especially the Caddy install +
permissions + sudoers, which is the most-missed step and later surfaces as
permission errors or apps that never receive their identity headers. If you must,
treat install.sh as the source of truth rather than a shortened list.
AppStudio (optional): to enable AI app-building, set an Anthropic API key —
systemctl edit appcrane --force, addEnvironment="ANTHROPIC_API_KEY=sk-ant-..."under[Service], thensystemctl daemon-reload && systemctl restart appcrane.
Deploy your first app
The installer already created your admin user, so once DNS points at the box:
# Reachable at https://<your-domain>/myapp
crane app create --name "MyApp" --slug myapp --repo https://github.com/yourorg/myapp
crane deploy myapp --env sandbox
# Give a teammate access (optional)
crane user create --name sarah --email sarah@example.com
crane app assign myapp --email sarah@example.comCLI Reference
Server
crane status # Server health: CPU, RAM, disk, apps
crane config --show # Show CLI config
crane config --url http://localhost:5001 # Set API URL
crane config --key dhk_admin_xxx # Set API key
# Recover a lost platform-owner API key (run on the box, direct DB).
# Defaults to the platform_admin; override to target a specific account:
crane regenerate-key # Regenerate the platform owner's key
crane regenerate-key --email you@ex.com # ...for a specific user by email
crane regenerate-key --user-id 1 # ...or by user idMigrate config between instances
Move the platform settings (including encrypted secrets) to another AppCrane —
without sharing encryption keys. Export keeps secrets ciphertext; import
re-encrypts them with the target instance's own key.
# On the SOURCE instance:
crane config export --out config.json
# Copy config.json to the TARGET, then on the TARGET:
OLD_ENCRYPTION_KEY=<source ENCRYPTION_KEY> crane config import config.jsonThe source ENCRYPTION_KEY (from the source's .env) is needed only to decrypt
the secrets during import; it is used transiently, never stored. One-way values
(e.g. the SCIM token, stored as a hash) can't be migrated — the import lists them
to regenerate on the target. Delete config.json afterward.
Apps (admin)
crane app list
crane app create --name X --slug x --domain x.example.com --repo https://github.com/...
crane app info myapp
crane app delete myapp --confirm
crane app assign myapp --email user@example.comDeploy (app user)
crane deploy myapp --env sandbox
crane deploy myapp --env production
crane deploy:history myapp --env prod
crane deploy:log myapp --id 5
crane rollback myapp --env production
crane promote myapp # sandbox → production, zero downtimeEnv Vars (app user — admin cannot access)
crane env set myapp --env sandbox DATABASE_URL=postgres://... API_KEY=sk-test
crane env list myapp --env production
crane env list myapp --env sandbox --reveal
crane env delete myapp API_KEY --env sandboxHealth, Webhooks, Backups
crane health status myapp
crane health config myapp --env prod --endpoint /api/health --interval 30
crane webhook myapp --auto-sandbox on
crane backup create myapp --env prod
crane backup list myapp
crane logs myapp --env production
crane audit --app myappMCP (for AI agents)
AppCrane is MCP-first. One claude mcp add and the agent gets 42
appcrane_* tools — list apps, deploy, set/get secrets, read logs,
manage access, rotate icons, the lot. Tool names are AWS-aligned
(stage, set_secret/get_secret, cp).
claude mcp add --transport http appcrane https://crane.example.com/api/mcp \
--header "X-API-Key: dhk_admin_or_user_xxxxxxxxxxxxx" \
--header "X-Github-Token: ghp_your_github_pat"Then in any Claude Code session:
Onboard a new app. Start by calling
appcrane_get_guidewithtopic="onboarding"for the playbook.
The agent pulls the current guide from the server, so edits propagate
without a redeploy of your tooling. topic="operations" returns the
post-onboarding reference (deploy lifecycle, troubleshooting fast
failures, access management, etc.).
Architecture
Ubuntu Server
├── Caddy (reverse proxy, auto-HTTPS)
│ ├── myapp.example.com → production app
│ └── myapp-sandbox.example.com → sandbox app
├── Docker (container isolation)
│ ├── myapp-production ← isolated container per env
│ └── myapp-sandbox
├── AppCrane API (:5001)
│ ├── Express 5 + SQLite
│ ├── Health checker (cron)
│ ├── SSO (SAML / OIDC / SCIM)
│ ├── AppStudio AI pipeline
│ └── Presence (WebSocket)
└── /data/apps/myapp/
├── production/releases/ (symlink-based, last 5)
└── sandbox/releases/Every container is published to loopback only (127.0.0.1:<port>:3000), so
Caddy is the only way in. The one exception is a TCP-ingress app, which
additionally publishes its container port at 0.0.0.0:<public_port> — outside
Caddy, and outside every control Caddy provides. See
§6 below.
Security
Init locked to localhost — admin setup only from the server itself
API key auth — all requests require
X-API-KeyheaderAdmin isolation — admin cannot read env vars or
/data/; enforced at middleware levelAES-256-GCM encrypted env vars at rest
Webhook HMAC verification for GitHub
SCIM deprovisioning — removing a user from your IdP revokes AppCrane access automatically
All actions audited — who did what, when
Supply chain — SBOM + build provenance
A deployment self-updates straight from git (/api/self-update runs git fetch
git reset --hard origin/main), so the question a reviewer asks is "how do I know the source I pulled is the source you published?" Every tagged release answers it with four attached artifacts:
Artifact | What it is |
| Reproducible |
| CycloneDX SBOM of the production dependency tree |
| Same, SPDX format |
| Checksums for all of the above |
The source archive carries build provenance and an SBOM attestation signed via sigstore keyless (GitHub artifact attestations) — no long-lived signing key exists to be stolen. Verify a downloaded archive with:
gh attestation verify appcrane-<tag>-source.tar.gz --repo gitayg/appCraneDev dependencies are deliberately excluded from the SBOM — they aren't shipped to a deployment, and including them would overstate the real attack surface.
Identity contract for deployed apps
Apps deployed on AppCrane never need to implement their own auth. The Caddy proxy verifies every request against /api/identity/verify before forwarding it to the container, and the result is delivered to the app in three complementary ways. Apps should consume them in this precedence order:
1. Request headers (zero-fetch, recommended)
Caddy copy_headers the verified identity onto the upstream proxy request. The app reads them directly:
Header | Value | Notes |
|
| Always present on every proxied request, including ones with no identity. Read it first. |
| Backward-compat single identifier. Set on | |
| numeric id (string) | Set on |
| Granular. May be absent if the user has no email. | |
| display name, |
|
|
| Platform-wide tier, raw token. Not a per-app permission. |
|
| Per-app role — the one to gate on. An explicit |
|
|
|
| comma-separated keys, e.g. | The roles the app defines for itself — a different system from |
Trust model: the Caddy generator wraps the request_header -X-AppCrane-* strips and the forward_auth block in a route { … } so they execute in written order — Caddy's own directive sort would otherwise run the strips after forward_auth and delete the identity it had just copied. Caddy zeroes out any client-set X-AppCrane-* headers first, then copy_headers re-injects only what /verify returned. The strips are emitted on every route that proxies an app, including headless apps and auth_bypass_paths prefixes where no forward_auth runs at all — a route that verifies nobody must not accept the caller's own X-AppCrane-Is-Admin. Header smuggling is impossible — what the app receives is guaranteed platform-issued. Caddy also strips the platform's cc_token session cookie out of Cookie before it reaches any container (v2.39.0), so an app can't read a visitor's platform session and act as them — apps must take identity from these headers, never from a cookie.
Identity does not require SSO. /api/identity/verify resolves a session from X-API-Key or from Authorization: Bearer / the cc_token cookie against identity_sessions. SSO is one way to create such a session; local password login and API keys are others. An instance with no IdP still injects the full header set for logged-in users.
Absence semantics: on an authenticated app an unverified visitor never reaches the container at all (Caddy fails closed at forward_auth and redirects to /login), so presence = trusted. Identity legitimately absent means X-AppCrane-Auth-Mode is headless (whole app opted out) or bypass (this path is in auth_bypass_paths, or the app is served on its own custom domain) — in every case the request is served with no verified identity and the app owns its own authn. No X-AppCrane-Auth-Mode at all means the request didn't come through AppCrane's proxy — i.e. direct-to-container. A custom-domain app is proxied and does get X-AppCrane-Auth-Mode: bypass.
Role ordering: none < viewer < user < admin < owner. appRole === 'admin' is a bug — it denies owners.
// Express example
const RANK = { none: 0, viewer: 1, user: 2, admin: 3, owner: 4 }
const atLeast = (appRole, min) => (RANK[appRole] ?? 0) >= RANK[min]
app.use((req, res, next) => {
const mode = req.get('X-AppCrane-Auth-Mode') // 'authenticated' | 'headless' | 'bypass'
const role = req.get('X-AppCrane-User-Role') // platform tier
const appRole = req.get('X-AppCrane-App-Role') // 'owner' | 'admin' | 'user' | 'viewer'
const email = req.get('X-AppCrane-User-Email') || req.get('X-AppCrane-User')
req.user = (mode === 'authenticated' && role)
? { id: req.get('X-AppCrane-User-Id'), email, role, appRole, isAppAdmin: atLeast(appRole, 'admin') }
: null
next()
})2. GET /api/me (when you need more than the basics)
Returns the full user object — name, email, username, global role — plus the per-app role for whatever app the caller is asking about. Same origin as the app, so the browser auto-sends cc_token; no SDK or token plumbing required:
const r = await fetch('/api/me') // ?app=<slug> optional; Referer-inferred otherwise
if (r.status === 401) { location.href = '/login?redirect=' + encodeURIComponent(location.href); return }
const { user, app_role } = await r.json()Auth precedence inside /api/me:
cc_tokencookie (proxied apps' default —httpOnly, browser-managed).Authorization: Bearer <session>(CLI / programmatic).X-API-Key: dhk_*(admin / agent keys).
App slug resolution:
Explicit
?app=<slug>query.Referer-inferred (first path segment; sandbox-suffix retry).Lean global-only payload if neither resolves.
3. Headless apps — opt out entirely
For services where the whole app is meant to be unauthenticated — telemetry ingest, public webhooks, status pages, the squash CLI's ping/stats — set the app's auth_mode to headless (owner-only toggle in the Launcher, or appcrane_set_app_meta slug=<…> auth_mode=headless via MCP). The Caddy block then skips forward_auth and copy_headers: no identity headers, no /api/me, no cc_token (that cookie is stripped for every app regardless). The incoming X-AppCrane-* strip is not skipped — a headless route verifies nobody, so it must not let a caller supply its own identity headers either. X-AppCrane-Auth-Mode: headless still arrives, so the app can distinguish "identity is off by design" from a misconfigured proxy. The app's own server takes responsibility for any payload-level authn it needs (HMAC, install-id, IP allowlist, etc.).
Pick by shape:
The whole app is unauth ingest → headless app (clean separation, smaller blast radius).
Mostly-auth app with a couple of public endpoints → keep
authenticated, gate the public paths at the app's own router.
4. Per-tenant DB (multitenancy) — opt in
Opt in with "multitenant": true in deployhub.json and AppCrane gives each of
your app's users an isolated SQLite database on the persistent /data volume —
you don't build tenant isolation yourself. A tenant is (org, user), where
org is the user's email domain. This is fully opt-in: apps that don't set
the flag are completely unaffected.
When enabled, AppCrane injects APPCRANE_TENANT_ROOT=/data/tenants. Use the
appcrane-tenant helper to derive the tenant DB from the
identity headers above (section 1) — no path-building by hand:
import { tenantDb } from 'appcrane-tenant'
app.get('/api/notes', (req, res) => {
const db = tenantDb(req) // opens /data/tenants/<org>/u<userId>/db.sqlite
res.json({ notes: db.prepare('SELECT * FROM notes').all() })
})tenantDbPath(req) returns just the path if you use a different SQLite driver.
Each tenant also gets a storage/ dir (tenantStorageDir(req) / tenantFile(req, name))
for files. Set "tenant_quota_mb": <n> in deployhub.json to cap per-tenant
usage — AppCrane injects it and assertTenantQuota(req) throws once a tenant is
full (the quota covers DB + storage).
Always build tenant paths via the helper (never from raw user input) — the
identity headers are platform-signed and the org slug is sanitised against
traversal. When a user's access is revoked, AppCrane purges that tenant's dir
automatically. Consumer domains (e.g. gmail.com) share an org label, but
isolation is per-user, so data never mixes. The helper isn't on npm yet — copy
packages/tenant/index.js or depend on it by path;
see the multitenant-notes example.
5. App-defined roles — the app's own vocabulary
An app can define roles of its own — approver, auditor, reviewer — and
AppCrane hands each user's set to the app on every request. AppCrane is the
authority, the app is the enforcer: the platform stores who holds which key and
issues it, and has no opinion on what the key permits.
The two are separate systems on purpose, down to separate tables and separate
wire fields. An app-defined role never confers an AppCrane privilege, and no
AppCrane authorization check reads one — otherwise an app owner could invent a
role named admin, assign it to themselves, and author their own escalation from
a settings form. For the same reason owner, admin, user, viewer, none
and platform_admin are rejected as keys, keys must match
/^[a-z][a-z0-9_-]{0,31}$/, and an app may define at most 16 of them (which also
bounds the header's length by design rather than by discovery).
On the server:
X-AppCrane-App-Roles, comma-separated and sorted, absent when the user holds none. A user may hold several — they are a union, so test set membership rather than equality. It is stripped off the client request and re-issued by/verifylike every other identity header.In the browser:
GET /api/me?app=<slug>returnsapp_roles: [...]besideapp_role([]when none).Explicit grants only. A
platform_adminholds no app-defined role unless someone granted it, and neither does the app'sowner— unlikeapp_role, there is no global-admin fallback. Holding an app role while being a plain platformuseris the normal case, not an edge case.Managed by the app's own owner/admin tier, over
/api/apps/<slug>/app-roles(note: not/roles, which is the platform tier) or theappcrane_list_app_roles/appcrane_create_app_role/appcrane_set_user_app_rolesMCP tools. Deleting a role cascades its grants.
const appRoles = new Set((req.get('X-AppCrane-App-Roles') || '').split(',').filter(Boolean))
if (!appRoles.has('approver')) return res.status(403).json({ error: 'approver role required' })6. TCP (layer-4) ingress — no proxy, no identity
Sections 1–5 all rest on the same assumption: Caddy is in front of the app. Some
apps aren't HTTP and cannot be proxied at all — the motivating case is a
forward/CONNECT proxy, where the client opens a raw TCP connection and gets a
tunnel back, which no HTTP reverse proxy can express. For those, a platform
admin (not the app owner) can set ingress_type: 'tcp' — PUT /api/apps/<slug>
or appcrane_set_app_ingress — and AppCrane publishes the production container's
port on the host at 0.0.0.0:<public_port>, from a dedicated 31000–31999 range,
the next time the container is recreated (a deploy, or the restart route — the
publish is a docker run flag, so nothing changes on a running container). The
existing loopback publish stays and sandbox is unaffected; this adds a door
rather than moving one.
The container must still answer /api/health over HTTP, whatever its
ingress_type: the deploy gate polls it for 30 s and rolls the release back
without a 200 carrying status and version. So tcp ingress serves apps that
also speak HTTP on the container port — true of the motivating CONNECT proxy —
and an app speaking only a non-HTTP protocol cannot be deployed today. Note
too that the publish covers the whole container port, so every HTTP route on it,
including that health endpoint and any admin route, is exposed alongside the raw
protocol.
That door has none of the controls above, and none of the ones AppCrane
gained in v2.35–v2.41: no forward_auth, no X-AppCrane-* identity headers
(nothing injects or strips them), no per-request audit, no rate limiting, no
security headers, and no TLS terminated by AppCrane. The app owns
authentication completely. It is not auth_mode: 'headless' — a headless app
still goes through Caddy and still gets TLS, security headers and the
X-AppCrane-Auth-Mode: headless stamp.
An app on a published port can still authenticate against the platform if it
chooses to: GET /api/me?app=<slug> verifies a Bearer token or X-API-Key: dhk_*
the client supplied, and POST /api/service/* authenticates the app itself with
the APPCRANE_SERVICE_TOKEN injected into every container. Both go over the
docker bridge (CRANE_INTERNAL_URL), not through Caddy.
public_port is allocated and stored per app (never derived from the app's slot,
which can be reassigned), unique across apps, and every change is written to the
audit log as app-ingress-change. Treat publishing as the exposing act — do
not assume a host firewall is holding the port shut. A Docker publish is a DNAT
rule evaluated in FORWARD that never traverses INPUT, so a plain ufw deny
does not block it; filter in the DOCKER-USER chain or upstream of the host.
And where the platform runs behind SDP, the boundary that exists is the
perimeter: a published port is reachable by everything inside it from the moment
the container is recreated.
Switching back to http stops the publish but does not close the port: the
running container keeps the binding until it is recreated, so redeploy or restart
the app before treating the exposure as revoked. Because that port is still bound,
AppCrane keeps it reserved to that app rather than returning it to the pool —
no other app can be allocated a number a live container still holds — and releases
it automatically when the container comes back without the publish. Until then the
app reports the number as pending_port_release on every read surface, so nothing
claims the port is closed while it is open.
For a CONNECT proxy specifically: a published port is reachable by everything that
can already reach the host, so on an SDP-fronted deployment that is everyone inside
the perimeter rather than the internet. A gap in the app's proxy authentication is
therefore an unaudited egress path out of the perimeter, and AppCrane logs none
of it because the traffic never touches Caddy. The app's 407 Proxy-Authenticate
path is the security boundary — the ingress isn't.
Permission Model
Action | Admin | App User |
Create/delete apps | Yes | No |
Assign users | Yes | No |
Server health | Yes | No |
Deploy / rollback / promote | No | Yes (own apps) |
View/edit env vars | No | Yes (own apps) |
Configure health/webhooks | No | Yes (own apps) |
Backups | No | Yes (own apps) |
Tech Stack
Node.js 20, Express 5, SQLite, Docker, Caddy 2, SAML/OIDC/SCIM, AES-256-GCM, Commander.js, Ubuntu 22.04+
License
GNU AGPL v3. Free and open source — use, modify, and self-host. If you run a modified version as a network service, you must make your source available under the same license. Need to run private modifications as a service, or embed AppCrane in a proprietary product? A commercial license is available.
Feedback & Contributions
Open an issue: https://github.com/gitayg/appCrane/issues
Pull requests welcome — please read CONTRIBUTING.md first. It includes the short CLA that keeps AppCrane's dual-licensing (AGPL + commercial) possible.
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 Servers
- Alicense-qualityDmaintenanceA hosted AI software engineer that writes code, opens PRs, reviews code, generates tests, runs security scans, and answers codebase questions. Connect from any MCP client (Claude Code, Cursor, Windsurf, or your own agents) and delegate engineering tasks.67MIT

Nexlayer MCPofficial
Flicense-qualityCmaintenanceAgentic cloud platform with 45+ MCP tools. Deploy any containerized stack, debug live pods (shell, file editing, DB queries), manage custom domains & TLS, push to built-in container registry, scale pods, and manage GPU workloads. The infrastructure layer where AI agents ship software to production.8
mcpgateofficial
Flicense-qualityAmaintenanceSelf-hosted MCP gateway that connects Claude, ChatGPT, and other AI agents to 20+ enterprise tools (GitLab, Jira, Notion, Google Workspace, Slack, Grafana, …) with OAuth, audit logs, and zero data leaving your infrastructure- Alicense-qualityBmaintenanceGives AI coding agents (Claude Code, Cursor, etc.) unified, secure access to dev infrastructure (Vercel, GitHub, Supabase, Cloudflare, GCP) via a single MCP token.MIT
Related MCP Connectors
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Self-hosted MCP gateway: turn any API, database or MCP server into AI connectors — no code.
Enterprise AI Control Plane: governance, guardrails, spend tracking, compliance & smart routing.
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/gitayg/appCrane'
If you have feedback or need assistance with the MCP directory API, please join our Discord server