Key handling
DER or raw hex, and the key type
HEDERA_OPERATOR_KEY accepts two formats:
- DER-encoded hex (starts with
302e...for ED25519 or3030...for ECDSA). The curve is part of the encoding, nothing else to configure. - Raw 64-character hex (with or without
0x). The bytes do not say which curve they belong to. HashPilot assumes ECDSA, which is what the Hedera Portal issues by default. For an ED25519 account, setHEDERA_OPERATOR_KEY_TYPE=ed25519(ecdsais also accepted to make the assumption explicit).
rpc_deploy_contract, rpc_execute_contract, Hardhat and Foundry deployments) sign with an ECDSA key and log a warning when the operator key is ED25519.
The startup key verification
When the server starts it fetches your operator account from the Mirror Node and compares the account’s public key with the one derived fromHEDERA_OPERATOR_KEY:
- If they match, the server starts.
- If the key was raw hex and does not match, HashPilot re-interprets it on the other curve and uses that when it matches (with a warning).
- Otherwise it refuses to start with an error that names the account’s key type and prefix and the derived key, so a wrong key surfaces immediately instead of as
INVALID_SIGNATUREon your first transaction. - Accounts with threshold or key-list keys skip the comparison. If the Mirror Node is unreachable the server starts and logs a warning.
account_info on your operator ID shows the key type the network has on record.
Never commit keys
- MCP configuration files (
claude_desktop_config.json,.cursor/mcp.json,mcp_config.json,.gemini/settings.json) hold the key in plain text. Keep them out of version control; for Gemini CLI use$VARIABLEreferences in theenvblock so the file contains no secret. - Hardhat and Foundry projects scaffolded by HashPilot read keys from
.env, and the generated.gitignoreexcludes it. HashPilot injects the operator key into deployments at runtime, so you rarely need to write it into.envat all. addressbook_manage importstores private keys unencrypted in the data directory. Import only what you need, and preferadd(no key) for accounts you only look up.state_manage backupandexportexclude private keys unless you passincludePrivateKeys: true. Treat such files like the keys themselves.- Use separate accounts for testnet and mainnet. A testnet key that leaks costs nothing; a mainnet key that leaks costs everything in the account.
Choosing a network
Develop on testnet. Use
network_switch to move between networks in a session; the choice is persisted, so check network_info (or health_check) before sending anything after a restart. JSON_RPC_RELAY_URL and MIRROR_NODE_URL only apply to the network named in HEDERA_NETWORK; other networks use the public endpoints.
Production RPC providers
The default JSON-RPC relay is Hashio (https://<network>.hashio.io/api). Hashio is rate-limited and intended for development only. Before going to mainnet, or when you hit rate limits on testnet, set JSON_RPC_RELAY_URL to a provider endpoint for the network in HEDERA_NETWORK:
rpc_*, the deployment tools, Hardhat and Foundry. health_check with verbose: true shows the relay URL in use.
Mirror Node usage
Reads through the Mirror Node are free and need no operator key:account_balance, account_info, mirror_query_account, every mirror_query resource, hcs_message query, hcs_topic info, and the docs behind index-network. Two things to keep in mind:
- The 60-day implicit window. On the Hedera-operated Mirror Nodes, history endpoints without a timestamp filter only return the last 60 days. Affected endpoints include
/api/v1/transactions,/api/v1/accounts/{id}(the transactions it embeds),/api/v1/contracts/resultsand/api/v1/contracts/results/logs. Older data is still there: query it with an explicit timestamp range of at most 60 days.mirror_query_accountwithincludeTransactionsis subject to this window. - Lag and limits. Data appears on the Mirror Node a few seconds after consensus, so a balance read straight after a transfer may be one step behind. The public nodes are rate-limited; for heavy use set
MIRROR_NODE_URLto a provider (Arkhia, Validation Cloud and others host Mirror Nodes) or your own.
Token association before transfer
A Hedera account can only hold a token it has associated with. Transferring to an unassociated account fails withTOKEN_NOT_ASSOCIATED_TO_ACCOUNT. The order is:
token_manage associatefor the receiving account. The receiving account must sign, so for an account other than the operator pass that account’sprivateKey(or import it into the address book first).token_manage transferfrom the treasury or holder.
decimals: 2, transferring 250 moves 2.50 tokens. account_balance reports token balances the same way. A transfer also needs the sender’s key: transfers from the operator’s own account need nothing extra, transfers from another account need senderPrivateKey.
Contract verification via Sourcify
HashScan shows verified source code from Sourcify. Sourcify supports Hedera mainnet (chain 295) and testnet (chain 296); previewnet (297) cannot be verified.verify_contractsubmits the source withaddress,network,contractNameandfilePath. Use the exact source and compiler settings that produced the deployed bytecode; a mismatch gives a partial match or a failure.hardhat_contract verifyfinds the Hardhat build-info file and returns the alternatives:npx hardhat verify --network <network> <address>with@nomicfoundation/hardhat-verify3.x and Sourcify enabled, or uploading the build-info at verify.sourcify.dev.- With Foundry,
forge verify-contract --verifier sourcify --chain 296 <address> src/Greeter.sol:Greeterdoes the same from the command line.
deployment_history records every deployment made through deploy_contract with its address and network, which is what you need for verification later.
Data directory and backups
Everything HashPilot persists lives in one directory:~/.hedera-mcp by default, or HASHPILOT_DATA_DIR if set. It holds the address book, the persisted network choice, deployments.json, and the backups/ and exports/ folders. Files from older versions that lived inside the package are migrated there on first start.
- Set
HASHPILOT_DATA_DIRwhen you run several editors with different accounts, or want the data on an encrypted volume. - Run
state_manage backupbefore upgrading HashPilot or moving machines. Backups are timestamped JSON inbackups/;outputPathis optional. state_manage restorereplaces the current state, or merges it withmerge: true.state_manage exportwrites a readable JSON snapshot (format: prettyby default) toexports/.- Backups exclude private keys unless you ask for them. If the address book holds imported keys and you need them in the backup, pass
includePrivateKeys: trueand store the file as carefully as the keys.
Cost awareness
Fees are paid by the operator account. Reads never need HBAR, so a read-only setup with no operator key still works for balances, HCS history, Mirror Node queries and error lookups. The docs tools need
OPENAI_API_KEY and are billed by OpenAI; error_explain is a local lookup and needs neither.