mcp-edge 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. mcp_edge-0.1.0/.env.example +18 -0
  2. mcp_edge-0.1.0/.github/workflows/ci.yml +39 -0
  3. mcp_edge-0.1.0/.gitignore +58 -0
  4. mcp_edge-0.1.0/CHANGELOG.md +36 -0
  5. mcp_edge-0.1.0/LICENSE +21 -0
  6. mcp_edge-0.1.0/PKG-INFO +152 -0
  7. mcp_edge-0.1.0/README.md +107 -0
  8. mcp_edge-0.1.0/pyproject.toml +81 -0
  9. mcp_edge-0.1.0/src/mcp_edge/__init__.py +12 -0
  10. mcp_edge-0.1.0/src/mcp_edge/buffer.py +60 -0
  11. mcp_edge-0.1.0/src/mcp_edge/cli.py +108 -0
  12. mcp_edge-0.1.0/src/mcp_edge/client.py +72 -0
  13. mcp_edge-0.1.0/src/mcp_edge/codec.py +44 -0
  14. mcp_edge-0.1.0/src/mcp_edge/devices/__init__.py +7 -0
  15. mcp_edge-0.1.0/src/mcp_edge/devices/simulator.py +97 -0
  16. mcp_edge-0.1.0/src/mcp_edge/gateway.py +88 -0
  17. mcp_edge-0.1.0/src/mcp_edge/health.py +67 -0
  18. mcp_edge-0.1.0/src/mcp_edge/mcplite.py +99 -0
  19. mcp_edge-0.1.0/src/mcp_edge/pool.py +64 -0
  20. mcp_edge-0.1.0/src/mcp_edge/registry.py +68 -0
  21. mcp_edge-0.1.0/src/mcp_edge/schema.py +46 -0
  22. mcp_edge-0.1.0/src/mcp_edge/server.py +76 -0
  23. mcp_edge-0.1.0/src/mcp_edge/tiers.py +148 -0
  24. mcp_edge-0.1.0/src/mcp_edge/transports/__init__.py +8 -0
  25. mcp_edge-0.1.0/src/mcp_edge/transports/base.py +55 -0
  26. mcp_edge-0.1.0/src/mcp_edge/transports/loopback.py +47 -0
  27. mcp_edge-0.1.0/tests/__init__.py +1 -0
  28. mcp_edge-0.1.0/tests/test_buffer.py +83 -0
  29. mcp_edge-0.1.0/tests/test_cli.py +22 -0
  30. mcp_edge-0.1.0/tests/test_client.py +42 -0
  31. mcp_edge-0.1.0/tests/test_codec.py +34 -0
  32. mcp_edge-0.1.0/tests/test_gateway.py +69 -0
  33. mcp_edge-0.1.0/tests/test_health.py +66 -0
  34. mcp_edge-0.1.0/tests/test_mcplite.py +38 -0
  35. mcp_edge-0.1.0/tests/test_pool.py +60 -0
  36. mcp_edge-0.1.0/tests/test_registry.py +61 -0
  37. mcp_edge-0.1.0/tests/test_schema.py +76 -0
  38. mcp_edge-0.1.0/tests/test_server.py +49 -0
  39. mcp_edge-0.1.0/tests/test_simulator.py +60 -0
  40. mcp_edge-0.1.0/tests/test_smoke.py +16 -0
  41. mcp_edge-0.1.0/tests/test_tiers.py +54 -0
  42. mcp_edge-0.1.0/tests/test_transports.py +49 -0
@@ -0,0 +1,18 @@
1
+ # MCP-Edge example environment variables.
2
+ # Copy to `.env` and fill in your own values. NEVER commit your real `.env`.
3
+
4
+ # Wokwi CI — firmware-in-the-loop simulation (v0.1-0.2).
5
+ # Create a token at https://wokwi.com/dashboard/ci
6
+ WOKWI_CLI_TOKEN=
7
+
8
+ # Edge Impulse — Tier-4 inference example (v0.2).
9
+ # Project API key: EI project > Dashboard > Keys tab.
10
+ EI_API_KEY=
11
+
12
+ # Arduino IoT Cloud — device-source example (v0.2).
13
+ # OAuth2 client credentials: IoT Cloud > API keys.
14
+ ARDUINO_CLIENT_ID=
15
+ ARDUINO_CLIENT_SECRET=
16
+
17
+ # Note: your PyPI token lives in your own environment / keyring for `twine`.
18
+ # It is never stored in this repository.
@@ -0,0 +1,39 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12"]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+ - name: Install
21
+ run: |
22
+ python -m pip install --upgrade pip
23
+ pip install -e ".[dev]"
24
+ - name: Lint
25
+ run: ruff check .
26
+ - name: Test
27
+ run: pytest -q --cov=mcp_edge --cov-report=term-missing
28
+
29
+ build:
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - uses: actions/checkout@v4
33
+ - uses: actions/setup-python@v5
34
+ with:
35
+ python-version: "3.12"
36
+ - name: Build sdist and wheel
37
+ run: |
38
+ python -m pip install --upgrade pip build
39
+ python -m build
@@ -0,0 +1,58 @@
1
+ # Byte-compiled / optimized / cache
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+
7
+ # Distribution / packaging
8
+ .Python
9
+ build/
10
+ dist/
11
+ downloads/
12
+ wheels/
13
+ *.egg-info/
14
+ .eggs/
15
+ *.egg
16
+ MANIFEST
17
+
18
+ # Virtual environments
19
+ .venv/
20
+ venv/
21
+ env/
22
+ ENV/
23
+
24
+ # Environment files / secrets / credentials
25
+ .env
26
+ .env.*
27
+ !.env.example
28
+ *.key
29
+ *.pem
30
+ *secret*
31
+ *secrets*
32
+ *.eim
33
+
34
+ # Testing / coverage
35
+ .pytest_cache/
36
+ .coverage
37
+ .coverage.*
38
+ htmlcov/
39
+ coverage.xml
40
+ .tox/
41
+ .cache/
42
+
43
+ # Type checking / linting
44
+ .mypy_cache/
45
+ .ruff_cache/
46
+ .dmypy.json
47
+
48
+ # Editors / OS
49
+ .vscode/
50
+ .idea/
51
+ *.swp
52
+ .DS_Store
53
+ Thumbs.db
54
+
55
+ # Build / sim artifacts / logs
56
+ *.log
57
+ *.vcd
58
+ screenshot*.png
@@ -0,0 +1,36 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format is based on
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.0] - 2026-06-25
10
+
11
+ First public release. Alpha: the API is unstable and will change.
12
+
13
+ ### Added
14
+ - Four-tier device taxonomy (`tiers`) mapping RFC 7228 device classes to MCP
15
+ strategies, with nine reference platforms.
16
+ - CBOR codec (`codec`) for the device link, plus a JSON size-comparison helper.
17
+ - Transport abstraction (`transports`) and an in-process loopback transport.
18
+ - MCP-Lite protocol (`mcplite`): CBOR-framed `tools/list`, `tools/call`,
19
+ `resources/read`.
20
+ - Device simulator (`devices.SimulatedDevice`) for hardware-free development and tests.
21
+ - Device client layer (`client`): the `DeviceClient` interface and `MCPLiteClient`.
22
+ - Device registry (`registry`) and the aggregating `Gateway`, which exposes every
23
+ device's tools under a device-prefixed composite namespace and routes calls back.
24
+ - Gateway exposed as an MCP server (`server.build_server`, `run_stdio`) built on the
25
+ SDK's low-level `Server`.
26
+ - `mcp-edge` CLI with `run [--demo]` to serve a gateway (optionally preloaded with
27
+ simulated devices) over stdio.
28
+ - Protocol adaptations: schema caching (`schema`), connection pooling (`pool`), and
29
+ offline request buffering (`buffer`).
30
+ - Health monitor (`health`) that probes devices and updates their connection state.
31
+
32
+ ### Notes
33
+ - Real serial / BLE / Wi-Fi transports (and firmware-in-the-loop testing) arrive in a
34
+ later release; this version exercises the full path against simulated devices.
35
+ - Performance figures in the MCP-Edge paper are projected estimates, not measurements
36
+ taken from this code.
mcp_edge-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Muntaser Syed, Sheikh Abujar, and Sharun Akter
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,152 @@
1
+ Metadata-Version: 2.4
2
+ Name: mcp-edge
3
+ Version: 0.1.0
4
+ Summary: Extend the Model Context Protocol (MCP) to edge and IoT devices: a bridging gateway, a lightweight MCP-Lite server, and a four-tier device taxonomy.
5
+ Project-URL: Homepage, https://github.com/jemsbhai/mcp-edge
6
+ Project-URL: Repository, https://github.com/jemsbhai/mcp-edge
7
+ Project-URL: Issues, https://github.com/jemsbhai/mcp-edge/issues
8
+ Author: Muntaser Syed, Sheikh Abujar, Sharun Akter
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: agents,edge,embedded,gateway,iot,llm,mcp,model-context-protocol
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Internet
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Topic :: System :: Hardware
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: cbor2>=5.6
25
+ Requires-Dist: mcp<2,>=1.4
26
+ Provides-Extra: all
27
+ Requires-Dist: bleak>=0.22; extra == 'all'
28
+ Requires-Dist: pyserial>=3.5; extra == 'all'
29
+ Requires-Dist: zeroconf>=0.131; extra == 'all'
30
+ Provides-Extra: ble
31
+ Requires-Dist: bleak>=0.22; extra == 'ble'
32
+ Provides-Extra: dev
33
+ Requires-Dist: build>=1.2; extra == 'dev'
34
+ Requires-Dist: mypy>=1.10; extra == 'dev'
35
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
36
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
37
+ Requires-Dist: pytest>=8.0; extra == 'dev'
38
+ Requires-Dist: ruff>=0.6; extra == 'dev'
39
+ Requires-Dist: twine>=5.0; extra == 'dev'
40
+ Provides-Extra: serial
41
+ Requires-Dist: pyserial>=3.5; extra == 'serial'
42
+ Provides-Extra: wifi
43
+ Requires-Dist: zeroconf>=0.131; extra == 'wifi'
44
+ Description-Content-Type: text/markdown
45
+
46
+ # MCP-Edge
47
+
48
+ [![CI](https://github.com/jemsbhai/mcp-edge/actions/workflows/ci.yml/badge.svg)](https://github.com/jemsbhai/mcp-edge/actions/workflows/ci.yml)
49
+
50
+ **Extend the [Model Context Protocol (MCP)](https://modelcontextprotocol.io) to edge and IoT devices.**
51
+
52
+ MCP-Edge lets cloud LLM agents discover and invoke physical hardware through the same
53
+ tool interface they already use for software APIs. It provides:
54
+
55
+ - a **gateway** that bridges cloud-native MCP transports (SSE / HTTP) to constrained
56
+ device channels (UART, BLE, local Wi-Fi), presenting every downstream device as a
57
+ standard MCP tool provider;
58
+ - **MCP-Lite**, a lightweight MCP server for devices with as little as ~512 KB of RAM;
59
+ - a **four-tier device taxonomy** (constrained MCUs, smart IoT nodes, BLE-only
60
+ wearables, Linux-class edge computers) that maps an MCP strategy to each tier;
61
+ - protocol adaptations for constrained links: CBOR encoding, schema caching,
62
+ connection pooling, and offline request buffering.
63
+
64
+ > **Status: alpha, under active development.** The public API is unstable and will
65
+ > change. This repository is a *reference implementation* of the framework described in
66
+ > the MCP-Edge paper (IEEE Cloud Summit 2026). Performance figures reported in the paper
67
+ > are projected estimates, not measurements taken from this codebase. This release
68
+ > exercises the full gateway path against *simulated* devices; real serial/BLE/Wi-Fi
69
+ > transports arrive in a later version.
70
+
71
+ ## Installation
72
+
73
+ Requires Python 3.10+.
74
+
75
+ ```bash
76
+ pip install mcp-edge
77
+ ```
78
+
79
+ For development, install from source:
80
+
81
+ ```bash
82
+ git clone https://github.com/jemsbhai/mcp-edge
83
+ cd mcp-edge
84
+ pip install -e ".[dev]"
85
+ ```
86
+
87
+ ## Quickstart
88
+
89
+ **Run a demo gateway** — an MCP server exposing two simulated devices over stdio:
90
+
91
+ ```bash
92
+ mcp-edge run --demo
93
+ ```
94
+
95
+ This serves a simulated sensor (`read_temp`, `read_humidity`) and a simulated ring
96
+ (`heart_rate`), each tool namespaced by device (`sensor-01/read_temp`, ...). To drive it
97
+ from an MCP client such as the MCP Inspector or Claude Desktop, configure a stdio server
98
+ with command `mcp-edge` and arguments `["run", "--demo"]`. The process logs to stderr and
99
+ waits for a client on stdin.
100
+
101
+ **Use the gateway as a library:**
102
+
103
+ ```python
104
+ import asyncio
105
+
106
+ from mcp_edge.client import MCPLiteClient
107
+ from mcp_edge.devices import SimulatedDevice
108
+ from mcp_edge.gateway import Gateway
109
+ from mcp_edge.registry import DeviceRegistry
110
+ from mcp_edge.tiers import Tier
111
+ from mcp_edge.transports import LoopbackTransport
112
+
113
+
114
+ async def main() -> None:
115
+ device = SimulatedDevice("sensor-01")
116
+ device.add_tool("read_temp", lambda args: {"celsius": 21.5})
117
+
118
+ transport = LoopbackTransport(device.handle)
119
+ await transport.open()
120
+
121
+ registry = DeviceRegistry()
122
+ registry.register("sensor-01", MCPLiteClient(transport), Tier.SMART_NODE)
123
+
124
+ gateway = Gateway(registry)
125
+ print([tool["name"] for tool in await gateway.list_tools()]) # ['sensor-01/read_temp']
126
+ print(await gateway.call_tool("sensor-01/read_temp", {})) # {'celsius': 21.5}
127
+
128
+
129
+ asyncio.run(main())
130
+ ```
131
+
132
+ ## Roadmap
133
+
134
+ - [x] **v0.1** — gateway core, in-process (loopback) transport, protocol adaptations
135
+ (CBOR, schema caching, connection pooling, offline buffering), device simulator,
136
+ health monitor, CLI, hermetic CI
137
+ - [ ] **v0.2** — real transports (`pyserial` UART/USB, BLE, Wi-Fi/mDNS) and
138
+ [Wokwi](https://wokwi.com) firmware-in-the-loop tests (Arduino / ESP32 / RP2040)
139
+ - [ ] **v0.2+** — Edge Impulse (inference as an MCP tool) and Arduino IoT Cloud
140
+ (properties as MCP) integration examples; Renode / QEMU backends
141
+
142
+ ## Development
143
+
144
+ ```powershell
145
+ pip install -e ".[dev]"
146
+ pytest -q
147
+ ruff check .
148
+ ```
149
+
150
+ ## License
151
+
152
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,107 @@
1
+ # MCP-Edge
2
+
3
+ [![CI](https://github.com/jemsbhai/mcp-edge/actions/workflows/ci.yml/badge.svg)](https://github.com/jemsbhai/mcp-edge/actions/workflows/ci.yml)
4
+
5
+ **Extend the [Model Context Protocol (MCP)](https://modelcontextprotocol.io) to edge and IoT devices.**
6
+
7
+ MCP-Edge lets cloud LLM agents discover and invoke physical hardware through the same
8
+ tool interface they already use for software APIs. It provides:
9
+
10
+ - a **gateway** that bridges cloud-native MCP transports (SSE / HTTP) to constrained
11
+ device channels (UART, BLE, local Wi-Fi), presenting every downstream device as a
12
+ standard MCP tool provider;
13
+ - **MCP-Lite**, a lightweight MCP server for devices with as little as ~512 KB of RAM;
14
+ - a **four-tier device taxonomy** (constrained MCUs, smart IoT nodes, BLE-only
15
+ wearables, Linux-class edge computers) that maps an MCP strategy to each tier;
16
+ - protocol adaptations for constrained links: CBOR encoding, schema caching,
17
+ connection pooling, and offline request buffering.
18
+
19
+ > **Status: alpha, under active development.** The public API is unstable and will
20
+ > change. This repository is a *reference implementation* of the framework described in
21
+ > the MCP-Edge paper (IEEE Cloud Summit 2026). Performance figures reported in the paper
22
+ > are projected estimates, not measurements taken from this codebase. This release
23
+ > exercises the full gateway path against *simulated* devices; real serial/BLE/Wi-Fi
24
+ > transports arrive in a later version.
25
+
26
+ ## Installation
27
+
28
+ Requires Python 3.10+.
29
+
30
+ ```bash
31
+ pip install mcp-edge
32
+ ```
33
+
34
+ For development, install from source:
35
+
36
+ ```bash
37
+ git clone https://github.com/jemsbhai/mcp-edge
38
+ cd mcp-edge
39
+ pip install -e ".[dev]"
40
+ ```
41
+
42
+ ## Quickstart
43
+
44
+ **Run a demo gateway** — an MCP server exposing two simulated devices over stdio:
45
+
46
+ ```bash
47
+ mcp-edge run --demo
48
+ ```
49
+
50
+ This serves a simulated sensor (`read_temp`, `read_humidity`) and a simulated ring
51
+ (`heart_rate`), each tool namespaced by device (`sensor-01/read_temp`, ...). To drive it
52
+ from an MCP client such as the MCP Inspector or Claude Desktop, configure a stdio server
53
+ with command `mcp-edge` and arguments `["run", "--demo"]`. The process logs to stderr and
54
+ waits for a client on stdin.
55
+
56
+ **Use the gateway as a library:**
57
+
58
+ ```python
59
+ import asyncio
60
+
61
+ from mcp_edge.client import MCPLiteClient
62
+ from mcp_edge.devices import SimulatedDevice
63
+ from mcp_edge.gateway import Gateway
64
+ from mcp_edge.registry import DeviceRegistry
65
+ from mcp_edge.tiers import Tier
66
+ from mcp_edge.transports import LoopbackTransport
67
+
68
+
69
+ async def main() -> None:
70
+ device = SimulatedDevice("sensor-01")
71
+ device.add_tool("read_temp", lambda args: {"celsius": 21.5})
72
+
73
+ transport = LoopbackTransport(device.handle)
74
+ await transport.open()
75
+
76
+ registry = DeviceRegistry()
77
+ registry.register("sensor-01", MCPLiteClient(transport), Tier.SMART_NODE)
78
+
79
+ gateway = Gateway(registry)
80
+ print([tool["name"] for tool in await gateway.list_tools()]) # ['sensor-01/read_temp']
81
+ print(await gateway.call_tool("sensor-01/read_temp", {})) # {'celsius': 21.5}
82
+
83
+
84
+ asyncio.run(main())
85
+ ```
86
+
87
+ ## Roadmap
88
+
89
+ - [x] **v0.1** — gateway core, in-process (loopback) transport, protocol adaptations
90
+ (CBOR, schema caching, connection pooling, offline buffering), device simulator,
91
+ health monitor, CLI, hermetic CI
92
+ - [ ] **v0.2** — real transports (`pyserial` UART/USB, BLE, Wi-Fi/mDNS) and
93
+ [Wokwi](https://wokwi.com) firmware-in-the-loop tests (Arduino / ESP32 / RP2040)
94
+ - [ ] **v0.2+** — Edge Impulse (inference as an MCP tool) and Arduino IoT Cloud
95
+ (properties as MCP) integration examples; Renode / QEMU backends
96
+
97
+ ## Development
98
+
99
+ ```powershell
100
+ pip install -e ".[dev]"
101
+ pytest -q
102
+ ruff check .
103
+ ```
104
+
105
+ ## License
106
+
107
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,81 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "mcp-edge"
7
+ dynamic = ["version"]
8
+ description = "Extend the Model Context Protocol (MCP) to edge and IoT devices: a bridging gateway, a lightweight MCP-Lite server, and a four-tier device taxonomy."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "Muntaser Syed" },
14
+ { name = "Sheikh Abujar" },
15
+ { name = "Sharun Akter" },
16
+ ]
17
+ keywords = ["mcp", "model-context-protocol", "edge", "iot", "llm", "agents", "gateway", "embedded"]
18
+ classifiers = [
19
+ "Development Status :: 3 - Alpha",
20
+ "Intended Audience :: Developers",
21
+ "License :: OSI Approved :: MIT License",
22
+ "Operating System :: OS Independent",
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Python :: 3.10",
25
+ "Programming Language :: Python :: 3.11",
26
+ "Programming Language :: Python :: 3.12",
27
+ "Topic :: Internet",
28
+ "Topic :: System :: Hardware",
29
+ "Topic :: Software Development :: Libraries :: Python Modules",
30
+ ]
31
+ dependencies = [
32
+ "mcp>=1.4,<2",
33
+ "cbor2>=5.6",
34
+ ]
35
+
36
+ [project.optional-dependencies]
37
+ serial = ["pyserial>=3.5"]
38
+ ble = ["bleak>=0.22"]
39
+ wifi = ["zeroconf>=0.131"]
40
+ all = ["mcp-edge[serial,ble,wifi]"]
41
+ dev = [
42
+ "pytest>=8.0",
43
+ "pytest-asyncio>=0.23",
44
+ "pytest-cov>=5.0",
45
+ "ruff>=0.6",
46
+ "mypy>=1.10",
47
+ "build>=1.2",
48
+ "twine>=5.0",
49
+ ]
50
+
51
+ [project.scripts]
52
+ mcp-edge = "mcp_edge.cli:main"
53
+
54
+ [project.urls]
55
+ Homepage = "https://github.com/jemsbhai/mcp-edge"
56
+ Repository = "https://github.com/jemsbhai/mcp-edge"
57
+ Issues = "https://github.com/jemsbhai/mcp-edge/issues"
58
+
59
+ [tool.hatch.version]
60
+ path = "src/mcp_edge/__init__.py"
61
+
62
+ [tool.hatch.build.targets.wheel]
63
+ packages = ["src/mcp_edge"]
64
+
65
+ [tool.pytest.ini_options]
66
+ testpaths = ["tests"]
67
+ asyncio_mode = "auto"
68
+ addopts = "-ra"
69
+
70
+ [tool.ruff]
71
+ line-length = 100
72
+ target-version = "py310"
73
+ src = ["src", "tests"]
74
+
75
+ [tool.ruff.lint]
76
+ select = ["E", "F", "I", "UP", "B", "W"]
77
+
78
+ [tool.mypy]
79
+ python_version = "3.10"
80
+ ignore_missing_imports = true
81
+ warn_unused_ignores = true
@@ -0,0 +1,12 @@
1
+ """MCP-Edge: extend the Model Context Protocol (MCP) to edge and IoT devices.
2
+
3
+ An early, in-development reference implementation of the MCP-Edge framework:
4
+ a gateway that bridges cloud-native MCP transports to constrained-device
5
+ channels, a lightweight MCP-Lite server, and a four-tier device taxonomy.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ __version__ = "0.1.0"
11
+
12
+ __all__ = ["__version__"]
@@ -0,0 +1,60 @@
1
+ """Offline request buffering.
2
+
3
+ When a device is briefly unreachable, the gateway can buffer operations destined for it
4
+ and replay them in order once it returns, rather than dropping them. The buffer is a
5
+ bounded FIFO; on overflow it raises rather than silently discarding, and a flush that
6
+ fails part-way leaves the failed item (and the rest) queued for the next attempt.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from collections import deque
12
+ from collections.abc import Awaitable, Callable
13
+ from typing import Generic, TypeVar
14
+
15
+ T = TypeVar("T")
16
+
17
+
18
+ class BufferFull(RuntimeError):
19
+ """Raised when enqueuing onto a full buffer."""
20
+
21
+
22
+ class OfflineBuffer(Generic[T]):
23
+ """A bounded FIFO buffer of operations for a temporarily unreachable device."""
24
+
25
+ def __init__(self, *, max_size: int = 128) -> None:
26
+ self.max_size = max_size
27
+ self._items: deque[T] = deque()
28
+
29
+ def __len__(self) -> int:
30
+ return len(self._items)
31
+
32
+ @property
33
+ def is_full(self) -> bool:
34
+ return len(self._items) >= self.max_size
35
+
36
+ def enqueue(self, item: T) -> None:
37
+ """Append ``item``; raises :class:`BufferFull` if the buffer is full."""
38
+ if self.is_full:
39
+ raise BufferFull(f"buffer is full (max_size={self.max_size})")
40
+ self._items.append(item)
41
+
42
+ async def flush(self, handler: Callable[[T], Awaitable[None]]) -> int:
43
+ """Apply ``handler`` to each item in FIFO order, removing it on success.
44
+
45
+ Returns the number flushed. If ``handler`` raises, the failed item stays at the
46
+ front (and the remaining items stay queued) so the operation can be retried.
47
+ """
48
+ count = 0
49
+ while self._items:
50
+ await handler(self._items[0])
51
+ self._items.popleft()
52
+ count += 1
53
+ return count
54
+
55
+ def clear(self) -> None:
56
+ """Discard all buffered items."""
57
+ self._items.clear()
58
+
59
+
60
+ __all__ = ["OfflineBuffer", "BufferFull"]