metamask-mcp: Signing
The metamask-mcp
server is the default wallet signer module in PILSO OS.
It acts as a secure bridge between an agent’s intent and the user’s wallet, preparing unsigned transaction payloads and routing them to MetaMask for final signature and onchain execution.
No private key is ever exposed — and no transaction is sent without explicit user approval.
What It Does
Prepares and formats raw Ethereum transactions (or EIP-712 messages)
Ensures the transaction structure is valid and RPC-ready
Sends the payload to MetaMask for signing
Waits for confirmation and returns signed tx or status
Supports
eth_sendTransaction
andeth_signTypedData_v4
Architecture Overview
LLM Agent → metamask-mcp → MetaMask UI → User signs → tx is sent
LLM builds intent: "Transfer 0.1 ETH to Bob"
metamask-mcp constructs a safe, valid transaction object
The object is passed to MetaMask via browser context or injected signer
User sees and approves/rejects
The signed transaction is broadcast to the chain
Tool Name: metamask.sign
metamask.sign
Request (from agent)
{
"tool": "metamask.sign",
"args": {
"to": "0x1234567890abcdef...",
"data": "0x...",
"value": "0",
"gas": "21000",
"chainId": 1
}
}
to
: Target contract or addressdata
: Hex-encoded function call or messagevalue
: Optional ETH value to sendgas
: Estimated gas limitchainId
: Target network ID
Response (to agent)
{
"status": "signed",
"txHash": "0xabc...",
"explorer": "https://etherscan.io/tx/0xabc..."
}
Server Setup
This server is included in the official MCP server repo.
To run it locally:
git clone https://github.com/pilso-os/mcp-servers
cd mcp-servers/metamask-mcp
npm install
npm start
It will default to http://localhost:3020
.
Add this endpoint in your pilso.config.json
:
"tools": [
"http://localhost:3020"
]
Test Call Locally
You can test the signing flow without running an agent:
npx pilso call \
--tool metamask.sign \
--args '{"to": "0x123...", "data": "0x...", "chainId": 1}'
MetaMask will prompt for signature. Nothing is signed without user approval.
Security Principles
Non-custodial: The server cannot access or sign transactions directly
User-controlled: All signing is done through MetaMask UI
Modular: Can be swapped out with other signer MCPs (e.g.
safe-mcp
)Auditable: All unsigned payloads are visible in logs before submission
Signing Best Practices
Always preview transaction payloads in your session logs
Set
alwaysAllow
tofalse
for signing tools — manual approval is saferOnly expose
metamask.sign
to scoped roles likesigner
, notdeveloper
Use guardrails like
“Never send tokens”
in roles to prevent misuse
Future Additions
Support for WalletConnect via
walletconnect-mcp
Support for Gnosis Safe via
safe-mcp
EIP-712 typed data signing (WIP)
✅ Summary
Tool name
metamask.sign
Port
3020
(default)
Signs?
No — prepares and sends to MetaMask
Custody risk
None
Execution flow
Agent → MCP → Wallet UI → Signature
metamask-mcp
ensures that every transaction is intentional, visible, and user-approved. It’s the foundation of PILSO’s non-custodial execution model.
Last updated