pfsense-mcp-server 0.2.2__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.
- pfsense_mcp_server-0.2.2/.gitignore +44 -0
- pfsense_mcp_server-0.2.2/CHANGELOG.md +97 -0
- pfsense_mcp_server-0.2.2/CODE_OF_CONDUCT.md +72 -0
- pfsense_mcp_server-0.2.2/CONTRIBUTING.md +92 -0
- pfsense_mcp_server-0.2.2/LICENSE +21 -0
- pfsense_mcp_server-0.2.2/PKG-INFO +309 -0
- pfsense_mcp_server-0.2.2/README.md +271 -0
- pfsense_mcp_server-0.2.2/SECURITY.md +43 -0
- pfsense_mcp_server-0.2.2/docs/ACCEPTANCE_v0.2.1.md +47 -0
- pfsense_mcp_server-0.2.2/docs/ACCEPTANCE_v0.2.2.md +129 -0
- pfsense_mcp_server-0.2.2/docs/API.md +466 -0
- pfsense_mcp_server-0.2.2/docs/PYPI_RELEASE.md +168 -0
- pfsense_mcp_server-0.2.2/docs/RECOVERY_CONTRACT_SPEC.md +152 -0
- pfsense_mcp_server-0.2.2/docs/RELEASE_CHECKLIST.md +78 -0
- pfsense_mcp_server-0.2.2/docs/SECURITY_MODEL.md +105 -0
- pfsense_mcp_server-0.2.2/docs/TIER1_ROADMAP.md +447 -0
- pfsense_mcp_server-0.2.2/pyproject.toml +118 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/__init__.py +1 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/api_version.py +26 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/application.py +80 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/capabilities.py +87 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/config.py +256 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/diagnostics.py +37 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/endpoints.py +231 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/errors.py +56 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/factory.py +24 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/logging_setup.py +86 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/__init__.py +3 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/acme_settings.py +25 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/arp_table_entry.py +39 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/auth_key.py +31 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/bind_settings.py +59 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/carp_status.py +26 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/cron_job.py +37 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/dhcp_lease.py +46 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/dhcp_server.py +81 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/dhcp_static_mapping.py +59 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/diagnostics_table.py +27 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/dns_resolver_host_override.py +33 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/dns_resolver_settings.py +57 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/email_notification_settings.py +60 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/firewall.py +167 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/firewall_advanced_settings.py +25 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/firewall_alias.py +44 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/firewall_nat_outbound_mode.py +23 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/firewall_nat_port_forward.py +81 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/firewall_traffic_shaper_limiter.py +123 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/free_radius_eap.py +79 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/gateways.py +104 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/interface_bridge.py +33 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/interface_config.py +141 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/interfaces.py +100 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/ntp_settings.py +53 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/ntp_time_server.py +31 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/pf_sense_user.py +51 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/pf_sense_user_group.py +35 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/service_status.py +31 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/ssh_settings.py +29 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/system.py +40 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/system_certificate.py +46 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/system_ha_sync.py +95 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/system_package.py +35 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/system_rest_api_settings.py +71 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/system_tunable.py +29 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/models/system_version.py +29 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/pfsense_client.py +516 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/pfsense_write_client.py +75 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/profiles.py +46 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/py.typed +1 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/recovery.py +95 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/rest_api_client.py +100 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/rollback.py +40 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/server.py +13 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tls.py +54 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/__init__.py +2 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/audit.py +70 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/__init__.py +1 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/acme_settings.py +18 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/arp_table.py +16 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/auth_keys.py +22 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/bind_settings.py +16 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/carp_status.py +18 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/cron_jobs.py +16 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/dhcp_leases.py +20 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/dhcp_servers.py +22 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/dhcp_static_mappings.py +21 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/diagnostics_tables.py +18 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/dns_resolver_host_overrides.py +16 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/dns_resolver_settings.py +18 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/email_notification_settings.py +24 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/firewall_advanced_settings.py +16 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/firewall_aliases.py +27 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/firewall_apply_status.py +19 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/firewall_nat_outbound_mode.py +17 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/firewall_nat_port_forwards.py +28 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/firewall_rules.py +22 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/firewall_states.py +28 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/firewall_states_size.py +18 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/firewall_traffic_shaper_limiters.py +18 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/freeradius_eap.py +18 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/gateway_status.py +22 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/gateways.py +22 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/interface_bridges.py +20 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/interface_configs.py +26 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/interfaces.py +23 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/ntp_settings.py +18 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/ntp_time_servers.py +16 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/service_status.py +20 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/ssh_settings.py +18 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/system_certificates.py +22 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/system_hasync.py +22 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/system_packages.py +16 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/system_restapi_settings.py +21 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/system_status.py +20 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/system_tunables.py +16 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/system_version.py +18 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/user_groups.py +20 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/read/users.py +25 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/registry.py +425 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/tools/write/__init__.py +3 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/transport/__init__.py +3 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/transport/base.py +33 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/transport/http.py +31 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/transport/mock.py +21 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/write_api_client.py +105 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/write_audit.py +110 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/write_endpoints.py +33 -0
- pfsense_mcp_server-0.2.2/src/pfsense_mcp/write_types.py +49 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.venv/
|
|
6
|
+
venv/
|
|
7
|
+
.pytest_cache/
|
|
8
|
+
.mypy_cache/
|
|
9
|
+
.ruff_cache/
|
|
10
|
+
dist/
|
|
11
|
+
build/
|
|
12
|
+
.coverage
|
|
13
|
+
coverage.xml
|
|
14
|
+
htmlcov/
|
|
15
|
+
|
|
16
|
+
# make validate output (junit-xml report) — working output, not a repo artifact
|
|
17
|
+
.validate/
|
|
18
|
+
|
|
19
|
+
# capture_fixture.py proposals — untrusted, unaudited candidates.
|
|
20
|
+
# Never committed directly; audit_fixture.py --approve copies an
|
|
21
|
+
# audited proposal into tests/fixtures/ explicitly.
|
|
22
|
+
.fixture_proposals/
|
|
23
|
+
|
|
24
|
+
# scaffold_capability.py proposals — generated code proposals for
|
|
25
|
+
# human review only. Never applied, staged, or committed by the tool.
|
|
26
|
+
.capability_proposals/
|
|
27
|
+
|
|
28
|
+
# Local logs (must never be committed)
|
|
29
|
+
*.log
|
|
30
|
+
logs/
|
|
31
|
+
|
|
32
|
+
# Local tooling state — never part of the repository
|
|
33
|
+
.claude/
|
|
34
|
+
|
|
35
|
+
# External AI handoff reports — local symlink to an external reports directory
|
|
36
|
+
reports-ai
|
|
37
|
+
|
|
38
|
+
# Defensive only — no secret material should ever exist in this repo,
|
|
39
|
+
# but these patterns guard against an accidental copy.
|
|
40
|
+
*.key
|
|
41
|
+
*secret*
|
|
42
|
+
*credential*
|
|
43
|
+
!tests/test_credential_non_disclosure.py
|
|
44
|
+
.env
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and the project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.2.2] - 2026-08-07
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Public CI across Python 3.11, 3.12, and 3.13.
|
|
15
|
+
- Branch coverage reporting, Bandit, and CodeQL configuration.
|
|
16
|
+
- Sdist/wheel inspection and clean installed-entry-point verification.
|
|
17
|
+
- Security, contribution, release-workflow, and project-agent guidance.
|
|
18
|
+
- Threat model, architecture diagrams and decisions, public roadmap, benchmark
|
|
19
|
+
methodology, and MCP client setup guides.
|
|
20
|
+
- GitHub issue and pull-request templates.
|
|
21
|
+
- Public API, type-quality, documentation, and final repository reviews.
|
|
22
|
+
- MCP ToolAnnotations on every production READ tool.
|
|
23
|
+
- Deterministic public MCP contract snapshot and offline release-candidate,
|
|
24
|
+
reproducible-build, documentation-consistency, and artifact-manifest checks.
|
|
25
|
+
- Implementation-independent Recovery Contract field, canonicalization, state,
|
|
26
|
+
fault, and reconciliation specification for future Tier 1 review.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- Package version prepared for v0.2.2 project hardening.
|
|
31
|
+
- README expanded for first-time installation and operation.
|
|
32
|
+
- Optional exact-name `PFSENSE_ALLOWED_TOOLS` restriction intersects with the
|
|
33
|
+
selected capability profile and fails closed on unknown names.
|
|
34
|
+
- Tier 1 roadmap strengthened for canonical target fingerprints, unstable IDs,
|
|
35
|
+
config-history conflicts, atomic rate/concurrency policy, and compensation
|
|
36
|
+
failure reconciliation; Tier 1 remains blocked.
|
|
37
|
+
- Auditor profile now derives directly from the supported READ capability set,
|
|
38
|
+
removing a duplicated activation list without changing the capability surface.
|
|
39
|
+
|
|
40
|
+
### Security
|
|
41
|
+
|
|
42
|
+
- Tool annotations remain untrusted client hints; capability, endpoint,
|
|
43
|
+
GET-only, credential, audit, and WRITE-inactivity controls remain
|
|
44
|
+
authoritative.
|
|
45
|
+
- Bound API-key metadata validation and bounded reading to one non-following
|
|
46
|
+
file descriptor, eliminating path replacement between check and use.
|
|
47
|
+
- Replaced certificate inventory fixtures prospectively with wholly synthetic
|
|
48
|
+
`.invalid` certificate identities. No private key is committed; historical
|
|
49
|
+
public certificate material remains in Git history and contained no secret.
|
|
50
|
+
- Reject all non-2xx upstream statuses, including redirects, and normalize
|
|
51
|
+
remaining HTTP transport failures without exposing upstream exception text.
|
|
52
|
+
- Reject encoded and Unicode control/format characters at configuration
|
|
53
|
+
boundaries that can reach URLs, tool restrictions, or logs.
|
|
54
|
+
- Distribution inspection rejects private-key content and additional private,
|
|
55
|
+
generated, database, backup, and SSH artifact paths.
|
|
56
|
+
|
|
57
|
+
## [0.2.1] - 2026-08-06
|
|
58
|
+
|
|
59
|
+
### Security
|
|
60
|
+
|
|
61
|
+
- Removed IPsec PSKs, SMTP passwords, and API-key plaintext from public models
|
|
62
|
+
and MCP schemas.
|
|
63
|
+
- Removed the auth-key identifying-metadata disclosure argument.
|
|
64
|
+
- Hardened audit records without logging arguments, responses, or exception
|
|
65
|
+
messages.
|
|
66
|
+
- Sanitized authentication and malformed-response errors.
|
|
67
|
+
- Added fail-closed URL, identity, TLS, key-file, and logging validation.
|
|
68
|
+
- Prohibited credential fields in approved fixtures and added negative
|
|
69
|
+
disclosure tests.
|
|
70
|
+
|
|
71
|
+
## [0.2.0] - 2026-08-06
|
|
72
|
+
|
|
73
|
+
### Added
|
|
74
|
+
|
|
75
|
+
- Tier 0 WRITE infrastructure, including recovery, rollback, audit, and write
|
|
76
|
+
client primitives.
|
|
77
|
+
- Independent checks for an empty WRITE endpoint allow-list and inactive WRITE
|
|
78
|
+
capabilities.
|
|
79
|
+
|
|
80
|
+
### Security
|
|
81
|
+
|
|
82
|
+
- Kept all Tier 0 WRITE infrastructure inert and unreachable from production
|
|
83
|
+
bootstrap. No WRITE tool or endpoint was activated.
|
|
84
|
+
|
|
85
|
+
## [0.1.0] - 2026-08-06
|
|
86
|
+
|
|
87
|
+
### Added
|
|
88
|
+
|
|
89
|
+
- Initial production-ready READ-only MCP server.
|
|
90
|
+
- Strongly typed pfSense REST API models and capability-gated tools.
|
|
91
|
+
- GET-only transport enforcement, sanitized fixtures, and offline tests.
|
|
92
|
+
|
|
93
|
+
[Unreleased]: https://github.com/night4me/pfsense-mcp-server/compare/v0.2.2...HEAD
|
|
94
|
+
[0.2.2]: https://github.com/night4me/pfsense-mcp-server/releases/tag/v0.2.2
|
|
95
|
+
[0.2.1]: https://github.com/night4me/pfsense-mcp-server/releases/tag/v0.2.1
|
|
96
|
+
[0.2.0]: https://github.com/night4me/pfsense-mcp-server/releases/tag/v0.2.0
|
|
97
|
+
[0.1.0]: https://github.com/night4me/pfsense-mcp-server/releases/tag/v0.1.0
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our pledge
|
|
4
|
+
|
|
5
|
+
We pledge to make participation in this project a harassment-free experience
|
|
6
|
+
for everyone, regardless of age, body size, visible or invisible disability,
|
|
7
|
+
ethnicity, sex characteristics, gender identity and expression, level of
|
|
8
|
+
experience, education, socio-economic status, nationality, personal
|
|
9
|
+
appearance, race, caste, color, religion, or sexual identity and orientation.
|
|
10
|
+
|
|
11
|
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
12
|
+
diverse, inclusive, and healthy community.
|
|
13
|
+
|
|
14
|
+
## Our standards
|
|
15
|
+
|
|
16
|
+
Examples of behavior that contributes to a positive environment include:
|
|
17
|
+
|
|
18
|
+
- demonstrating empathy and kindness;
|
|
19
|
+
- respecting differing opinions, viewpoints, and experiences;
|
|
20
|
+
- giving and gracefully accepting constructive feedback;
|
|
21
|
+
- accepting responsibility, apologizing, and learning from mistakes;
|
|
22
|
+
- focusing on what is best for the community and project.
|
|
23
|
+
|
|
24
|
+
Examples of unacceptable behavior include:
|
|
25
|
+
|
|
26
|
+
- sexualized language or imagery and unwelcome attention or advances;
|
|
27
|
+
- trolling, insulting or derogatory comments, and personal or political
|
|
28
|
+
attacks;
|
|
29
|
+
- public or private harassment;
|
|
30
|
+
- publishing another person's private information without explicit
|
|
31
|
+
permission;
|
|
32
|
+
- publishing credentials, appliance details, or other sensitive operational
|
|
33
|
+
data;
|
|
34
|
+
- conduct that could reasonably be considered inappropriate in a professional
|
|
35
|
+
setting.
|
|
36
|
+
|
|
37
|
+
## Enforcement responsibilities
|
|
38
|
+
|
|
39
|
+
Project maintainers are responsible for clarifying and enforcing acceptable
|
|
40
|
+
behavior. They may remove, edit, or reject contributions, comments, commits,
|
|
41
|
+
code, issues, and other contributions that do not align with this Code of
|
|
42
|
+
Conduct, and will communicate moderation reasons when appropriate.
|
|
43
|
+
|
|
44
|
+
## Scope
|
|
45
|
+
|
|
46
|
+
This Code of Conduct applies in project spaces and when an individual is
|
|
47
|
+
officially representing the project in public spaces.
|
|
48
|
+
|
|
49
|
+
## Enforcement
|
|
50
|
+
|
|
51
|
+
Report abusive, harassing, or otherwise unacceptable behavior privately to the
|
|
52
|
+
repository owner through their published GitHub contact channel. Do not use a
|
|
53
|
+
public issue for a conduct report. Reports will be reviewed promptly and
|
|
54
|
+
fairly, with respect for the reporter's privacy and safety.
|
|
55
|
+
|
|
56
|
+
Maintainers who do not follow or enforce this Code of Conduct in good faith may
|
|
57
|
+
face temporary or permanent consequences as determined by other project
|
|
58
|
+
leadership or platform administrators.
|
|
59
|
+
|
|
60
|
+
## Enforcement guidelines
|
|
61
|
+
|
|
62
|
+
Maintainers will consider context, severity, repetition, and impact when
|
|
63
|
+
deciding a proportionate response. Responses may include a private correction,
|
|
64
|
+
warning, temporary restriction, or permanent removal from project spaces.
|
|
65
|
+
|
|
66
|
+
## Attribution
|
|
67
|
+
|
|
68
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
|
69
|
+
version 2.1, available at
|
|
70
|
+
<https://www.contributor-covenant.org/version/2/1/code_of_conduct.html>.
|
|
71
|
+
|
|
72
|
+
[homepage]: https://www.contributor-covenant.org
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thank you for helping improve `pfsense-mcp-server`. This project prioritizes
|
|
4
|
+
security, explicit capability boundaries, and reviewable changes over feature
|
|
5
|
+
velocity.
|
|
6
|
+
|
|
7
|
+
## Before you begin
|
|
8
|
+
|
|
9
|
+
- Read [AGENTS.md](AGENTS.md), [the architecture overview](README.md#architecture),
|
|
10
|
+
and [the security model](docs/SECURITY_MODEL.md).
|
|
11
|
+
- Search existing issues and discussions before proposing substantial work.
|
|
12
|
+
- Open an issue for public design discussion unless the subject is a security
|
|
13
|
+
vulnerability. Report vulnerabilities privately through [SECURITY.md](SECURITY.md).
|
|
14
|
+
- Do not include credentials, real appliance details, raw responses, or
|
|
15
|
+
unsanitized logs in an issue, pull request, fixture, or test.
|
|
16
|
+
|
|
17
|
+
## Development setup
|
|
18
|
+
|
|
19
|
+
Python 3.11 or newer is supported.
|
|
20
|
+
|
|
21
|
+
```console
|
|
22
|
+
python -m venv .venv
|
|
23
|
+
.venv/bin/python -m pip install --upgrade pip
|
|
24
|
+
.venv/bin/python -m pip install -e ".[dev]"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The public test suite is fully offline. It uses `MockTransport` and approved,
|
|
28
|
+
sanitized fixtures; no pfSense appliance or credential is required.
|
|
29
|
+
|
|
30
|
+
## Making a change
|
|
31
|
+
|
|
32
|
+
1. Keep the change focused and preserve the capability-gated architecture.
|
|
33
|
+
2. Do not add or activate a capability, MCP tool, or WRITE endpoint without
|
|
34
|
+
explicit project approval.
|
|
35
|
+
3. Add tests for behavior and negative security properties.
|
|
36
|
+
4. Update public documentation when behavior or configuration changes.
|
|
37
|
+
5. Never weaken GET-only enforcement, credential non-disclosure, fixture
|
|
38
|
+
safety, or WRITE-inactivity checks.
|
|
39
|
+
|
|
40
|
+
For new fixture work, use the proposal/audit workflow documented in the
|
|
41
|
+
Makefile. Never commit a direct capture from a real appliance.
|
|
42
|
+
|
|
43
|
+
## Verification
|
|
44
|
+
|
|
45
|
+
Run the fast feedback loop while developing:
|
|
46
|
+
|
|
47
|
+
```console
|
|
48
|
+
make quick
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Before requesting review, run the authoritative local gate:
|
|
52
|
+
|
|
53
|
+
```console
|
|
54
|
+
make validate
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For packaging, coverage, or security-sensitive changes, also run the relevant
|
|
58
|
+
targets:
|
|
59
|
+
|
|
60
|
+
```console
|
|
61
|
+
make coverage
|
|
62
|
+
make security-static
|
|
63
|
+
make package-check
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Live private-infrastructure acceptance is maintainer-only, requires separate
|
|
67
|
+
approval, and is never a contributor or public CI requirement. See the
|
|
68
|
+
[release checklist](docs/RELEASE_CHECKLIST.md).
|
|
69
|
+
|
|
70
|
+
## Pull requests
|
|
71
|
+
|
|
72
|
+
A good pull request:
|
|
73
|
+
|
|
74
|
+
- explains the problem and the chosen scope;
|
|
75
|
+
- identifies compatibility and security impact;
|
|
76
|
+
- lists verification actually run;
|
|
77
|
+
- keeps unrelated formatting/refactoring out of the diff;
|
|
78
|
+
- includes no generated caches, reports containing private data, or build
|
|
79
|
+
artifacts.
|
|
80
|
+
|
|
81
|
+
Use clear commit messages in the imperative mood. Maintainers may squash or
|
|
82
|
+
reword commits during review.
|
|
83
|
+
|
|
84
|
+
## Code style
|
|
85
|
+
|
|
86
|
+
- Prefer typed, explicit code over reflection or implicit registration.
|
|
87
|
+
- Keep MCP tool functions thin and preserve precise public signatures.
|
|
88
|
+
- Translate upstream shape failures into sanitized typed exceptions.
|
|
89
|
+
- Never log arguments, response bodies, exception messages, or credentials.
|
|
90
|
+
- Follow Ruff formatting/lint and mypy configuration in `pyproject.toml`.
|
|
91
|
+
|
|
92
|
+
Participation is governed by [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 pfsense-mcp-server contributors
|
|
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,309 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pfsense-mcp-server
|
|
3
|
+
Version: 0.2.2
|
|
4
|
+
Summary: Security-focused local MCP server exposing strongly typed READ tools for pfSense.
|
|
5
|
+
Project-URL: Homepage, https://github.com/night4me/pfsense-mcp-server
|
|
6
|
+
Project-URL: Repository, https://github.com/night4me/pfsense-mcp-server
|
|
7
|
+
Project-URL: Issues, https://github.com/night4me/pfsense-mcp-server/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/night4me/pfsense-mcp-server/blob/main/CHANGELOG.md
|
|
9
|
+
Project-URL: Security, https://github.com/night4me/pfsense-mcp-server/security/policy
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: firewall,mcp,networking,observability,pfsense
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: System Administrators
|
|
16
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: System :: Networking :: Firewalls
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.11
|
|
24
|
+
Requires-Dist: httpx<1.0,>=0.27
|
|
25
|
+
Requires-Dist: mcp<2.0.0,>=1.0.0
|
|
26
|
+
Requires-Dist: pydantic<3.0,>=2.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: bandit<2.0,>=1.7; extra == 'dev'
|
|
29
|
+
Requires-Dist: build<2.0,>=1.2; extra == 'dev'
|
|
30
|
+
Requires-Dist: hatchling<2.0,>=1.25; extra == 'dev'
|
|
31
|
+
Requires-Dist: mypy<2.0,>=1.10; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest-cov<8.0,>=5.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest<9.0,>=8.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: respx<1.0,>=0.21; extra == 'dev'
|
|
35
|
+
Requires-Dist: ruff<1.0,>=0.6; extra == 'dev'
|
|
36
|
+
Requires-Dist: twine<7.0,>=5.0; extra == 'dev'
|
|
37
|
+
Description-Content-Type: text/markdown
|
|
38
|
+
|
|
39
|
+
# pfsense-mcp-server
|
|
40
|
+
|
|
41
|
+
[](https://github.com/night4me/pfsense-mcp-server/actions/workflows/ci.yml)
|
|
42
|
+
[](https://github.com/night4me/pfsense-mcp-server/actions/workflows/codeql.yml)
|
|
43
|
+

|
|
44
|
+
[](LICENSE)
|
|
45
|
+
|
|
46
|
+
A security-focused local MCP server exposing 41 strongly typed pfSense REST
|
|
47
|
+
API tools. It gives an MCP client operational visibility into one managed
|
|
48
|
+
pfSense Plus appliance while keeping the production path GET-only.
|
|
49
|
+
|
|
50
|
+
Key properties:
|
|
51
|
+
|
|
52
|
+
- explicit capability gates and typed Pydantic responses;
|
|
53
|
+
- credential fields excluded from models, schemas, logs, errors, and fixtures;
|
|
54
|
+
- optional sensitive metadata omitted by default;
|
|
55
|
+
- fail-closed configuration and TLS verification by default;
|
|
56
|
+
- 41 READ tools, zero WRITE tools, and an empty WRITE endpoint allow-list.
|
|
57
|
+
|
|
58
|
+
## Status
|
|
59
|
+
|
|
60
|
+
v0.2.2 is the current release state. It completes project, packaging,
|
|
61
|
+
documentation, and defense-in-depth hardening while preserving the 41-tool READ
|
|
62
|
+
API. It is not yet published on PyPI. No mutating capability is active, and the
|
|
63
|
+
accepted Tier 0 WRITE infrastructure remains inert.
|
|
64
|
+
|
|
65
|
+
## Scope (current phase)
|
|
66
|
+
|
|
67
|
+
- REST API only — SSH is out of scope.
|
|
68
|
+
- The production server is read-only. Accepted Tier 0 WRITE infrastructure
|
|
69
|
+
exists as dormant library code, but it is not constructed by production
|
|
70
|
+
bootstrap, has no allow-listed endpoint, and registers no MCP tool.
|
|
71
|
+
- 34 capabilities, 41 tools, spanning system, interfaces, gateways,
|
|
72
|
+
firewall, users, certificates, DHCP, DNS, NTP, SSH, cron, ACME,
|
|
73
|
+
FreeRADIUS, HA/CARP, and diagnostics. See `src/pfsense_mcp/capabilities.py`
|
|
74
|
+
for the authoritative list.
|
|
75
|
+
|
|
76
|
+
## Architecture
|
|
77
|
+
|
|
78
|
+
Transport (swappable: HttpTransport / MockTransport)
|
|
79
|
+
↓
|
|
80
|
+
RestApiClient GET-only enforcement, API-version resolution,
|
|
81
|
+
↓ JSON parsing, error mapping, duration logging
|
|
82
|
+
PfSenseClient semantic methods, raw JSON → typed models
|
|
83
|
+
↓
|
|
84
|
+
ToolRegistry / MCP Tools thin, capability-gated
|
|
85
|
+
|
|
86
|
+
`Application` (application.py) owns startup, dependency construction,
|
|
87
|
+
and lifecycle — via `factory.py` for client construction and
|
|
88
|
+
`profiles.py` for capability-set selection. `server.py`'s only job is
|
|
89
|
+
`Application().run()`.
|
|
90
|
+
|
|
91
|
+
`diagnostics.py` reports local server health (configuration validity,
|
|
92
|
+
TLS mode, active API version, registered capabilities, transport
|
|
93
|
+
type) without ever contacting pfSense.
|
|
94
|
+
|
|
95
|
+
The authoritative capability profile gates registration before a tool can
|
|
96
|
+
be exposed. The default auditor profile contains the accepted READ set;
|
|
97
|
+
the engineer placeholder contains no capabilities. Endpoint registries
|
|
98
|
+
independently enforce GET-only access and an empty WRITE allow-list.
|
|
99
|
+
An optional exact-name restriction can further reduce the tools authorized by
|
|
100
|
+
the selected profile; it can never add a tool or capability.
|
|
101
|
+
|
|
102
|
+
## Credentials
|
|
103
|
+
|
|
104
|
+
This project never stores, logs, or contains an API key. The key is
|
|
105
|
+
loaded at runtime from a local file outside this repository — only
|
|
106
|
+
its **first line** is read — path supplied via `PFSENSE_API_KEY_FILE`.
|
|
107
|
+
The server fails closed if the key cannot be loaded.
|
|
108
|
+
|
|
109
|
+
## Configuration (missing/invalid values fail closed)
|
|
110
|
+
|
|
111
|
+
| Variable | Required | Example |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| `PFSENSE_API_URL` | yes | `https://pfsense.example.invalid` |
|
|
114
|
+
| `PFSENSE_IDENTITY` | yes | `api-mcp-admin` |
|
|
115
|
+
| `PFSENSE_API_KEY_FILE` | yes | `/path/outside/repository/pfsense-api.key` |
|
|
116
|
+
| `PFSENSE_TLS_MODE` | no (default `strict`) | `strict` / `auto` / `insecure` |
|
|
117
|
+
| `PFSENSE_TLS_CA_FILE` | required if `PFSENSE_TLS_MODE=auto` | path to a CA bundle |
|
|
118
|
+
| `PFSENSE_API_VERSION` | no (default `v2`) | `v2` |
|
|
119
|
+
| `PFSENSE_PROFILE` | no (default `auditor`) | `auditor` / `engineer` |
|
|
120
|
+
| `PFSENSE_ALLOWED_TOOLS` | no | comma-separated exact MCP tool names |
|
|
121
|
+
| `PFSENSE_LOG_MAX_BYTES` | no (default `5000000`) | log-file rotation size |
|
|
122
|
+
| `PFSENSE_LOG_BACKUP_COUNT` | no (default `5`) | rotated log files kept |
|
|
123
|
+
|
|
124
|
+
`PFSENSE_TLS_MODE=insecure` disables certificate verification and must
|
|
125
|
+
be set explicitly. Switching to `auto` later (once a CA file exists)
|
|
126
|
+
requires no code change — only this configuration.
|
|
127
|
+
|
|
128
|
+
`PFSENSE_PROFILE=engineer` currently grants no capabilities — write
|
|
129
|
+
tools are not registered or reachable. It is a named placeholder for
|
|
130
|
+
a separate, explicitly authorized future phase.
|
|
131
|
+
|
|
132
|
+
`PFSENSE_ALLOWED_TOOLS` is an optional restriction applied after the selected
|
|
133
|
+
profile. If absent, the auditor profile keeps all 41 tools. If present, only
|
|
134
|
+
the comma-separated exact names in both the profile and restriction register.
|
|
135
|
+
Whitespace around names is ignored and duplicate names are normalized. An
|
|
136
|
+
explicitly empty value registers zero tools. Unknown names, empty list entries,
|
|
137
|
+
wildcards, and prefix patterns fail closed at startup. The setting can only
|
|
138
|
+
remove tools; it cannot grant a capability, activate WRITE, or override an
|
|
139
|
+
endpoint check.
|
|
140
|
+
|
|
141
|
+
## Security policy
|
|
142
|
+
|
|
143
|
+
Credential material is never part of a public model or MCP schema and
|
|
144
|
+
is ignored if pfSense includes it in a READ response. Optional
|
|
145
|
+
`include_identifying_metadata` arguments disclose sensitive operational
|
|
146
|
+
metadata only; they never disclose passwords, pre-shared keys, private
|
|
147
|
+
keys, or API-key plaintext. See the [security model](docs/SECURITY_MODEL.md)
|
|
148
|
+
and [vulnerability reporting policy](SECURITY.md).
|
|
149
|
+
|
|
150
|
+
The supported MCP transport is local stdio. The process launching and
|
|
151
|
+
controlling that channel is the caller-authentication boundary; this is
|
|
152
|
+
not a multi-tenant network service. Public CI has no production
|
|
153
|
+
configuration and never contacts a pfSense appliance.
|
|
154
|
+
|
|
155
|
+
Every current tool advertises MCP `readOnlyHint=true` and
|
|
156
|
+
`openWorldHint=true`: it does not mutate pfSense, but it reads dynamic data
|
|
157
|
+
from an external appliance. These annotations are untrusted client hints for
|
|
158
|
+
presentation and tool selection, not authorization. They do not relax
|
|
159
|
+
capability profiles, the optional exact-name restriction, GET-only or endpoint
|
|
160
|
+
enforcement, credential handling, auditing, or WRITE inactivity.
|
|
161
|
+
|
|
162
|
+
## Installation from source
|
|
163
|
+
|
|
164
|
+
Linux is the supported production platform because secure credential loading
|
|
165
|
+
depends on descriptor-bound Unix file semantics. Python 3.11 or newer is
|
|
166
|
+
required. Clone the repository, create an isolated environment, and install
|
|
167
|
+
the project:
|
|
168
|
+
|
|
169
|
+
```console
|
|
170
|
+
git clone https://github.com/night4me/pfsense-mcp-server.git
|
|
171
|
+
cd pfsense-mcp-server
|
|
172
|
+
python -m venv .venv
|
|
173
|
+
.venv/bin/python -m pip install --upgrade pip
|
|
174
|
+
.venv/bin/python -m pip install .
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The project is not currently published on PyPI. Do not use a similarly named
|
|
178
|
+
package from a package index. After the owner publishes the authenticated
|
|
179
|
+
release, the exact-version installation command will be:
|
|
180
|
+
|
|
181
|
+
```console
|
|
182
|
+
python -m pip install 'pfsense-mcp-server==0.2.2'
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Until the project page and release provenance are publicly verifiable, install
|
|
186
|
+
from the reviewed source tree as shown above.
|
|
187
|
+
|
|
188
|
+
## Quick start
|
|
189
|
+
|
|
190
|
+
Create the API-key file outside the repository and restrict it to the account
|
|
191
|
+
that runs the MCP server:
|
|
192
|
+
|
|
193
|
+
```console
|
|
194
|
+
install -m 600 /dev/null /absolute/private/path/pfsense-api.key
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Place the key on the first line without printing it in shell history or logs.
|
|
198
|
+
Then configure your MCP client to launch the console entry point with these
|
|
199
|
+
environment variables:
|
|
200
|
+
|
|
201
|
+
```json
|
|
202
|
+
{
|
|
203
|
+
"command": "/absolute/path/to/.venv/bin/pfsense-mcp-server",
|
|
204
|
+
"env": {
|
|
205
|
+
"PFSENSE_API_URL": "https://pfsense.example.invalid",
|
|
206
|
+
"PFSENSE_IDENTITY": "api-mcp-admin",
|
|
207
|
+
"PFSENSE_API_KEY_FILE": "/absolute/private/path/pfsense-api.key",
|
|
208
|
+
"PFSENSE_TLS_MODE": "strict"
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
The exact outer MCP-client configuration key varies by client. Use one of the
|
|
214
|
+
[verified client examples](examples/README.md), then confirm that the client
|
|
215
|
+
shows 41 READ tools and no WRITE tools. A first safe call is
|
|
216
|
+
`pfsense_get_system_status`. The server communicates over stdio and produces
|
|
217
|
+
no web interface or screenshotable UI.
|
|
218
|
+
|
|
219
|
+
For development, install the project with its test and analysis tools:
|
|
220
|
+
|
|
221
|
+
```console
|
|
222
|
+
.venv/bin/python -m pip install -e ".[dev]"
|
|
223
|
+
make quick
|
|
224
|
+
make validate
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Additional release checks are documented in the
|
|
228
|
+
[release checklist](docs/RELEASE_CHECKLIST.md). Live private-infrastructure
|
|
229
|
+
acceptance is separate, opt-in, and never part of public CI.
|
|
230
|
+
|
|
231
|
+
## Direct launch
|
|
232
|
+
|
|
233
|
+
Direct launch is useful for confirming configuration and MCP startup. The
|
|
234
|
+
process waits for MCP messages on stdin when configuration is valid.
|
|
235
|
+
|
|
236
|
+
```console
|
|
237
|
+
PFSENSE_API_URL=https://pfsense.example.invalid \
|
|
238
|
+
PFSENSE_IDENTITY=api-mcp-admin \
|
|
239
|
+
PFSENSE_API_KEY_FILE=/absolute/private/path/pfsense-api.key \
|
|
240
|
+
PFSENSE_TLS_MODE=strict \
|
|
241
|
+
pfsense-mcp-server
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Troubleshooting
|
|
245
|
+
|
|
246
|
+
### The server exits with a configuration error
|
|
247
|
+
|
|
248
|
+
Configuration fails closed. Confirm every required variable is present, the
|
|
249
|
+
API URL is an HTTPS origin without a path, and the identity contains no control
|
|
250
|
+
characters. Error messages identify the invalid setting but never print the
|
|
251
|
+
key value.
|
|
252
|
+
|
|
253
|
+
### The API-key file is rejected
|
|
254
|
+
|
|
255
|
+
The file must be a regular non-symlink file owned by the process user, with no
|
|
256
|
+
group or other permission bits, and its first line must be non-empty and
|
|
257
|
+
bounded. Parent directories should normally be mode 0700.
|
|
258
|
+
|
|
259
|
+
### TLS verification fails
|
|
260
|
+
|
|
261
|
+
Prefer `strict` with the system trust store. For an internal CA, set
|
|
262
|
+
`PFSENSE_TLS_MODE=auto` and point `PFSENSE_TLS_CA_FILE` to a readable CA
|
|
263
|
+
bundle. `insecure` disables certificate verification and should be limited to
|
|
264
|
+
short, explicitly accepted diagnostics.
|
|
265
|
+
|
|
266
|
+
### No tools appear
|
|
267
|
+
|
|
268
|
+
Use `PFSENSE_PROFILE=auditor`, the default accepted READ profile. The
|
|
269
|
+
`engineer` placeholder intentionally grants no capabilities in this build.
|
|
270
|
+
Also check `PFSENSE_ALLOWED_TOOLS`: an explicitly empty value intentionally
|
|
271
|
+
registers zero tools, and a configured subset hides every unlisted tool.
|
|
272
|
+
|
|
273
|
+
### Can this server manage more than one appliance?
|
|
274
|
+
|
|
275
|
+
No. One process has one configured upstream identity and appliance. Launch a
|
|
276
|
+
separate process with separate configuration for another appliance.
|
|
277
|
+
|
|
278
|
+
## Documentation
|
|
279
|
+
|
|
280
|
+
- [MCP tool reference](docs/API.md)
|
|
281
|
+
- [Future-major API review](docs/API_REVIEW.md)
|
|
282
|
+
- [Client setup examples](examples/README.md)
|
|
283
|
+
- [Architecture diagrams](docs/ARCHITECTURE_DIAGRAMS.md)
|
|
284
|
+
- [Architecture decisions](docs/adr/README.md)
|
|
285
|
+
- [Offline benchmark methodology](docs/BENCHMARKS.md)
|
|
286
|
+
- [Threat model](docs/THREAT_MODEL.md)
|
|
287
|
+
- [Security abuse-case catalog](docs/SECURITY_TEST_CATALOG.md)
|
|
288
|
+
- [Security model](docs/SECURITY_MODEL.md)
|
|
289
|
+
- [Vulnerability reporting](SECURITY.md)
|
|
290
|
+
- [Public roadmap](docs/ROADMAP.md)
|
|
291
|
+
- [Future Recovery Contract specification](docs/RECOVERY_CONTRACT_SPEC.md)
|
|
292
|
+
- [Contribution guide](CONTRIBUTING.md)
|
|
293
|
+
- [Release checklist](docs/RELEASE_CHECKLIST.md)
|
|
294
|
+
- [PyPI release procedure](docs/PYPI_RELEASE.md)
|
|
295
|
+
- [Dependency policy](docs/DEPENDENCY_POLICY.md)
|
|
296
|
+
- [v0.2.2 acceptance](docs/ACCEPTANCE_v0.2.2.md)
|
|
297
|
+
- [v0.2.1 acceptance](docs/ACCEPTANCE_v0.2.1.md)
|
|
298
|
+
|
|
299
|
+
## Contributing
|
|
300
|
+
|
|
301
|
+
Contributions are welcome within the documented security and approval
|
|
302
|
+
boundaries. Read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a change.
|
|
303
|
+
Report vulnerabilities privately as described in [SECURITY.md](SECURITY.md).
|
|
304
|
+
|
|
305
|
+
## License
|
|
306
|
+
|
|
307
|
+
Licensed under the [MIT License](LICENSE). The copyright notice uses the
|
|
308
|
+
project contributor identity and does not assert ownership by an invented
|
|
309
|
+
person or organization.
|