Metadata-Version: 2.4
Name: nrprotocol
Version: 0.1.0
Summary: Node Reach Protocol — The universal standard for AI-to-world control.
Author-email: Elmadani SALKA <Elmadani.SALKA@proton.me>
License: MIT
Project-URL: Homepage, https://github.com/ElmadaniS/nrp
Project-URL: Repository, https://github.com/ElmadaniS/nrp
Project-URL: Issues, https://github.com/ElmadaniS/nrp/issues
Keywords: ai,robotics,iot,protocol,mcp,nrp,llm,edge
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: System :: Networking
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

<div align="center">

<img src="logo.svg" width="80" alt="Halyn">

# NRP

### Node Reach Protocol

**The universal standard for AI-to-world control.**

MCP connects LLMs to software.<br>
**NRP connects LLMs to everything else.**

Servers · Robots · Drones · Sensors · Vehicles · APIs · Factories · Smart Homes

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Python 3.10+](https://img.shields.io/badge/Python-3.10+-green.svg)](https://python.org)
[![Tests](https://img.shields.io/badge/Tests-48%20passed-brightgreen.svg)]()

</div>

---

## The Problem

Every device speaks a different language. SSH for servers. ROS2 for robots. MQTT for sensors. OPC-UA for factories. REST for APIs. Hundreds of protocols. Thousands of SDKs. No standard.

MCP standardized software integration. NRP does the same for hardware and physical systems.

## The Protocol

3 methods. That is the interface.

```
OBSERVE  →  read state    (sensors, metrics, cameras, APIs)
ACT      →  change state  (commands, movements, writes, calls)
SHIELD   →  safety limits (boundaries the AI cannot cross)
```

Every device becomes a **node**. Every node has an address:

```
nrp://factory/robot/arm-7
nrp://farm/sensor/soil-north
nrp://cloud/api/stripe
nrp://home/light/kitchen
nrp://fleet/vehicle/truck-42
```

Every node **describes itself**. The AI reads the manifest and knows what to do. Zero configuration. Zero documentation.

## Write a Driver in 100 Lines

```python
from nrp import NRPDriver, NRPManifest, ChannelSpec, ActionSpec, ShieldSpec

class MyRobot(NRPDriver):

    def manifest(self) -> NRPManifest:
        return NRPManifest(
            nrp_id=self._nrp_id,
            manufacturer="Unitree", model="G1",
            observe=[
                ChannelSpec("joints", "float[]", unit="rad", rate="100Hz"),
                ChannelSpec("battery", "int", unit="percent"),
                ChannelSpec("camera", "image", rate="30Hz"),
            ],
            act=[
                ActionSpec("walk", {"speed": "float m/s"}, "Walk forward", dangerous=True),
                ActionSpec("pick", {"target": "string"}, "Pick an object", dangerous=True),
                ActionSpec("stand", {}, "Stand still"),
            ],
            shield=[
                ShieldSpec("max_speed", "limit", 1.5, "m/s"),
                ShieldSpec("workspace", "zone", [0, 0, 10, 10], "meters"),
            ],
        )

    async def observe(self, channels=None):
        return {"joints": self.read_joints(), "battery": self.read_battery()}

    async def act(self, command, args):
        if command == "walk":
            return self.walk(args["speed"])
        if command == "pick":
            return self.pick(args["target"])

    def shield_rules(self):
        return [ShieldRule("max_speed", ShieldType.LIMIT, 1.5)]
```



## What the AI Sees

When a node connects, the AI receives a human-readable description:

```
Node: nrp://factory/robot/g1-01
  Device: Unitree G1
  Observe (read state):
    joints: float[] (rad) — Joint angles at 100Hz
    battery: int (percent) — Battery level
    camera: image — Camera feed at 30Hz
  Act (commands):
    walk(speed: float m/s) [DANGEROUS] — Walk forward
    pick(target: string) [DANGEROUS] — Pick an object
    stand() — Stand still
  Shield (safety limits):
    max_speed: limit = 1.5 m/s
    workspace: zone = [0, 0, 10, 10] meters
```



## Real-Time Events

Nodes push events. The AI reacts without polling.

```python
# The node pushes
await driver.emit("battery_low", Severity.WARNING, percent=8)
await driver.emit("collision", Severity.EMERGENCY, force=45.2)

# The control plane routes
bus.subscribe("battery_*", alert_handler)
bus.subscribe("nrp://factory/*", factory_monitor)
```

**Emergency events bypass all queues** and are processed synchronously.

## Specification

| Document | Description |
|----------|-------------|
| [IDENTITY.md](spec/IDENTITY.md) | Universal addressing: `nrp://scope/kind/name` |
| [MANIFEST.md](spec/MANIFEST.md) | Self-describing nodes: channels, actions, shields |
| [EVENTS.md](spec/EVENTS.md) | Real-time push: severity levels, emergency bypass |
| [NRP_SPEC.md](spec/NRP_SPEC.md) | Protocol overview |

## Install

```bash
pip install nrp
```

## Examples

- [`hello_ssh.py`](examples/hello_ssh.py) — Connect to a server in 60 lines
- [`multi_node.py`](examples/multi_node.py) — 3 sensors, 1 conversation

## Built With NRP

| Project | Description |
|---------|-------------|
| [Halyn](https://github.com/ElmadaniS/halyn) | NRP control plane with domain-scoped authorization |

## Why Not Just Use MCP?

MCP is brilliant for software. But:

- MCP has no concept of **physical safety** (shield rules)
- MCP has no concept of **real-time events** (push, not pull)
- MCP has no concept of **self-describing hardware** (manifests)
- MCP has no concept of **universal device identity** (`nrp://`)
- MCP tools are defined by the server. NRP tools are declared by the device.

NRP complements MCP. A control plane exposes NRP nodes as MCP tools — transparent to the LLM.

## Architecture

```
Any LLM (Claude, GPT, Ollama, local)
    │
    │  MCP (software)
    │
    ▼
Control Plane (e.g. Halyn)
    │
    │  NRP (physical + digital world)
    │
    ├──→ Servers (SSH)
    ├──→ Robots (ROS2, Unitree, DJI)
    ├──→ Sensors (MQTT)
    ├──→ APIs (REST, GraphQL — auto-introspected)
    ├──→ Containers (Docker)
    ├──→ Browsers (Chrome CDP)
    ├──→ Factories (OPC-UA, Modbus)
    ├──→ Vehicles (CAN, DDS)
    └──→ Anything with an interface
```

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md). A driver is 4 methods, ~100 lines. If it has an interface, it can be an NRP node.

## License

MIT — Free forever. Use it. Build on it.

## Author

**Elmadani SALKA**
