AI over DePIN
Neurai does not run models on-chain and does not promise autonomous AI networks. What it has is narrower and useful: a bridge inside the node that connects a token-gated, encrypted DePIN channel to any language model with an OpenAI-compatible API. Holders of the token talk to the model through the channel; nobody else can, and no public API endpoint exists.
This page describes exactly what that bridge does, how to run it, what it cannot do, and one realistic pattern for building something more capable on top of it with the existing libraries.
The node calls this feature MCP mode (-depinmcp). It is Neurai's own bridge to chat/completions endpoints. It is not the Model Context Protocol used by desktop AI clients, and it does not expose tools to the model.
What the worker does
The worker is a background thread of neuraid, enabled per node. On each poll it:
- Reads the local DePIN pool for messages in the monitored token or any section below it, no older than 24 hours, not sent by the node itself and not processed before.
- Decrypts each message once with the node's own address key and keeps only those whose text starts with the command prefix,
/aiby default. - Applies the global and per-sender rate limits, trims the text and caps it at 4,000 characters.
- Sends the text to the configured endpoint as a chat completion, with a fixed system prompt and, when enabled, the sender's last few turns as context.
- Signs the answer with the node address, prefixes it with
[BOT]:, splits it into fragments if it is long, and publishes it to the section the question came from. Recipients are the active holders of that section and of its ancestors up to the monitored token, resolved on-chain at that moment.
Everything travels as ordinary DePIN messages: encrypted per recipient, signed, off-chain and expiring with the pool.
Running it
You need a node that already serves a DePIN pool, see Running a service node, and a model server. Any of these work out of the box because they speak the OpenAI chat API:
| Server | Endpoint the worker uses | Notes |
|---|---|---|
| Ollama | http://localhost:11434 + /v1/chat/completions | ollama run llama3.1 or any pulled model |
| LM Studio | http://localhost:1234 + /v1/chat/completions | Default URL of the worker |
| llama.cpp server | http://localhost:8080 + /v1/chat/completions | llama-server -m model.gguf |
| Hosted API | provider URL + /v1/chat/completions | Set -depinmcpapikey. Prompts leave your machine |
# neurai.conf
# DePIN pool (already required)
assetindex=1
pubkeyindex=1
depinmsg=1
depinmsgtoken=&FACTORY
# AI bridge
depinmcp=1
depinmcpaddress=Nbot... # node address that decrypts commands and signs replies
depinmcpurl=http://localhost:11434 # model server
depinmcpendpoint=/v1/chat/completions
depinmcpkey=/ai # command prefix
depinmcpinterval=10 # seconds between polls
depinmcpcontext=6 # history entries per sender (3 turns), 0 disables
depinmcpconcurrency=2 # parallel model requests
depinmcpratelimit=10 # commands per minute per sender, 0 = unlimited
depinmcpglobalratelimit=60 # commands per minute in total, 0 = unlimited
depinmcpmaxtokens=500
depinmcptemperature=0.7
depinmcptimeout=120 # seconds per model call
The address in depinmcpaddress must hold the token and have a revealed public key, like any other participant. The worker asks the server for /v1/models at startup to learn the model name shown in the status RPC. If the server is down at startup the worker still starts and retries.
Check it:
neurai-cli depinmcpstatus
The reply reports enabled, running, mcp_url, model_name, depin_token, node_address, command_key, poll_interval, commands_processed, total_errors, rate_limited, tasks_in_flight, context_sessions, processed_cache and the last poll time.
Using it
From any DePIN client, a wallet with chat or a device, send a message to the token or to a section:
/ai Summarise the last readings I posted and tell me if anything looks abnormal.
The answer arrives in the same section, from the node address, starting with [BOT]:. Sending /ai reset clears your conversation context on the node.
| Parameter | Default | Effect |
|---|---|---|
-depinmcpkey | /ai | Prefix that triggers the model |
-depinmcpprefix | [BOT]: | Prefix of the first fragment of every reply |
-depinmcpcontext | 6 | History entries kept per sender, in user and assistant pairs. Idle contexts are dropped |
-depinmcpfragsize | 1500 | Characters per reply fragment |
-depinmcpmaxfragments | 5 | Reply is cut after this many fragments |
-depinmcpratelimit | 0 | Per-sender commands per minute |
-depinmcpglobalratelimit | 0 | Total commands per minute |
-depinmcpconcurrency | 2 | Model calls in flight at once |
-depinmcptimeout | 120 | Seconds before a model call is abandoned |
Processed message hashes are kept in mcp_processed.dat in the data directory, capped at 10,000 entries with oldest-first eviction, so a restart does not answer the same question twice.
What it does not do
Be clear about the boundaries before designing around it:
- No tools, no chain access. The model receives text and returns text. It cannot query balances, read sensors or send transactions. The system prompt is fixed.
- No routing between models. One node, one endpoint, one model.
- No device control by itself. A device that wants to act on an answer must read the
[BOT]:reply and decide what to do with it. - No memory beyond the short context. Per-sender history is a few turns in RAM.
- Trust in the operator. The node address decrypts every command addressed to it. Choose the operator as you would choose who reads your messages.
What it gives you is still valuable: a private assistant whose access control is a token you already issue, running on hardware you choose, with no accounts or API keys to hand out.
Realistic uses
| Use | How it works today |
|---|---|
| Support assistant for a project's holders | Holders of &PROJECT ask questions in the channel. The model answers with the operator's chosen weights. Nobody outside the token can use it |
| Interpreting device output | A device or a script posts readings as /ai text. The answer, a plain-language assessment, lands in the device's section where operators read it |
| Translation and summaries inside a private channel | Messages never leave the encrypted channel and never reach a third-party API when the model is local |
| Per-section assistants | Because replies go back to the section they were asked in, one node can serve &FACTORY/LINE1 and &FACTORY/LINE2 without mixing them |
Building an agent outside the node
If you need the model to do things, do not extend the node. Build a small client that reads a section, talks to a model with tool calling, and executes only the actions you allow. Every piece exists:
DePIN section ──► your script ──► model with tools ──► your script executes
(read with (Node.js) (Ollama, remote…) - RPC reads: getassetdata,
neurai-depin-msg) checkdepinvalidity, balances
- RPC writes you whitelist
- reply into the section
- Read and write the channel with
@neuraiproject/neurai-depin-msg: signed challenges,poolsigverification and decryption are handled for you. The script holds its own key and is itself a token holder. - Query the chain with
@neuraiproject/neurai-readerfor read-only data or@neuraiproject/neurai-rpcagainst your own node. - Call the model with function definitions that map to those reads, and keep any write behind an explicit allow-list and a signature by the operator.
- Post the result back as a normal message. Recipients are decided by the token, as always.
This keeps the node simple and auditable, lets you swap models and tools freely, and gives the agent an identity, its address and its token, that the chain can freeze or revoke like any other holder's.
Private chat in the browser
neurai-ai-chat is Neurai's build of WebLLM Chat: a language model that runs entirely in the browser with WebGPU. Nothing is sent to a server. It is independent from DePIN messaging and useful as a private assistant on a workstation, or as a front end for a local MLC-LLM server.
Further reading
- DePIN section: the protocol the bridge runs on.
- Running a service node: pool setup and all node flags.
- IoT development: posting readings and reading replies from an ESP32.