weaver-kernel 0.3.0__tar.gz → 0.5.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 (66) hide show
  1. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/.github/workflows/ci.yml +29 -0
  2. weaver_kernel-0.5.0/.github/workflows/publish.yml +74 -0
  3. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/AGENTS.md +4 -1
  4. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/CHANGELOG.md +21 -0
  5. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/PKG-INFO +16 -2
  6. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/README.md +13 -0
  7. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/RELEASE.md +6 -5
  8. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/docs/agent-context/invariants.md +4 -1
  9. weaver_kernel-0.5.0/docs/integrations.md +130 -0
  10. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/docs/security.md +5 -1
  11. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/pyproject.toml +3 -2
  12. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/__init__.py +3 -1
  13. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/drivers/__init__.py +2 -1
  14. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/drivers/http.py +1 -1
  15. weaver_kernel-0.5.0/src/agent_kernel/drivers/mcp.py +236 -0
  16. weaver_kernel-0.5.0/src/agent_kernel/drivers/mcp_support.py +154 -0
  17. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/firewall/transform.py +0 -6
  18. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/policy.py +113 -1
  19. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/tests/test_drivers.py +134 -2
  20. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/tests/test_firewall.py +131 -0
  21. weaver_kernel-0.5.0/tests/test_mcp_driver.py +298 -0
  22. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/tests/test_policy.py +205 -29
  23. weaver_kernel-0.3.0/.github/workflows/publish.yml +0 -35
  24. weaver_kernel-0.3.0/docs/integrations.md +0 -70
  25. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/.claude/CLAUDE.md +0 -0
  26. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/.github/copilot-instructions.md +0 -0
  27. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/.gitignore +0 -0
  28. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/CONTRIBUTING.md +0 -0
  29. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/LICENSE +0 -0
  30. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/Makefile +0 -0
  31. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/docs/agent-context/architecture.md +0 -0
  32. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/docs/agent-context/lessons-learned.md +0 -0
  33. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/docs/agent-context/review-checklist.md +0 -0
  34. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/docs/agent-context/workflows.md +0 -0
  35. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/docs/architecture.md +0 -0
  36. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/docs/capabilities.md +0 -0
  37. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/docs/context_firewall.md +0 -0
  38. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/examples/basic_cli.py +0 -0
  39. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/examples/billing_demo.py +0 -0
  40. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/examples/http_driver_demo.py +0 -0
  41. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/drivers/base.py +0 -0
  42. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/drivers/memory.py +0 -0
  43. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/enums.py +0 -0
  44. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/errors.py +0 -0
  45. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/firewall/__init__.py +0 -0
  46. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/firewall/budgets.py +0 -0
  47. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/firewall/redaction.py +0 -0
  48. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/firewall/summarize.py +0 -0
  49. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/handles.py +0 -0
  50. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/kernel.py +0 -0
  51. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/models.py +0 -0
  52. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/py.typed +0 -0
  53. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/registry.py +0 -0
  54. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/router.py +0 -0
  55. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/tokens.py +0 -0
  56. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/src/agent_kernel/trace.py +0 -0
  57. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/tests/conftest.py +0 -0
  58. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/tests/test_handles.py +0 -0
  59. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/tests/test_kernel.py +0 -0
  60. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/tests/test_logging.py +0 -0
  61. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/tests/test_models.py +0 -0
  62. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/tests/test_redaction.py +0 -0
  63. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/tests/test_registry.py +0 -0
  64. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/tests/test_router.py +0 -0
  65. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/tests/test_tokens.py +0 -0
  66. {weaver_kernel-0.3.0 → weaver_kernel-0.5.0}/tests/test_trace.py +0 -0
@@ -45,3 +45,32 @@ jobs:
45
45
  python examples/basic_cli.py
46
46
  python examples/billing_demo.py
47
47
  python examples/http_driver_demo.py
48
+
49
+ conformance_stub:
50
+ name: "Weaver Spec Conformance Stub (v0.1.0)"
51
+ runs-on: ubuntu-latest
52
+ needs: test
53
+ permissions:
54
+ contents: read
55
+
56
+ steps:
57
+ - uses: actions/checkout@v4
58
+
59
+ - name: Set up Python
60
+ uses: actions/setup-python@v5
61
+ with:
62
+ python-version: "3.12"
63
+
64
+ - name: Install dependencies
65
+ run: pip install -e ".[dev]"
66
+
67
+ # Placeholder: activate once dgenio/weaver-spec#4 ships the conformance runner.
68
+ # weaver-spec and weaver-contracts are published on PyPI.
69
+ # weaver_contracts.conformance does not yet exist (dgenio/weaver-spec#4).
70
+ # Replace this step with:
71
+ # pip install weaver-contracts # PyPI dist name uses a hyphen
72
+ # python -m weaver_contracts.conformance --target agent_kernel
73
+ - name: weaver-spec conformance suite (stub)
74
+ run: |
75
+ echo "weaver-contracts 0.2.0 is on PyPI; weaver_contracts.conformance runner not yet available (dgenio/weaver-spec#4)."
76
+ echo "Stub passes. Activate when dgenio/weaver-spec#4 ships."
@@ -0,0 +1,74 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ jobs:
8
+ ci:
9
+ name: "CI gate"
10
+ uses: ./.github/workflows/ci.yml
11
+
12
+ build:
13
+ name: "Build"
14
+ needs: ci
15
+ runs-on: ubuntu-latest
16
+ permissions:
17
+ contents: read
18
+ steps:
19
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
20
+
21
+ - name: Set up Python
22
+ uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
23
+ with:
24
+ python-version: "3.12"
25
+
26
+ - name: Install build tools
27
+ run: pip install build
28
+
29
+ - name: Build sdist and wheel
30
+ run: python -m build
31
+
32
+ - name: Upload dist artifacts
33
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
34
+ with:
35
+ name: dist
36
+ path: dist/
37
+
38
+ release:
39
+ name: "GitHub Release"
40
+ needs: build
41
+ runs-on: ubuntu-latest
42
+ permissions:
43
+ contents: write # required to create releases
44
+ steps:
45
+ - name: Download dist artifacts
46
+ uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
47
+ with:
48
+ name: dist
49
+ path: dist/
50
+
51
+ - name: Create GitHub Release
52
+ uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
53
+ with:
54
+ generate_release_notes: true
55
+ fail_on_unmatched_files: true
56
+ files: dist/*
57
+
58
+ publish:
59
+ name: "Publish to PyPI"
60
+ needs: release
61
+ runs-on: ubuntu-latest
62
+ environment: pypi
63
+ permissions:
64
+ contents: read
65
+ id-token: write # required for Trusted Publisher (OIDC)
66
+ steps:
67
+ - name: Download dist artifacts
68
+ uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
69
+ with:
70
+ name: dist
71
+ path: dist/
72
+
73
+ - name: Publish to PyPI
74
+ uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
@@ -25,9 +25,12 @@ agent-kernel is part of the **Weaver ecosystem**:
25
25
 
26
26
  This repo must conform to weaver-spec invariants. Key invariants (all equally critical):
27
27
  - **I-01**: Every tool output must pass through a context boundary before reaching the LLM.
28
- - **I-02**: Context boundaries must enforce budgets (size, depth, field count).
28
+ - **I-02**: Every execution must be authorized and auditable (preceded by a policy decision, followed by a trace event).
29
29
  - **I-06**: Tokens must bind principal + capability + constraints; no reuse across principals.
30
30
 
31
+ Note: Budget enforcement (size, depth, field count) is an agent-kernel implementation
32
+ constraint that satisfies I-01 — it is not a separate weaver-spec invariant number.
33
+
31
34
  Full spec: [dgenio/weaver-spec](https://github.com/dgenio/weaver-spec)
32
35
 
33
36
  ## Domain vocabulary
@@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.0] - 2026-04-12
11
+
12
+ ### Added
13
+ - Built-in `MCPDriver` with stdio and Streamable HTTP transports, tool auto-discovery, normalized MCP result handling, and optional dependency guardrails.
14
+ - Declared weaver-spec v0.1.0 compatibility in README: invariants I-01 (firewall), I-02 (authorization + audit), and I-06 (scoped tokens) are satisfied.
15
+ - Added placeholder `conformance_stub` CI job that will activate once the weaver-spec conformance suite ships (dgenio/weaver-spec#4).
16
+
17
+ ## [0.4.0] - 2026-03-14
18
+
19
+ ### Added
20
+ - Sliding-window rate limiting in `DefaultPolicyEngine` per `(principal_id, capability_id)` pair (#39).
21
+ Default limits by safety class: 60 READ / 10 WRITE / 2 DESTRUCTIVE per 60s window.
22
+ Service-role principals get 10× limits. Configurable via constructor.
23
+ - GitHub Release step in publish workflow — creates a release with auto-generated notes and artifacts before publishing to PyPI.
24
+
25
+ ### Fixed
26
+ - `HTTPDriver`: DELETE requests now forward args as query params instead of silently dropping them.
27
+
28
+ ### Removed
29
+ - Dead `_truncate_str` helper in `firewall/transform.py` (defined but never called).
30
+
10
31
  ## [0.3.0] - 2026-03-09
11
32
 
12
33
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: weaver-kernel
3
- Version: 0.3.0
3
+ Version: 0.5.0
4
4
  Summary: Capability-based security kernel for AI agents operating in large tool ecosystems
5
5
  Project-URL: Homepage, https://github.com/dgenio/agent-kernel
6
6
  Project-URL: Repository, https://github.com/dgenio/agent-kernel
@@ -223,13 +223,14 @@ Requires-Python: >=3.10
223
223
  Requires-Dist: httpx>=0.27
224
224
  Provides-Extra: dev
225
225
  Requires-Dist: httpx>=0.27; extra == 'dev'
226
+ Requires-Dist: mcp>=1.6; extra == 'dev'
226
227
  Requires-Dist: mypy>=1.10; extra == 'dev'
227
228
  Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
228
229
  Requires-Dist: pytest-cov>=5.0; extra == 'dev'
229
230
  Requires-Dist: pytest>=8.0; extra == 'dev'
230
231
  Requires-Dist: ruff>=0.4; extra == 'dev'
231
232
  Provides-Extra: mcp
232
- Requires-Dist: mcp>=1.0; extra == 'mcp'
233
+ Requires-Dist: mcp>=1.6; extra == 'mcp'
233
234
  Provides-Extra: otel
234
235
  Requires-Dist: opentelemetry-api>=1.20; extra == 'otel'
235
236
  Description-Content-Type: text/markdown
@@ -346,6 +347,19 @@ asyncio.run(main())
346
347
 
347
348
  `agent-kernel` sits **above** `contextweaver` (context compilation) and **above** raw tool execution. It provides the authorization, execution, and audit layer.
348
349
 
350
+ ## Weaver Spec Compatibility: v0.1.0
351
+
352
+ agent-kernel is a compliant implementation of [weaver-spec v0.1.0](https://github.com/dgenio/weaver-spec).
353
+ The following invariants are satisfied:
354
+
355
+ | Invariant | Description | How agent-kernel satisfies it |
356
+ |-----------|-------------|-------------------------------|
357
+ | **I-01** | LLM never sees raw tool output by default | `Context Firewall` always transforms `RawResult → Frame`; raw driver output is not returned by default, and non-admin principals cannot obtain `raw` response mode |
358
+ | **I-02** | Every execution is authorized and auditable | `PolicyEngine` authorizes at grant time; a valid `CapabilityToken` (HMAC-verified on every `invoke()`) carries the authorization decision; `TraceStore` records every `ActionTrace` |
359
+ | **I-06** | CapabilityTokens are scoped | Tokens bind `principal_id + capability_id + constraints` with an explicit TTL; `revoke(token_id)` / `revoke_all(principal_id)` are supported |
360
+
361
+ See [docs/agent-context/invariants.md](docs/agent-context/invariants.md) for the full internal invariant list and [weaver-spec INVARIANTS.md](https://github.com/dgenio/weaver-spec/blob/main/docs/INVARIANTS.md) for the specification.
362
+
349
363
  ## Security disclaimers
350
364
 
351
365
  > **v0.1 is not production-hardened for real authentication.**
@@ -110,6 +110,19 @@ asyncio.run(main())
110
110
 
111
111
  `agent-kernel` sits **above** `contextweaver` (context compilation) and **above** raw tool execution. It provides the authorization, execution, and audit layer.
112
112
 
113
+ ## Weaver Spec Compatibility: v0.1.0
114
+
115
+ agent-kernel is a compliant implementation of [weaver-spec v0.1.0](https://github.com/dgenio/weaver-spec).
116
+ The following invariants are satisfied:
117
+
118
+ | Invariant | Description | How agent-kernel satisfies it |
119
+ |-----------|-------------|-------------------------------|
120
+ | **I-01** | LLM never sees raw tool output by default | `Context Firewall` always transforms `RawResult → Frame`; raw driver output is not returned by default, and non-admin principals cannot obtain `raw` response mode |
121
+ | **I-02** | Every execution is authorized and auditable | `PolicyEngine` authorizes at grant time; a valid `CapabilityToken` (HMAC-verified on every `invoke()`) carries the authorization decision; `TraceStore` records every `ActionTrace` |
122
+ | **I-06** | CapabilityTokens are scoped | Tokens bind `principal_id + capability_id + constraints` with an explicit TTL; `revoke(token_id)` / `revoke_all(principal_id)` are supported |
123
+
124
+ See [docs/agent-context/invariants.md](docs/agent-context/invariants.md) for the full internal invariant list and [weaver-spec INVARIANTS.md](https://github.com/dgenio/weaver-spec/blob/main/docs/INVARIANTS.md) for the specification.
125
+
113
126
  ## Security disclaimers
114
127
 
115
128
  > **v0.1 is not production-hardened for real authentication.**
@@ -16,7 +16,7 @@ Update the `version` field in `pyproject.toml`:
16
16
 
17
17
  ```toml
18
18
  [project]
19
- version = "0.3.0"
19
+ version = "0.4.0"
20
20
  ```
21
21
 
22
22
  ### 2. Update the changelog
@@ -25,7 +25,7 @@ Add a new section to `CHANGELOG.md` under `## [Unreleased]`, then rename it
25
25
  to the new version with today's date:
26
26
 
27
27
  ```markdown
28
- ## [0.3.0] - 2026-04-01
28
+ ## [0.4.0] - 2026-03-14
29
29
 
30
30
  ### Added
31
31
  - ...
@@ -42,8 +42,8 @@ to the new version with today's date:
42
42
 
43
43
  ```bash
44
44
  git add pyproject.toml CHANGELOG.md
45
- git commit -m "release: v0.3.0"
46
- git tag v0.3.0
45
+ git commit -m "release: v0.4.0"
46
+ git tag v0.4.0
47
47
  git push origin main --tags
48
48
  ```
49
49
 
@@ -53,7 +53,8 @@ Pushing the `v*` tag triggers `.github/workflows/publish.yml`, which:
53
53
 
54
54
  1. Runs the full CI suite (`make ci` equivalent) as a gate.
55
55
  2. Builds the sdist and wheel with `python -m build`.
56
- 3. Publishes to PyPI using Trusted Publisher (OIDC no API tokens stored).
56
+ 3. Creates a GitHub Release with auto-generated notes and the built artifacts attached.
57
+ 4. Publishes to PyPI using Trusted Publisher (OIDC — no API tokens stored).
57
58
 
58
59
  Monitor the workflow run at:
59
60
  <https://github.com/dgenio/agent-kernel/actions/workflows/publish.yml>
@@ -11,9 +11,12 @@ All three are equally critical — there is no priority ordering.
11
11
  | Invariant | Requirement | Where enforced |
12
12
  |-----------|-------------|----------------|
13
13
  | **I-01** | Every tool output must pass through a context boundary before reaching the LLM | `Firewall.transform()` in `firewall/transform.py` |
14
- | **I-02** | Context boundaries must enforce budgets (size, depth, field count) | `Budgets` in `firewall/budgets.py` |
14
+ | **I-02** | Every execution must be authorized and auditable (CapabilityToken validated before execution; TraceEvent recorded after) | `HMACTokenProvider.verify()` + `TraceStore.record()` in `kernel.py`; `PolicyEngine.evaluate()` at grant time in `grant_capability()` |
15
15
  | **I-06** | Tokens must bind principal + capability + constraints; no reuse across principals | `HMACTokenProvider.verify()` in `tokens.py` |
16
16
 
17
+ > **Budget enforcement** (size, depth, field count via `Budgets` in `firewall/budgets.py`) is an
18
+ > implementation constraint that strengthens I-01. It has no separate invariant number in weaver-spec.
19
+
17
20
  ## Forbidden shortcuts — "never do" list
18
21
 
19
22
  These constraints are non-negotiable. Violating any one silently degrades security.
@@ -0,0 +1,130 @@
1
+ # Integrations
2
+
3
+ ## MCP (Model Context Protocol)
4
+
5
+ The built-in `MCPDriver` supports both local stdio servers and remote Streamable HTTP servers.
6
+
7
+ Install the optional dependency first:
8
+
9
+ ```bash
10
+ pip install "weaver-kernel[mcp]"
11
+ ```
12
+
13
+ ### Stdio transport
14
+
15
+ ```python
16
+ import asyncio
17
+
18
+ from agent_kernel import CapabilityRegistry, Kernel, StaticRouter
19
+ from agent_kernel.drivers.mcp import MCPDriver
20
+
21
+
22
+ async def main() -> None:
23
+ registry = CapabilityRegistry()
24
+ router = StaticRouter(fallback=[])
25
+ kernel = Kernel(registry=registry, router=router)
26
+
27
+ # Connect to a local MCP server process.
28
+ driver = MCPDriver.from_stdio(
29
+ command="python",
30
+ args=["-m", "my_mcp_server"],
31
+ server_name="local-tools",
32
+ )
33
+ kernel.register_driver(driver)
34
+
35
+ # Discover tools and register them as capabilities.
36
+ capabilities = await driver.discover(namespace="local")
37
+ registry.register_many(capabilities)
38
+
39
+ # Route each discovered capability to this MCP driver.
40
+ for capability in capabilities:
41
+ router.add_route(capability.capability_id, [driver.driver_id])
42
+
43
+
44
+ asyncio.run(main())
45
+ ```
46
+
47
+ ### Streamable HTTP transport
48
+
49
+ ```python
50
+ import asyncio
51
+
52
+ from agent_kernel import CapabilityRegistry, Kernel, StaticRouter
53
+ from agent_kernel.drivers.mcp import MCPDriver
54
+
55
+
56
+ async def main() -> None:
57
+ registry = CapabilityRegistry()
58
+ router = StaticRouter(fallback=[])
59
+ kernel = Kernel(registry=registry, router=router)
60
+
61
+ # Connect to a remote Streamable HTTP MCP server.
62
+ # Note: max_retries > 0 creates at-least-once delivery semantics for
63
+ # tools/call — if a connection drops after the server processes the
64
+ # request but before the response arrives, the call will be repeated.
65
+ # Ensure target tools are idempotent, or set max_retries=0 for
66
+ # WRITE/DESTRUCTIVE capabilities.
67
+ driver = MCPDriver.from_http(
68
+ url="https://example.com/mcp",
69
+ server_name="remote-tools",
70
+ max_retries=1,
71
+ )
72
+ kernel.register_driver(driver)
73
+
74
+ # Discover tools and register them as capabilities.
75
+ capabilities = await driver.discover(namespace="remote")
76
+ registry.register_many(capabilities)
77
+
78
+ # Route each discovered capability to this MCP driver.
79
+ for capability in capabilities:
80
+ router.add_route(capability.capability_id, [driver.driver_id])
81
+
82
+
83
+ asyncio.run(main())
84
+ ```
85
+
86
+ ### Notes
87
+
88
+ - `discover()` converts `tools/list` results into `Capability` objects.
89
+ - `execute()` calls `tools/call` and normalizes MCP content blocks for the firewall.
90
+ - MCP `isError` responses raise `DriverError` with the server-provided detail.
91
+ - If `mcp` is not installed, factory methods raise a helpful `ImportError`.
92
+
93
+ ## HTTPDriver
94
+
95
+ The built-in `HTTPDriver` supports GET, POST, PUT, DELETE:
96
+
97
+ ```python
98
+ from agent_kernel.drivers.http import HTTPDriver, HTTPEndpoint
99
+
100
+ driver = HTTPDriver(driver_id="my_api")
101
+ driver.register_endpoint("users.list", HTTPEndpoint(
102
+ url="https://api.example.com/users",
103
+ method="GET",
104
+ headers={"Authorization": "Bearer ..."},
105
+ ))
106
+ kernel.register_driver(driver)
107
+ ```
108
+
109
+ ## Custom drivers
110
+
111
+ Any object implementing the `Driver` protocol can be registered:
112
+
113
+ ```python
114
+ class Driver(Protocol):
115
+ @property
116
+ def driver_id(self) -> str: ...
117
+ async def execute(self, ctx: ExecutionContext) -> RawResult: ...
118
+ ```
119
+
120
+ ## Capability mapping
121
+
122
+ When mapping MCP tools to capabilities, prefer task-shaped names:
123
+
124
+ | MCP tool | Capability ID | Safety class |
125
+ |----------|--------------|--------------|
126
+ | `list_files` | `fs.list_files` | READ |
127
+ | `read_file` | `fs.read_file` | READ |
128
+ | `write_file` | `fs.write_file` | WRITE |
129
+ | `delete_file` | `fs.delete_file` | DESTRUCTIVE |
130
+ | `execute_code` | `sandbox.run_code` | DESTRUCTIVE |
@@ -35,4 +35,8 @@ Consider an agent that obtains a token for `billing.list_invoices` then passes i
35
35
  - The `AGENT_KERNEL_SECRET` must be kept secret. Rotate it if compromised.
36
36
  - The default `InMemoryDriver` has no persistence — suitable for testing only.
37
37
  - PII redaction is heuristic (regex-based). It is not a substitute for proper data governance.
38
- - There is no rate limiting or quota enforcement in v0.1.
38
+ - Rate limiting is enforced per `(principal_id, capability_id)` pair using a sliding window.
39
+ Default limits: 60 READ / 10 WRITE / 2 DESTRUCTIVE invocations per 60-second window.
40
+ Principals with the `"service"` role receive 10× the default limits. Limits are
41
+ configurable via `DefaultPolicyEngine(rate_limits=...)`. There is no distributed or
42
+ persistent rate-limit state — limits reset on process restart.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "weaver-kernel"
7
- version = "0.3.0"
7
+ version = "0.5.0"
8
8
  description = "Capability-based security kernel for AI agents operating in large tool ecosystems"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -38,8 +38,9 @@ dev = [
38
38
  "ruff>=0.4",
39
39
  "mypy>=1.10",
40
40
  "httpx>=0.27",
41
+ "mcp>=1.6",
41
42
  ]
42
- mcp = ["mcp>=1.0"]
43
+ mcp = ["mcp>=1.6"]
43
44
  otel = ["opentelemetry-api>=1.20"]
44
45
 
45
46
  [tool.hatch.build.targets.wheel]
@@ -37,6 +37,7 @@ Errors::
37
37
 
38
38
  from .drivers.base import Driver, ExecutionContext
39
39
  from .drivers.http import HTTPDriver
40
+ from .drivers.mcp import MCPDriver
40
41
  from .drivers.memory import InMemoryDriver, make_billing_driver
41
42
  from .enums import SafetyClass, SensitivityTag
42
43
  from .errors import (
@@ -78,7 +79,7 @@ from .router import StaticRouter
78
79
  from .tokens import CapabilityToken, HMACTokenProvider
79
80
  from .trace import TraceStore
80
81
 
81
- __version__ = "0.1.0"
82
+ __version__ = "0.4.0"
82
83
 
83
84
  __all__ = [
84
85
  # version
@@ -129,6 +130,7 @@ __all__ = [
129
130
  "ExecutionContext",
130
131
  "InMemoryDriver",
131
132
  "HTTPDriver",
133
+ "MCPDriver",
132
134
  "make_billing_driver",
133
135
  # firewall
134
136
  "Firewall",
@@ -2,6 +2,7 @@
2
2
 
3
3
  from .base import Driver, ExecutionContext
4
4
  from .http import HTTPDriver
5
+ from .mcp import MCPDriver
5
6
  from .memory import InMemoryDriver
6
7
 
7
- __all__ = ["Driver", "ExecutionContext", "HTTPDriver", "InMemoryDriver"]
8
+ __all__ = ["Driver", "ExecutionContext", "HTTPDriver", "MCPDriver", "InMemoryDriver"]
@@ -83,7 +83,7 @@ class HTTPDriver:
83
83
  params: dict[str, Any] = {}
84
84
  json_body: dict[str, Any] | None = None
85
85
 
86
- if endpoint.method.upper() == "GET":
86
+ if endpoint.method.upper() in ("GET", "DELETE"):
87
87
  params = {k: v for k, v in ctx.args.items() if k != "operation"}
88
88
  else:
89
89
  json_body = {k: v for k, v in ctx.args.items() if k != "operation"}