@maroo-chain/m-aws
v0.2.7
Published
Maroo Agent Wallet Stack — MCP server for AI agent wallet management on Maroo chain
Downloads
346
Readme
m-aws — Maroo Agent Wallet Stack
MCP server that lets any LLM-powered AI client (Claude Code, Claude Desktop, Cursor, Gemini CLI) create and operate AI agent wallets on the Maroo blockchain. 19 tools covering agent lifecycle, on-chain spending policy, OKRW transfers, gas-source switching, and ownership transfer.
Here, try this (Claude Code, 30 seconds)
npm install -g @maroo-chain/m-aws # installs the `m-aws` CLI
m-aws init # interactive setup: pick provider, write
# .mcp.json, log in (re-runnable, idempotent)m-aws init is the recommended entry point — it picks an auth provider, writes (or merges) .mcp.json for you, and optionally launches login. Manual setup, if preferred:
m-aws login kakao # one-time browser auth (or `login email` for OPAQUE)Drop this into .mcp.json at the root of any project you want agent capabilities in:
{
"mcpServers": {
"m-aws": { "command": "m-aws", "args": ["serve"] }
}
}Package name is
@maroo-chain/m-aws(npm scope). The CLI binary is justm-awsfor convenience — type that everywhere.
Open the project in Claude Code — m-aws loads automatically. Ask:
"Create a new agent called trading-bot, fund it with 100 OKRW, and set a 50 OKRW per-tx spending limit."
Claude Code will call agent.create → agent.fund → policy.set and report back. Every tool call returns {ok:true,data} or a structured {ok:false,error} with a suggestion.
Authenticate
m-aws login kakao # Kakao OAuth (browser)
m-aws login google # Google OAuth
m-aws login email # OPAQUE email/password (no browser)
m-aws signup email # Create a new OPAQUE account
m-aws status # Show current identity (address, expiry)
m-aws logout # Clear credentialsCredentials are stored at ~/.maroo/credentials.json and auto-refreshed on expiry. For CI or containers, set WAAS_AUTH_TOKEN instead — the file is ignored when the env var is present.
Use with MCP clients
Same config block works everywhere:
{
"mcpServers": {
"m-aws": { "command": "m-aws", "args": ["serve"] }
}
}| Client | Config file (macOS) | Per-project? |
|---|---|---|
| Claude Code | .mcp.json at repo root, or ~/.claude.json | yes (repo wins) |
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json | no — global only |
| Cursor | .cursor/mcp.json or ~/.cursor/mcp.json | yes |
| Gemini CLI | .gemini/settings.json or ~/.gemini/settings.json | yes |
If m-aws isn't on the client's PATH (common with Claude Desktop), use npx:
{ "command": "npx", "args": ["-y", "@maroo-chain/m-aws", "serve"] }Not authenticated yet when the client loads? The server still starts in no-auth mode — every tool call returns NO_AUTH with the fix: Run m-aws login kakao. This means a Claude Code session can point at m-aws before the user logs in, and the first tool call will say exactly what to do.
Tool surface
Every tool follows namespace.verb. Each returns either {ok:true,data:…} or {ok:false,error:{code,message,detail,suggestion,retryable}}.
agent.*
| Tool | Purpose |
|---|---|
| agent.create | Create a new AI agent with its own AA wallet. Returns PENDING status; ACTIVE in ~1–3 min. Optional gasSource (SELF / OWNER / PAYMASTER) + gasSourceAddress lock in the funding mode at creation time — composite call (createAgent → setGasSource) with pre-flight so a malformed request never leaves an orphan agent. |
| agent.list | List every agent owned by the current user. |
| agent.detail | Full info for one agent (includes balance). |
| agent.balance | Agent's OKRW balance. |
| agent.owner_balance | Current user's OKRW balance. |
| agent.fund | Send OKRW from owner → agent (synchronous, returns txHash). |
| agent.drain | Recover an agent's OKRW back to the owner wallet in spending-limit chunks. Optional maxAmount cap; surfaces drainedSoFar + txHashesCompleted on partial failure for resumable recovery. |
| agent.set_gas_source | Switch gas-funding mode between PAYMASTER (sponsored, default), SELF (agent's own OKRW), and OWNER (experimental — server-side stored, on-chain falls back to SELF until WaaS ships owner-pays-gas). Pre-flight rejects mode/address mismatches. |
| agent.freeze / agent.unfreeze | Pause / resume all signing for an agent. |
| agent.revoke | Permanently kill an agent (IRREVERSIBLE; funds become unmovable). |
policy.*
| Tool | Purpose |
|---|---|
| policy.get | Read the agent's on-chain spending policy (limit + allowed targets). |
| policy.set | Update policy via owner tx to IdentityRegistry metadata. Omit a field to keep its current value. |
| policy.preflight | Dry-run a proposed transfer — returns canTransact + per-gate reasons. Call before every transfer.send. |
transfer.*
| Tool | Purpose |
|---|---|
| transfer.send | Agent sends OKRW to an address. Server-side policy enforcement; synchronous result. |
| transfer.initiate | Start ownership transfer to another user (agent frozen; 24 h to accept). |
| transfer.accept | Recipient claims the agent; WaaS executes on-chain ERC-721 transfer. |
| transfer.cancel | Either party aborts a pending transfer. |
| transfer.pending | List incoming transfers awaiting your decision. |
Every tool description includes Preconditions, Returns, Next steps, and known Error codes. Call tools/list via MCP to see the full spec.
Error codes
All errors arrive as {ok:false,error:{code,message,detail,suggestion,retryable}}. Codes and expected behavior:
| Code | Fires when | Retryable? | What to do |
|---|---|---|---|
| NO_AUTH | Server has no credentials and no WAAS_AUTH_TOKEN. | No (until user logs in) | Run m-aws login kakao (or login email), then restart the MCP client. |
| INVALID_INPUT | Schema or pre-flight rejection (e.g. OWNER gas mode without gasSourceAddress, address with non-OWNER mode). | No | Fix the request shape per the suggestion. The server runs pre-flights BEFORE side-effecting calls so malformed requests never leave partial state. |
| FORBIDDEN | Server says the caller isn't allowed (e.g. agent belongs to a different owner, or current status disallows the change). | No | Confirm agent.detail matches the caller's identity, or change agent status (e.g. unfreeze) first. |
| AGENT_NOT_FOUND | agentId doesn't resolve. | No | List with agent.list and use a real id. |
| AGENT_PENDING | Tool needs onchainAgentId but it's still null — agent was just created. | Yes | Wait 1–3 min and retry. Use agent.detail to watch for status flip to ACTIVE. |
| AGENT_NOT_ACTIVE | Agent is FROZEN or REVOKED — can't transact. | No | If FROZEN, call agent.unfreeze. If REVOKED, create a new agent. |
| AGENT_CREATED_GAS_FAILED | agent.create succeeded but the requested non-PAYMASTER gas-source flip failed mid-way. | Yes | The agent IS real (its id is in error.detail.agentId). Wait for ACTIVE, then call agent.set_gas_source with the suggestion's ready-to-paste args. |
| INSUFFICIENT_BALANCE | Agent's OKRW balance is less than the requested amount. | No (until topped up) | Call agent.fund to send more OKRW, or reduce amount. |
| POLICY_REJECTED | On-chain policy (spending limit or allowed targets) blocks the transfer. | No (until policy changes) | Call policy.get to see rules, then policy.set to adjust. |
| FUND_FAILED | The owner → agent funding tx failed on-chain. | Yes | Check detail.errorMessage. Often transient; retry after a few seconds. |
| TX_FAILED | The agent's send tx failed on-chain. | Yes | Same handling as FUND_FAILED — inspect detail, retry. |
| UNKNOWN_TOOL | Called a tool name that doesn't exist. | No | Check detail.availableTools. |
| INTERNAL_ERROR | Unexpected non-ToolError exception. | No | Inspect message; report if it persists. |
Idempotency
Any mutating tool (create, fund, freeze, send, …) accepts an optional clientToken argument. Calls with the same (tool, owner, clientToken) within 1 h return the cached first result instead of re-executing.
{ "name": "agent.fund", "arguments": {
"agentId": "019d…", "amount": "100",
"clientToken": "my-request-uuid-v4"
} }Useful for LLM retry loops, network flake handling, and safe replay.
Development
git clone https://github.com/hashed-open-finance/m-aws
cd m-aws/packages/mcp-server
npm install
npm run build
npm link # puts `m-aws` on your PATH
npm test # 94 testsOther CLI commands
m-aws init # interactive setup wizard (write/merge .mcp.json + login)
m-aws doctor # auth + WaaS API + RPC + owner-balance health check
m-aws update # check npm + upgrade to latest
m-aws version # print package + version
m-aws tui # launch the Rust TUI (requires the m-aws-tui binary)Environment
| Variable | Default | Description |
|---|---|---|
| WAAS_AUTH_TOKEN | — | Override stored credentials (Bearer token; falls back to cookie prefix) |
| WAAS_BASE_URL | https://testing.waas-dev.shardlab.io | WaaS API base URL (testnet) |
Limits / known scope
- Testnet only — Maroo chain id 450815, OKRW token. Mainnet support TBD.
- Agent registration takes 30–60 s after
agent.create— the WaaS cron writes the IdentityRegistry record asynchronously. During that window, policy and send operations returnAGENT_PENDING. The LLM should retry after waiting. - Policy writes are on-chain —
policy.setincurs an owner transaction. Paymaster covers gas in typical cases; if the owner wallet is empty, the tx can fail. Fund the owner wallet first. - Revoke is permanent — there's no un-revoke. Use
agent.freezefor temporary pauses.
