tenki_whoami
Return the identity and workspaces for the current API key. Cheap credential test.
Takes no parameters.

io.github.LuxorLabsPublished by GitHub account LuxorLabsv0.3.1Updated Oct 30, 2026
Disposable microVM sandboxes for AI agents: run code, read/write files, git, preview URLs.
Gives an assistant disposable Tenki Cloud microVM sandboxes to run code, manage files and git, and publish preview URLs.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Follow the launch instructions in the repository.
@tenkicloud/mcpA Model Context Protocol server for Tenki Cloud. Give any agent — Claude, Codex, Cursor — a disposable microVM it can create, run code in, read and write files, run git, and expose to the web. Sandboxes boot in ~2 seconds and are billed per second.
Part of making Tenki the execution layer coding agents reach for: the agent writes code and Tenki runs it in isolation. (Tenki's Code Reviewer and Runners — AI PR review and managed CI — are separate products; this server currently exposes the Sandbox.)
Nothing to clone or build. The package installs one command, tenki-mcp.
Connect to Tenki's hosted MCP service and sign in with your Tenki account:
Claude Code's mcp add command stores the server configuration; mcp login performs the one-time browser authorization and workspace selection.
Alternatively, run the MCP server locally with an API key:
The repo doubles as a plugin marketplace. This prompts for your API key on install and stores it in your OS keychain — no env var to manage:
Add to claude_desktop_config.json:
Add the same block to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):
The OpenAI Codex CLI reads MCP servers from ~/.codex/config.toml. Add:
After adding the server, start a fresh session so the client loads it, then ask your agent one of:
print(2+2) in a fresh Tenki sandbox." — a full boot → run → teardown round-trip.If the tenki_* tools don't show up, restart the client so it re-reads its config.
No key yet? Start the server without one and ask the agent to check tenki_auth_status — it reports what to set and where. See Auth.
For development, or to run an unreleased change:
Substitute node /absolute/path/to/tenki-mcp/dist/index.js for the npx command in any of the configs above. See CONTRIBUTING.md for the full development loop.
71 tools — all 68 public unary API methods (enforced by a CI parity audit), two workflow helpers, and tenki_auth_status. Implementation-only control-plane methods are intentionally excluded. Grouped by domain:
Full per-release breakdown in CHANGELOG.md.
Set one of TENKI_API_KEY or TENKI_AUTH_TOKEN — when both are set, TENKI_AUTH_TOKEN wins. The header is chosen by token prefix: tk_… → Authorization: Bearer, ory_st_… → X-Session-Token, otherwise a session cookie. Override the endpoint with TENKI_API_ENDPOINT (default https://api.tenki.cloud).
Without a credential the server still starts, registering only tenki_auth_status — so instead of an MCP client reporting an opaque "server failed to start", the agent can call that tool and get told what to set. Ask it "check tenki auth status" any time other tools return auth errors: it reports the credential kind (API key vs session token), the endpoint, and whether a live identity probe succeeded — never the token itself. It reports status only; get a credential with tenki login or from the dashboard.
Besides stdio, the server speaks Streamable HTTP so it can be hosted for remote MCP clients:
For a single-user deployment, HTTP mode can hold one shared TENKI_API_KEY and therefore exposes a powerful capability. By default it:
127.0.0.1) only — set TENKI_MCP_HTTP_HOST=0.0.0.0 to expose it, but thenTENKI_MCP_HTTP_TOKEN and send Authorization: Bearer <token>. It refuses to start on a non-loopback host without one.Point an HTTP-capable MCP client at /mcp. Static-key mode uses one shared TENKI_API_KEY for all sessions. Verified end-to-end (test/http-transport.test.mjs: auth gate, DNS-rebinding rejection, connect → tools/list → tool call over HTTP).
Hosted multi-tenant deployments instead use Tenki Identity's OAuth facade. The MCP server publishes RFC 9728 protected-resource metadata and exchanges each caller's access token through the private Identity service. Identity owns Hydra, validates the requested audience and scope, and issues a short-lived API delegation bound to the user, client, and workspace selected on the Tenki consent page. tenki-mcp has no Hydra Admin access and does not hold the delegation-signing secret.
Tenki's API is ConnectRPC — JSON over HTTP/1.1, not REST. Every control-plane call is POST https://api.tenki.cloud/tenki.sandbox.v1.SandboxService/{Method} with a lowerCamelCase JSON body. Per-session file I/O runs on a separate data-plane endpoint returned at create time, authenticated with a short-lived session certificate. This server owns both transports so the tools stay one-liners.
Command output: tenki_exec and tenki_run_code capture stdout/stderr by redirecting to files (sh -c '… > out 2> err') and reading them back over the data plane, so you get the output inline through a plain HTTP client.
The wire details are ported from the live-verified n8n community node.
This server holds a Tenki API key and can run code + spend credits, so treat it as a capability. Full model + CSA MCP Server Top-10 mapping in SECURITY.md. Quick controls:
readOnlyHint / destructiveHint). Run TENKI_MCP_READONLY=1 for an inspection-only server (read tools only), or TENKI_MCP_DISABLED_TOOLS=tenki_run_code,… to drop specific tools.TENKI_MCP_AUDIT=1 logs each tool call's name to stderr.tenki_run_code/tenki_exec/tenki_read_file return output from untrusted code — clients should treat tool results as data, not instructions.Report vulnerabilities via a private security advisory, not a public issue.
MIT
Source: README.md at commit 8199be4
Return the identity and workspaces for the current API key. Cheap credential test.
Takes no parameters.
Boot a throwaway microVM, run a snippet (shell/python/javascript), return its stdout/stderr/exit code, and tear the sandbox down. Cost-guarded and self-terminating. Use this for one-shot execution when you don't need a persistent sandbox. Output over ~64KB per stream is truncated head+tail — and the sandbox is gone, so for large output use tenki_create_sandbox + tenki_exec and page through the retained file.
envcoderequiredlanguagerequiredtimeout_secondsCreate a persistent sandbox microVM, optionally from a snapshot or template image. Returns the session (id, state) and its data-plane endpoint. Boots in ~2s. Use tenki_exec / tenki_read_file / tenki_write_file against the returned session_id.
envnametagsimagecpu_coresmemory_mbwait_readysnapshot_iddisk_size_gbworkspace_idallow_inboundallow_outbound+3 moreFetch a sandbox's current state and metadata.
session_idrequiredList sandboxes for the workspace.
page_sizepage_tokeninclude_terminatedTerminate (destroy) a sandbox. The microVM and its filesystem are gone after this.
session_idrequiredPause a sandbox (snapshot + suspend) so it can be resumed later.
session_idrequiredResume a previously paused sandbox.
session_idrequiredExtend a running sandbox's wall-clock lifetime by N seconds so it isn't auto-terminated at its max-duration cap.
session_idrequiredadditional_duration_secondsrequiredUpdate mutable fields on an existing sandbox — its name, tags, idle timeout, or max duration.
nametagssession_idrequiredidle_timeout_minutesmax_duration_secondsTerminate MULTIPLE sandboxes in one call (bulk). IRREVERSIBLE — every listed sandbox and its filesystem is destroyed. Use tenki_terminate_sandbox for a single one.
session_idsrequiredReport client-side activity on a sandbox to reset its idle timer and keep it from being reaped as idle (a keep-alive heartbeat).
session_idrequiredList every sandbox belonging to a specific workspace (defaults to the API key's workspace) — useful for spotting leaked, still-billing sandboxes across the workspace.
page_sizepage_tokenworkspace_idinclude_terminatedRun a command in an existing sandbox and return stdout, stderr, and exit code inline. Streams over max_output_bytes (default 64KB) come back as a head+tail preview with the full output retained at stdoutPath/stderrPath in the sandbox.
cwdenvargscommandrequiredsession_idrequiredtimeout_secondsmax_output_bytesRead a UTF-8 text file from a sandbox (paths under /home/tenki).
pathrequiredsession_idrequiredWrite a UTF-8 text file to a sandbox (paths under /home/tenki).
pathrequiredcontentrequiredsession_idrequiredList a directory in a sandbox, including dotfiles (.git, .env, .gitignore) by default — set include_hidden false to omit them.
pathrequiredsession_idrequiredinclude_hiddenGet metadata (size, mode, type, timestamps) for a file or directory in a sandbox. Use to check whether a path exists or inspect it before reading/removing.
pathrequiredsession_idrequiredCreate a directory in a sandbox. Set recursive to also create any missing parent directories (mkdir -p).
pathrequiredrecursivesession_idrequiredDelete a file or directory in a sandbox. Set recursive to remove a non-empty directory and its contents (rm -r).
pathrequiredrecursivesession_idrequiredMove or rename a file or directory within a sandbox. Both paths are under /home/tenki.
torequiredfromrequiredsession_idrequiredRun a git operation in a sandbox. Only clone, checkout, diff, and log are supported by the API — for any other git command (status, add, commit, push, ...) use tenki_exec with `git ...`. clone arg keys: repo (required, the URL), branch?, depth?, directory?. CAVEAT (live-verified): checkout/diff/log run in the session's working directory (/home/tenki), which is not a repository and has no directory arg — so on a repo cloned into a subdirectory they fail with 'not a git repository'. Use tenki_exec with `git -C <directory> ...` instead (e.g. `git -C /home/tenki/hw log -n 2`). For reference, their arg keys are — checkout: ref (required), create? ('true' = -b); diff: range? or base?+head?, path?; log: max_count?, range?, path?.
argsoperationrequiredsession_idrequiredExpose a port from a sandbox and get a public preview URL. Useful when an agent starts a web server it wants to show.
portrequiredslugsession_idrequiredList the ports currently exposed from a sandbox.
session_idrequiredRemove an inbound port exposure from a sandbox, taking its public URL/preview offline. Use this to un-publish a port previously exposed with tenki_expose_port.
portrequiredsession_idrequiredCreate a shareable public preview URL for a port in a sandbox. The sandbox must have inbound networking enabled (create it with allow_inbound).
portrequiredslugrequiredexpires_atsession_idrequiredOpen a viewer-token-gated (AUTHENTICATED-mode) preview. USE tenki_expose_port OR tenki_create_preview_url INSTEAD for an ordinary web server: for any port other than the web terminal (7681) the API deliberately returns a non-regional fallback host that currently has no edge route, so the URL 404s (live-verified). The returned viewerToken does resolve via tenki_resolve_preview_token; only the URL is unreachable. Requires allow_inbound.
portrequiredexpires_atsession_idrequiredList the workspace's preview URLs, newest page first. Pass session_id to keep only the ones bound to that sandbox (filtered here, not server-side — so it applies to the page you fetched; raise page_size or follow next_page_token to widen it). Results are paginated: a nextPageToken in the response means more pages exist.
page_sizepage_tokensession_idworkspace_idFetch a specific preview URL's details by id.
preview_url_idrequiredDelete a preview URL by id, taking it permanently offline.
preview_url_idrequiredRefresh (keep-alive) a live preview by its preview token so it isn't torn down as idle.
preview_tokenrequiredBind a named preview URL to a sandbox session and port (advanced routing).
portrequiredsession_idrequiredpreview_url_idrequiredUnbind a named preview URL from its current session/port (advanced routing).
preview_url_idrequiredResolve a preview token to the sandbox/port it points at (advanced).
tokenrequiredCapture a running sandbox's disk and memory as a reusable snapshot (attached volumes are NOT captured); boot a new sandbox from it later with tenki_create_sandbox + snapshot_id.
nameexpires_atsession_idrequiredstore_raw_imageFetch one snapshot's status and metadata by ID.
snapshot_idrequiredList the saved snapshots for the workspace (owner inferred from the API key).
page_sizepage_tokenList the snapshots captured from a specific sandbox session.
page_sizepage_tokensession_idrequiredList dangling snapshots — those whose source session no longer exists — for the workspace, useful for cleanup.
page_sizepage_tokenUpdate a snapshot's mutable metadata (name and/or expiry).
nameexpires_atsnapshot_idrequiredPermanently delete a snapshot by ID.
snapshot_idrequiredGet a short-lived, pre-signed URL to download a snapshot's raw disk image (requires the snapshot to have been created with store_raw_image).
snapshot_idrequiredList all snapshots in a workspace (defaults to the key's first workspace). Supports pagination.
page_sizepage_tokenworkspace_idCreate a workspace-scoped persistent volume — durable block storage that survives sandbox teardown. Defaults the workspace to the API key's first; override with workspace_id.
namerequiredsize_bytesrequiredworkspace_idFetch a single volume's metadata and current state by its id.
volume_idrequiredList persistent volumes in a workspace (defaults to the key's first workspace). Supports pagination.
page_sizepage_tokenworkspace_idRename a volume (update its human-readable name). To change a volume's size use tenki_resize_volume instead.
namerequiredvolume_idrequiredPermanently delete a volume and destroy its data. Fails with VolumeInUse if the volume is still attached to a session — detach it first.
volume_idrequiredGrow a volume to a new size in bytes (1 MiB … 100 GiB). Volumes can grow but not shrink.
volume_idrequiredsize_bytesrequiredMount a volume into a running sandbox at an absolute path. Set read_only to mount without write access.
read_onlyvolume_idrequiredmount_pathrequiredsession_idrequiredUnmount a volume from a sandbox session.
volume_idrequiredsession_idrequiredCreate a custom-image template (a reusable sandbox-image spec: base image + setup script + default resources). Build it into a bootable image later with tenki_build_template. NOTE: only a TYPED template (created with builder_spec, no legacy fields) can build a named, publishable image (image_name) that tenki_create_sandbox boots via its `image` arg.
namerequiredtagsenv_varscpu_coresmemory_mbstart_cmdbuilder_specdisk_size_gbparent_imagesetup_scriptworkspace_idbase_image_id+1 moreRetrieve one template by ID.
template_idrequiredList templates for the workspace, optionally filtered by tags.
tagspage_sizepage_tokenworkspace_idUpdate mutable fields on a template. Only the fields you provide are changed; pass clear_tags to remove all tags.
nametagsenv_varscpu_coresmemory_mbstart_cmdclear_tagstemplate_idrequiredbuilder_specdisk_size_gbsetup_scriptbase_image_idDelete a template by ID. Pass force to delete even when builds or dependents exist.
forcetemplate_idrequiredTrigger a build for a template, producing a bootable image. Returns the created build — poll it with tenki_get_template_build until READY; the ready build's imageDigestRef is what tenki_create_sandbox's `image` arg takes.
build_envimage_nametemplate_idrequiredbuild_secretspublish_raw_imageCancel an in-progress template build by its build ID.
build_idrequiredRetrieve one template build by its build ID (state, progress, and result image). A READY build's imageDigestRef is the reference tenki_create_sandbox's `image` arg takes.
build_idrequiredList the currently active (in-progress) builds for a given template.
template_idrequiredGet per-second sandbox billing and usage figures for a workspace — use this for cost visibility across all of the workspace's sandboxes.
workspace_idRead a workspace's sandbox quotas and retention policy: max snapshots/templates/volumes/total bytes, max concurrent and sticky sessions, max preview URLs, and the pause/snapshot retention periods. These are workspace limits — there are no per-session defaults (idle timeout and max duration are set per sandbox at creation).
workspace_idUpdate a workspace's sandbox quotas and retention periods. Only the fields you pass change. Each quota has a matching clear_* flag to remove the override and fall back to the platform default; pass the value OR its clear flag, not both. There are no per-session defaults here — idle timeout and max duration are set per sandbox at creation.
max_volumesworkspace_idmax_snapshotsmax_templatesmax_total_bytesmax_preview_urlsmax_sticky_sessionspause_retention_daysclear_pause_retentionmax_concurrent_sessionssnapshot_retention_daysclear_snapshot_retentionGet the workspace's pause- and snapshot-retention periods. DEPRECATED upstream: this RPC is marked deprecated in the API — tenki_get_workspace_settings returns the same retention fields alongside the quotas. An empty response means no retention override, i.e. kept indefinitely.
workspace_idUpdate the workspace's snapshot-retention policy: how long snapshots are kept before automatic cleanup. Pass retention_days to set it, or clear_retention to keep snapshots indefinitely (the unset state) — exactly one of the two. DEPRECATED upstream: prefer tenki_update_workspace_settings, which sets the same retention (and pause retention) alongside the quotas.
workspace_idretention_daysclear_retentionGet a short-lived signed URL to upload (HTTP PUT) a binary file to a path inside a sandbox. Use for non-text payloads too large or binary for tenki_write_file.
pathrequiredsession_idrequiredcontent_typeGet a short-lived signed URL to download (HTTP GET) a command artifact from a sandbox by its artifact id (e.g. a command's stdout/stderr artifact). Note: the API supports download-by-artifact-id only, not download-by-path.
session_idrequiredartifact_idrequiredSet the SSH authorized public keys on a running sandbox, enabling direct SSH access for the given keys.
session_idrequiredpublic_keysrequiredIssue a short-lived SSH certificate for a public key, authorizing SSH access to a sandbox via the SSH gateway.
public_keyrequiredsession_idrequiredList the currently active SSH gateways for the workspace.
workspace_idReport whether the server has a usable Tenki credential, which kind (API key vs OAuth session token), and the endpoint it targets — verified with a live identity probe. Call this first when other tools fail with auth errors, or when this is the only tool available (which means no credential is configured). Reports status only; it does not log in and never returns the token.
Takes no parameters.
90% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
"Run this Python in a fresh sandbox and tell me what it prints." │ ▼ tenki_run_code boots a microVM → runs it → returns stdout → tears it downexport TENKI_API_KEY=tk_your_key_herenpx -y @tenkicloud/mcp # speaks MCP over stdioclaude mcp add --transport http tenki https://mcp.tenki.cloud/mcpclaude mcp login tenkiclaude mcp add tenki --env TENKI_API_KEY=tk_your_key_here -- npx -y @tenkicloud/mcp/plugin marketplace add LuxorLabs/tenki-mcp/plugin install tenki@tenki{ "mcpServers": { "tenki": { "command": "npx", "args": ["-y", "@tenkicloud/mcp"], "env": { "TENKI_API_KEY": "tk_your_key_here" } } }}{ "mcpServers": { "tenki": { "command": "npx", "args": ["-y", "@tenkicloud/mcp"], "env": { "TENKI_API_KEY": "tk_your_key_here" } } }}[mcp_servers.tenki]command = "npx"args = ["-y", "@tenkicloud/mcp"]env = { TENKI_API_KEY = "tk_your_key_here" }git clone https://github.com/LuxorLabs/tenki-mcp.git && cd tenki-mcpnpm install && npm run buildTENKI_API_KEY=tk_your_key_here node dist/index.jsTENKI_MCP_TRANSPORT=http PORT=3000 TENKI_API_KEY=… npx -y @tenkicloud/mcp# → tenki-mcp running on http://127.0.0.1:3000/mcp (Streamable HTTP) [loopback only, no auth]# expose to a network safely:TENKI_MCP_TRANSPORT=http TENKI_MCP_HTTP_HOST=0.0.0.0 PORT=3000 \ TENKI_MCP_HTTP_TOKEN=$(openssl rand -hex 32) TENKI_API_KEY=… npx -y @tenkicloud/mcp