noeta-cli
v0.3.3
Published
CLI portal to Noeta Cloud for agents & humans: `npx noeta-cli login` (browser approval, no prompts), then call the workspace API/MCP tools directly — no MCP client configuration required.
Maintainers
Readme
noeta-cli
Installs the noeta command (npm i -g noeta-cli for the short form; npx noeta-cli … works with no install).
CLI portal to a Noeta Cloud workspace — for agents and
the humans who authorize them. For the core mental model — environments,
workspaces, folders, permissions, agent identity — read
CONCEPTS.md (or run noeta concepts).
npx noeta-cli loginThat's the whole setup: your browser opens, you sign in, pick an access level (full / editor / commenter / read-only), and click Approve. The command finishes on the click — it never asks for terminal input — and saves the token locally. From then on the CLI is the integration; no MCP client configuration required:
No browser on this machine? (a server, an SSH session, a container.) login
also prints a short code and an /activate URL. On any device that's already
signed in — your phone, say — go to https://noeta.cloud/activate, type the
code, and approve there. Nothing is emailed; you initiate it from the terminal
and confirm on a device you're already logged into.
npx noeta-cli whoami # who am I, which workspace, what cap
npx noeta-cli tools # list the workspace's tools
npx noeta-cli call get_doc '{"docId":"<id>"}' # read a document
npx noeta-cli call insert_blocks '{"docId":"<id>","blocks":[{"type":"paragraph","content":"hi"}]}'
npx noeta-cli logout # revoke the token server-side + forget itMultiple environments
login defaults to https://noeta.cloud; pass your deployment's URL for per-org
instances. Each is identified by its domain — no aliases to invent or keep in
sync. Target one with --env <domain>: the full host, or the deployment url.
npx noeta-cli login https://your-org.noeta.cloud # add an environment
npx noeta-cli envs # list envs; ★ marks the default
npx noeta-cli use your-org.noeta.cloud # set the default
npx noeta-cli call get_doc '{"docId":"…"}' # a READ uses the default
npx noeta-cli call insert_blocks '{…}' --env your-org.noeta.cloud # a WRITE must name --envSelection precedence: --env <domain> / --url > NOETA_ENV > NOETA_URL > the
default. NOETA_TOKEN overrides the stored token (CI). Every command prints its
resolved target to stderr, so you always see where an action landed.
Writes are guarded. Once more than one environment is configured, reads use the
default freely, but a write (anything that isn't get_*/list_*/read_*) is
refused unless you name the target with --env. A mutating call can't land on the
wrong deployment because of a stale default.
Credentials live in ~/.config/noeta/credentials.json (0600), one entry per
deployment (prefer noeta envs / mcp-config / whoami --json over reading it):
{
"default": "https://your-org.noeta.cloud",
"origins": {
"https://your-org.noeta.cloud": {
"token": "noeta_…",
"agentId": "agt_…",
"agentName": "My Agent",
"workspaceId": "ws_…"
}
}
}What the identity is
Approving mints a delegated agent identity: it acts on your behalf,
capped at the level you approved — it can do at most what you can do, never
more, and everything it writes is attributed to you via the agent. Revoke
any time with npx noeta-cli logout (or DELETE /api/agents/<id> as your
signed-in user).
For agents driving this programmatically
Coding agent? Read AGENTS.md — the playbook for driving this from a shell
(authenticate → noeta tools --json to discover → noeta call). The short version:
No command reads stdin, and --json makes stdout a single machine-readable
value (progress and errors go to stderr):
npx noeta-cli login --json --no-open # stderr: the approval link to hand to the user
# stdout: {"token":…,"agentId":…,"mcpUrl":…} on approval
npx noeta-cli whoami --json
npx noeta-cli tools --json
npx noeta-cli call get_doc '{"docId":"<id>"}' # stdout: the tool result JSONExit codes: 0 ok · 1 usage/network/server error · 2 login denied,
expired, or timed out · 3 the tool call returned an error (reason on stderr).
Native MCP connection
Every deployment is also a real MCP server — MCP over Streamable HTTP
(JSON-RPC 2.0) at POST <deployment>/mcp, authenticated with
Authorization: Bearer <token>. login prints the ready-to-paste
registration, and noeta mcp-config reprints it any time (plus --json
for {mcpUrl, baseUrl, serverName, claudeMcpAdd}). The client server name is derived
from the host (noeta-<subdomain>), so several deployments register side by side:
claude mcp add --scope user --transport http noeta-your-org https://your-org.noeta.cloud/mcp \
--header "Authorization: Bearer noeta_…"Keep --scope user: it stores the server in your home config. Project scope
would write the Bearer token into a .mcp.json that's easy to commit — never
put the token in anything that lands in version control.
The raw HTTP contract (no node required)
The CLI is a convenience over plain HTTP — any language can do this (OAuth-device-grant shaped):
# 1. start (no auth): returns userCode (for the browser), deviceCode (for you), verifyUrl
curl -X POST https://your-org.noeta.cloud/api/agent-auth/start \
-H 'content-type: application/json' -d '{"clientName":"My Agent"}'
# 2. send the user to verifyUrl (…/?agent-auth=<userCode>) and let them approve
# 3. poll (no auth) every ~2s until "approved"; the token is returned exactly ONCE
curl -X POST https://your-org.noeta.cloud/api/agent-auth/poll \
-H 'content-type: application/json' -d '{"deviceCode":"<deviceCode>"}'Then, with Authorization: Bearer <token>:
POST /mcp— MCP over Streamable HTTP (JSON-RPC 2.0):tools/list,tools/callGET /agent/me— the authenticated identityPOST /agent/revoke— self-revoke (whatlogoutcalls)
Requests expire after 10 minutes; the userCode in the URL can't poll the
token; the server stores only a hash of the token.
Requirements
Node ≥ 18 (global fetch). Zero dependencies.
