Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
196 commits
Select commit Hold shift + click to select a range
1b62370
Initial implementation of TarkaMCP - Proxmox infrastructure MCP server
Showdown76py Apr 16, 2026
4fcc0eb
Add integration test suite and server-side installation README
Showdown76py Apr 16, 2026
f9d8acc
Fix missing French accents in README.md
Showdown76py Apr 16, 2026
499457c
Polish README with badges, features section, and usage examples
Showdown76py Apr 16, 2026
d031539
Add multi-platform support: Streamable HTTP transport, auth, deploy
Showdown76py Apr 16, 2026
aebbb59
Make bearer token auth optional for Claude web compatibility
Showdown76py Apr 16, 2026
c7b6659
Replace bearer token auth with URL-based secret
Showdown76py Apr 16, 2026
65db6e9
Replace URL secret with proper OAuth 2.1 client credentials
Showdown76py Apr 16, 2026
ed061cf
Remove local/stdio mode, make HTTP-only with OAuth
Showdown76py Apr 16, 2026
f099fad
Fix Proxmox API usage bugs and systemd unit
claude Apr 16, 2026
044d33f
Review round 2: robustness, auth hardening, cluster dedup, README
claude Apr 16, 2026
90aaf10
Merge pull request #1 from Showdown76py/claude/review-proxmox-api-Xu7Lj
Showdown76py Apr 16, 2026
0b3b008
Use Python venv for install and update systemd unit
Showdown76py Apr 16, 2026
b8ee184
Make install.sh robust when python3-venv is missing
Showdown76py Apr 16, 2026
d4aeae8
Add OAuth 2.1 authorization_code + PKCE flow for browser clients
Showdown76py Apr 16, 2026
43ba161
Forward MCP app lifespan to Starlette root
Showdown76py Apr 16, 2026
6d536c1
Configure MCP DNS-rebinding allowlist via env vars
Showdown76py Apr 16, 2026
cc724c9
Document TARKAMCP_ALLOWED_HOSTS and auth error troubleshooting
Showdown76py Apr 16, 2026
eb2c448
Fix iLO client falling back to hponcfg local mode
Showdown76py Apr 16, 2026
690312a
Enforce TOTP 2FA for every OAuth client
Showdown76py Apr 16, 2026
e059e96
Serve OAuth protected-resource metadata (RFC 9728)
Showdown76py Apr 16, 2026
f767f6b
Add security_end_session tool to revoke the caller's bearer token
Showdown76py Apr 16, 2026
82c2c5c
Add 30s grace period before revoked tokens actually expire
Showdown76py Apr 16, 2026
191838d
Shorten revocation grace period from 30s to 8s
Showdown76py Apr 16, 2026
4d60321
Advertise ExampleCore logo as the MCP server icon
Showdown76py Apr 16, 2026
efd8f78
Add dashboard design spec for login + Gemini chat panels
Showdown76py Apr 16, 2026
74a55a3
Add dashboard stage 1: auth, sessions, login UI
Showdown76py Apr 16, 2026
18020f2
Add dashboard stages 2 & 3: Gemini chat with MCP tools
Showdown76py Apr 16, 2026
02960f7
Use correct Gemini 3 preview model IDs
Showdown76py Apr 16, 2026
08cfde6
Fix Gemini PERMISSION_DENIED by switching to local MCP session
Showdown76py Apr 16, 2026
9a26108
Unwrap TaskGroup ExceptionGroups + restore remote MCP mode
Showdown76py Apr 16, 2026
f114f8d
Classify 403 as model-access error with a clear remediation
Showdown76py Apr 16, 2026
69c6ad0
Auto-retry transient Gemini 5xx + classify 500 INTERNAL
Showdown76py Apr 16, 2026
83b741b
Fix deterministic 500 INTERNAL on gemini-2.5-pro via manual MCP tool …
Showdown76py Apr 16, 2026
e28a02e
Disable remote MCP mode, route 500 cascade to a clear error
Showdown76py Apr 16, 2026
73f91f3
Detect bearer wiped by service restart + fix MCP auth header plumbing
Showdown76py Apr 17, 2026
d7c3700
Break the refresh<->chat redirect loop after a service restart
Showdown76py Apr 17, 2026
8f7afe0
Extend chat markdown: headings, lists, blockquote, hr
Showdown76py Apr 17, 2026
4dea78e
Always require manual approval before running SSH exec from the chat
Showdown76py Apr 17, 2026
8d9cedd
Add dashboard "Tokens API" page for external MCP clients
Showdown76py Apr 17, 2026
777d766
Promote Tokens API to a prominent sidebar CTA
Showdown76py Apr 17, 2026
1f76a7d
README: document Tokens API, SSH confirmation, MCP local-only mode
Showdown76py Apr 17, 2026
ca75516
Add per-client usage limits to the dashboard chat panel
Showdown76py Apr 17, 2026
dc518ba
Turn usage footer into a clickable Claude-style modal
Showdown76py Apr 17, 2026
0a7962b
Split dashboard docs out + run tokens page without a Gemini key
Showdown76py Apr 17, 2026
467047b
Merge pull request #2 from Showdown76py/docs/dashboard-split-and-toke…
Showdown76py Apr 17, 2026
a9b5179
Merge remote-tracking branch 'origin/main' into feat/usage-modal
Showdown76py Apr 17, 2026
5c517de
Merge pull request #3 from Showdown76py/feat/usage-modal
Showdown76py Apr 17, 2026
96ef3a9
Require manual approval for proxmox_exec_* + trim README into docs/
Showdown76py Apr 17, 2026
c7c0edf
Rebrand TarkaMCP to BeaconMCP with modular N-node / N-BMC support
Showdown76py Apr 17, 2026
272555c
Quote Proxmox token_id in beaconmcp.yaml.example
Showdown76py Apr 17, 2026
f1360bf
Add 'Generating…' indicator to the dashboard chat stream
Showdown76py Apr 17, 2026
3dd384e
Strip :port from Proxmox node host before SSH/BMC tunneling
Showdown76py Apr 17, 2026
d7ab887
Rename indicator 'Generating…' to 'Thinking…' and slow animations
Showdown76py Apr 17, 2026
d22b094
Recommend deploying BeaconMCP on the primary Proxmox node
Showdown76py Apr 17, 2026
527f33c
Merge pull request #4 from Showdown76py/rebranding/beaconmcp
Showdown76py Apr 17, 2026
1abb61c
Switch to Apache 2.0 + Commons Clause
Showdown76py Apr 17, 2026
a54701a
Modify LICENSE for software name and copyright
Showdown76py Apr 17, 2026
cd9ac47
Render GFM tables in the dashboard chat
Showdown76py Apr 17, 2026
27f4c85
Split Connecting clients docs per provider and remove TOTP-generation…
Showdown76py Apr 17, 2026
d6bd01c
Document the TOTP automation escape hatch with prominent warnings
Showdown76py Apr 17, 2026
b7ffa19
Support OAuth Dynamic Client Registration via slug-gated bootstrap URLs
Showdown76py Apr 17, 2026
6b08895
Link to ChatGPT connectors from the tokens page
Showdown76py Apr 17, 2026
8a44ef9
Promote the ChatGPT connectors link to a proper CTA section
Showdown76py Apr 17, 2026
a190b51
Reorganise /app/tokens around auth methods and platforms
Showdown76py Apr 17, 2026
72a390d
Polish /app/tokens with nested tabs, hero endpoint, and logo pills
Showdown76py Apr 17, 2026
9fe380b
Group client variants under parent platforms; add Mistral/OpenCode/VS…
Showdown76py Apr 17, 2026
4256aff
Correct MCP config schemas after verifying against each vendor's docs
Showdown76py Apr 17, 2026
24f7e39
Tighten /app/tokens and split client docs into docs/clients.md
Showdown76py Apr 17, 2026
e0e8755
Add Perplexity as an OAuth + DCR platform
Showdown76py Apr 17, 2026
fa92205
Mistral Le Chat: correct menu path, prefer OAuth DCR, document CORS a…
Showdown76py Apr 17, 2026
498e94e
Mistral Le Chat: pure OAuth 2.1 on /mcp; expandable CORS note; flag V…
Showdown76py Apr 17, 2026
021edd3
Refine client coverage: add Codex, drop Perplexity, promote OAuth DCR…
Showdown76py Apr 17, 2026
74c7e0d
Validate redirect_uris against a trusted-origin allowlist on both DCR…
Showdown76py Apr 17, 2026
9566182
Update token-page tests to match the redesigned counter + banner strings
Showdown76py Apr 17, 2026
5b755ee
Collapse method-tag badges to OAuth 2.1 / Bearer (drop DCR distinction)
Showdown76py Apr 17, 2026
6820bd0
docs: link clients.md from README dashboard section
Showdown76py Apr 17, 2026
56370d0
Restore the OAuth 2.1 / OAuth + DCR / Bearer three-way split
Showdown76py Apr 17, 2026
20e25eb
fix: update RFC 9728 metadata to include /mcp path in resource
Showdown76py Apr 17, 2026
c5c25b8
Token-optimize MCP tool responses + fix list_nodes for standalone hosts
Showdown76py Apr 17, 2026
d9a728a
Make Proxmox / SSH / BMC capabilities independent + SSH multi-host
Showdown76py Apr 17, 2026
e6791ea
Forward MCP instructions as Gemini system_instruction in dashboard chat
Showdown76py Apr 17, 2026
e470628
Merge pull request #5 from Showdown76py/feature/independent-capabilities
Showdown76py Apr 17, 2026
f3e47cf
Redesign dashboard UI (chat, auth, tokens)
Showdown76py Apr 17, 2026
904cad2
Merge pull request #6 from Showdown76py/web/redesign
Showdown76py Apr 17, 2026
c93f25b
Add aggregator tools, unify exec tools, add fields= trim
Ailcope Apr 17, 2026
4fb14bd
dashboard: interleave assistant text between tool calls
Showdown76py Apr 17, 2026
cae6ab2
dashboard: fix invalid function_call part replay
Showdown76py Apr 17, 2026
7dfb869
dashboard: separate tool-round text and raise loop limit
Showdown76py Apr 17, 2026
8a8757c
dashboard: interleave streaming text and tool cards
Showdown76py Apr 17, 2026
957f321
Bring OAuth 2FA page + 'Thinking…' shimmer up to the new design
Showdown76py Apr 17, 2026
f499921
SSH: restore pre-2.0 homelab ergonomics with inherit_proxmox_nodes
Showdown76py Apr 17, 2026
c538edf
Docker image + LAN-IP convention for host: fields
Showdown76py Apr 17, 2026
1d31fec
Add `beaconmcp init` — interactive TUI config wizard
Showdown76py Apr 17, 2026
26edad4
beaconmcp init: refuse to overwrite existing config; fix NameError wi…
Showdown76py Apr 18, 2026
f244969
wizard: load existing beaconmcp.yaml so `init` doubles as an editor
Showdown76py Apr 18, 2026
d2d728b
wizard: cover server port/session_key/dyn-reg, dashboard, proxmox ver…
Showdown76py Apr 18, 2026
d5a0aad
Fix formatting in architecture section of README
Showdown76py Apr 18, 2026
b6b9a8d
config: clearer error when a referenced env var is set but empty
Showdown76py Apr 18, 2026
ec49b62
wizard: give allowed_hosts/allowed_origins a bounded height
Showdown76py Apr 18, 2026
a6e01d7
docs: align README / docs / tests with unified ssh_run & proxmox_run
Ailcope Apr 18, 2026
ff44378
docs/runtime: replace remaining *_exec_command references
Ailcope Apr 18, 2026
757ad1b
batch A: mechanical fixes, logging, fields=, parallel aggregators
Ailcope Apr 18, 2026
031f71d
batch C: structured audit log + Prometheus /metrics endpoint
Ailcope Apr 18, 2026
2d82425
Update src/beaconmcp/proxmox/aggregators.py
Ailcope Apr 18, 2026
2571b80
docs: clarify proxmox_run LXC behavior
Showdown76py Apr 18, 2026
0b95e35
Merge pull request #9 from Ailcope/fix/confirmation-unified-run-names
Ailcope Apr 18, 2026
9730b3f
Merge branch 'beacon-main-latest' into pr-10-conflict-fix
Showdown76py Apr 18, 2026
54b693c
Merge pull request #10 from Ailcope/feat/batch-a-mechanical-fixes
Ailcope Apr 19, 2026
0f20fd7
batch B: SSH known_hosts + per-IP rate-limit on auth endpoints
Ailcope Apr 18, 2026
f64bb35
Apply suggestion from @Copilot
Showdown76py Apr 18, 2026
8e59965
Harden auth rate-limit IP trust and add Cloudflare proxy macro
Showdown76py Apr 19, 2026
64d8876
chore: generalize AI assistant terminology across docs and config
Ailcope Apr 19, 2026
f5f351b
Update init wizard with trusted_proxies support
Showdown76py Apr 19, 2026
d6ab775
Merge pull request #11 from Ailcope/feat/batch-b-security
Ailcope Apr 19, 2026
565e2d9
feat: Operator UX and Safety enhancements
Ailcope Apr 19, 2026
4db68d5
Fix Starlette middleware duplication in HTTP app setup
Showdown76py Apr 19, 2026
18bc5f7
Merge origin/main into feat/batch-c-observability and resolve conflicts
Showdown76py Apr 19, 2026
ac78d47
Merge pull request #12 from Ailcope/feat/batch-c-observability
Ailcope Apr 19, 2026
aa92530
feat: Add Proxmox VM snapshot tools
Ailcope Apr 19, 2026
65bcd0f
fix: address operator UX regressions and safety concerns
Ailcope Apr 19, 2026
c92efe6
fix: address PR feedback on snapshot tools
Ailcope Apr 19, 2026
81aad53
docs: add updating instructions to README
Ailcope Apr 19, 2026
8b9e134
feat: add QEMU guest agent file operations and Proxmox vzdump backup …
Ailcope Apr 19, 2026
9e3669a
feat(epic-hardware-redfish): Implement Universal Redfish REST backend
Ailcope Apr 19, 2026
f3b7dcc
feat(epic-dashboard-overhaul): Add Status Overview and Usage/Cost Tra…
Ailcope Apr 19, 2026
fe3ac20
Merge branch 'feat/epic-hardware-redfish' into chore/misc
Ailcope Apr 19, 2026
a6ee98f
Merge branch 'feat/epic-dashboard-overhaul' into chore/misc
Ailcope Apr 19, 2026
78b9da1
fix(proxmox): fix backup create format, restore parse logic, and read…
Ailcope Apr 19, 2026
e6ed8cd
fix(bmc): fix BMCDevice imports, add verify_tls toggle, and pin httpx…
Ailcope Apr 19, 2026
fc1a354
refactor(dashboard): Replace fake data with neutral Coming Soon place…
Ailcope Apr 19, 2026
396daac
Merge branch 'feat/epic-hardware-redfish' into chore/misc
Ailcope Apr 19, 2026
55a72a3
Merge branch 'feat/epic-dashboard-overhaul' into chore/misc
Ailcope Apr 19, 2026
9605067
Merge pull request #13 from Ailcope/feat/operator-ux
Ailcope Apr 19, 2026
0a6fee8
Merge pull request #14 from Ailcope/feat/vm-snapshots
Ailcope Apr 19, 2026
3ab4766
Merge pull request #18 from Ailcope/feat/epic-dashboard-overhaul
Ailcope Apr 19, 2026
cd90306
fix(proxmox): harden proxmox_write_file with size limits and normaliz…
Ailcope Apr 19, 2026
c910abe
fix(bmc): discover Redfish LogServices dynamically instead of hardcod…
Ailcope Apr 19, 2026
342433c
Merge branch 'feat/epic-hardware-redfish' into chore/misc
Ailcope Apr 19, 2026
a08fc2d
Merge upstream main and resolve conflicts
Ailcope Apr 19, 2026
6708390
Merge upstream main and resolve conflicts
Ailcope Apr 19, 2026
158c3b5
Merge upstream main and resolve conflicts
Ailcope Apr 19, 2026
cbad750
Merge branch 'feat/epic-guest-data' into chore/misc
Ailcope Apr 19, 2026
2dc4634
Merge branch 'feat/epic-hardware-redfish' into chore/misc
Ailcope Apr 19, 2026
bbd3cfd
Merge pull request #16 from Ailcope/feat/epic-guest-data
Ailcope Apr 19, 2026
61d349a
Merge pull request #17 from Ailcope/feat/epic-hardware-redfish
Ailcope Apr 19, 2026
0ff2f3a
Merge pull request #19 from Ailcope/chore/misc
Ailcope Apr 19, 2026
2a63521
Fix doctor config parsing and repair Proxmox VM tools file
Showdown76py Apr 19, 2026
ac1f66b
Refactor redirect URI validation to unify CORS and OAuth checks under…
Showdown76py Apr 20, 2026
195893b
feat(proxmox): large-file upload/download for VMs and CTs
Showdown76py Apr 20, 2026
c1f6d3f
fix: checksum false-positive, add overwrite guard and delete tool
Ailcope Apr 25, 2026
9215f3b
fix(transfers): surface unverified-checksum warning, atomic download
claude Apr 25, 2026
1277827
Merge pull request #20 from Showdown76py/feat/large-file-transfers
Showdown76py Apr 25, 2026
0366d94
fix(ssh): per-host host-key verification overrides
Ailcope Jun 10, 2026
0433085
fix(proxmox): pre-check read_file size + robust backup-restore type d…
Ailcope Jun 10, 2026
138f2e8
feat(auth,audit): persist named API tokens + wire the audit log
Ailcope Jun 10, 2026
643beab
fix(security): owner-only tokens.db, harden audit redaction
Showdown76py Jun 11, 2026
ca2ff95
feat(config): YAML keys for tokens_db/audit_log, wizard host-key support
Showdown76py Jun 11, 2026
c1f356d
fix(proxmox): anchor PBS type heuristic on the VMID segment
Showdown76py Jun 11, 2026
0594f68
feat(auth): configurable named-token TTL (default 30 days)
Ailcope Jun 11, 2026
60e5315
fix(auth): named_token_ttl=0 means no expiry instead of silently 30 d
Showdown76py Jun 11, 2026
599eab2
Merge pull request #22 from Ailcope/fix/review-patches
Showdown76py Jun 11, 2026
76ad29b
perf(server): offload sync tools off the asyncio event loop
Ailcope Jun 22, 2026
785f33f
fix(auth): thread-safe TokenStore and TOTP replay protection
Ailcope Jun 22, 2026
a6c5270
fix(auth): diagnose Cloudflare-stripped bearer; ship CF guide
Ailcope Jun 22, 2026
e7f3fcd
chore(ci): add ci + ruff/pytest config, fix bmc registry test
Ailcope Jun 22, 2026
2e787d2
chore(lint): clear pre-existing ruff errors in the test suite
Ailcope Jun 22, 2026
77d6917
docs(cloudflare): explain OWASP managed-rule 403s on infra commands
Ailcope Jun 23, 2026
e77225f
fix: per-thread Proxmox connections, don't lock out on replayed TOTP
Showdown76py Jul 24, 2026
22840e8
ci: add config/build/docker jobs, fix broken wheel build
Showdown76py Jul 24, 2026
76b682e
ci: drop dead env vars, artifact upload and stale comments
Showdown76py Jul 24, 2026
70e2a67
fix(security): close findings from a full security audit
Ailcope Jul 24, 2026
169a51b
Merge pull request #25 from Showdown76py/worktree-ci-extension
Showdown76py Jul 25, 2026
e5657b1
chore(ci): bump docker/setup-buildx-action from 3 to 4
dependabot[bot] Jul 25, 2026
902499c
chore(ci): bump actions/setup-python from 5 to 7
dependabot[bot] Jul 25, 2026
ee2bd39
chore(ci): bump actions/checkout from 4 to 7
dependabot[bot] Jul 25, 2026
ab8555a
chore(ci): bump docker/build-push-action from 6 to 7
dependabot[bot] Jul 25, 2026
e11858a
Merge pull request #30 from Showdown76py/dependabot/github_actions/do…
Showdown76py Jul 29, 2026
4a6e549
Merge pull request #29 from Showdown76py/dependabot/github_actions/ac…
Showdown76py Jul 29, 2026
50ab2c8
Merge pull request #28 from Showdown76py/dependabot/github_actions/ac…
Showdown76py Jul 29, 2026
0829e75
Merge pull request #27 from Showdown76py/dependabot/github_actions/do…
Showdown76py Jul 29, 2026
dd0cfd6
fix(security): don't let a stray dry_run argument bypass the confirm …
Showdown76py Jul 29, 2026
859aed6
Merge remote-tracking branch 'origin/main' into security-audit-fix
Showdown76py Jul 29, 2026
6e56320
ci: give the config job the RACK3_IDRAC_PASSWORD stub
Showdown76py Jul 29, 2026
82f24bb
docs: split the README into focused guides (#31)
Showdown76py Jul 29, 2026
5581e37
fix(deps): hold mcp below 2.0 until the MCPServer rename is done
Showdown76py Jul 29, 2026
9874e67
Merge origin/main into security-audit-fix
Showdown76py Jul 29, 2026
4bc09aa
Merge pull request #32 from Showdown76py/fix/pin-mcp-below-2
Showdown76py Jul 29, 2026
fdb22b4
Merge remote-tracking branch 'origin/main' into security-audit-fix
Showdown76py Jul 29, 2026
d29e558
Merge pull request #24 from Ailcope/fix/security-audit
Showdown76py Jul 29, 2026
9f496cb
feat(auth): passkey sign-in + confirmation step on both login pages (…
Showdown76py Jul 29, 2026
0c24b22
feat(updates): update notice for signed-in operators + self-update MC…
Showdown76py Jul 29, 2026
87caf1a
feat: interactive panels via the MCP Apps extension (#34)
Showdown76py Jul 29, 2026
6b531df
fix(auth): gate X-Forwarded-Host on trusted_proxies
Ailcope Jul 30, 2026
29cf44b
fix(dashboard): gate vm-create-with-config behind the confirmation modal
Ailcope Jul 31, 2026
8ec9a58
fix(auth): correct the X-Forwarded-Host gate for uvicorn's proxy-headers
Ailcope Jul 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Keep the build context small — ship only what's needed to build the wheel.

# VCS & editors
.git
.gitignore
.github
.vscode
.idea

# Python caches
__pycache__
*.pyc
*.pyo
*.pyd
.pytest_cache
.mypy_cache
.ruff_cache
.coverage
htmlcov
*.egg-info
build
dist

# Local venvs and env files — never bake secrets into the image
.venv
venv
env
.env
.env.*
!.env.example

# Runtime state that should NOT go into the image
clients.json
dashboard.db
*.sqlite
*.sqlite3

# Local config (user-specific — built image uses /config at runtime)
beaconmcp.yaml

# Docs / tooling / ops extras that aren't needed at runtime
docs
deploy/install.sh
deploy/beaconmcp.service
.playwright-mcp
.assistant

# OS cruft
.DS_Store
Thumbs.db

# Tests aren't shipped in the wheel
tests
40 changes: 40 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# BeaconMCP secrets.
#
# Topology lives in beaconmcp.yaml (see beaconmcp.yaml.example). This file
# only holds the values the YAML references as ${VAR}. Every variable below
# is optional — include only the secrets your topology actually uses.

# --- Proxmox API tokens ----------------------------------------------------
# One secret per entry under proxmox.nodes[] in beaconmcp.yaml.
PVE1_TOKEN_SECRET=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
PVE2_TOKEN_SECRET=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

# --- BMC credentials -------------------------------------------------------
# One secret per entry under bmc.devices[]. Name the env vars after the
# device id for clarity.
RACK1_ILO_PASSWORD=change-me
RACK2_IPMI_PASSWORD=change-me

# --- SSH fallback ----------------------------------------------------------
SSH_PASSWORD=change-me

# --- Dashboard -------------------------------------------------------------
# Omit GEMINI_API_KEY to disable the integrated chat (the tokens page still works).
# GEMINI_API_KEY=...

# Auto-generated by deploy/install.sh on first run. Encrypts client_secret
# at rest for dashboard sessions. Regenerating invalidates every session.
# BEACONMCP_SESSION_KEY=<base64 32 bytes>

# --- Legacy env-var overrides (deprecated, removed in 2.1) -----------------
# Only used when no beaconmcp.yaml is found. Prefer the YAML file.
# BEACONMCP_CONFIG=/etc/beaconmcp/config.yaml
# BEACONMCP_CLIENTS_FILE=/opt/beaconmcp/clients.json
# BEACONMCP_PORT=8420
# BEACONMCP_HOST=0.0.0.0
# BEACONMCP_ALLOWED_HOSTS=mcp.example.com,127.0.0.1:*,localhost:*,[::1]:*
# BEACONMCP_ALLOWED_ORIGINS=https://assistant.ai,https://chat.openai.com,https://gemini.google.com
# BEACONMCP_DASHBOARD_ENABLED=true
# BEACONMCP_DASHBOARD_PUBLIC_URL=https://mcp.example.com
# BEACONMCP_DASHBOARD_LIMIT_5H_USD=2.0
# BEACONMCP_DASHBOARD_LIMIT_WEEK_USD=10.0
15 changes: 15 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: monthly
commit-message:
prefix: "chore(ci)"

- package-ecosystem: pip
directory: /
schedule:
interval: monthly
commit-message:
prefix: "chore(deps)"
127 changes: 127 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
name: CI

on:
# Branch-scoped so a push to a branch with an open PR doesn't run twice.
push:
branches: [main]
pull_request:

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# 3.13 is what the Docker image runs on.
python-version: ["3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v7

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
cache: pip

- name: Install dependencies
run: pip install -e ".[wizard,dev]"

- name: Lint
run: ruff check src/ tests/

- name: Test
run: pytest -q

# beaconmcp.yaml.example is the documented schema. If a config key is renamed
# in the loader without updating the template, this catches it.
config:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- uses: actions/setup-python@v7
with:
python-version: "3.12"
cache: pip

- name: Install
run: pip install -e .

- name: Validate the example config
# The template references secrets as ${VAR} and the loader rejects
# unset ones, so feed it throwaway values.
env:
BEACONMCP_SESSION_KEY: MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA=
GEMINI_API_KEY: ci-dummy
PVE1_TOKEN_SECRET: ci-dummy
PVE2_TOKEN_SECRET: ci-dummy
RACK1_ILO_PASSWORD: ci-dummy
RACK2_IPMI_PASSWORD: ci-dummy
RACK3_IDRAC_PASSWORD: ci-dummy
VPS2_PW: ci-dummy
run: beaconmcp validate-config --config beaconmcp.yaml.example

# Templates, static files and the logo ride along implicitly with the package
# directory. A missing one only surfaces when the dashboard renders, so assert
# on the built artifact here.
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- uses: actions/setup-python@v7
with:
python-version: "3.12"
cache: pip

- name: Build sdist + wheel
run: |
pip install build
python -m build

- name: Assert packaged data files are present
run: |
python - <<'PY'
import pathlib, sys, zipfile

names = zipfile.ZipFile(next(pathlib.Path("dist").glob("*.whl"))).namelist()
for prefix in ("beaconmcp/assets/logo.webp",
"beaconmcp/dashboard/templates/",
"beaconmcp/dashboard/static/"):
if not any(n.startswith(prefix) for n in names):
sys.exit(f"wheel is missing {prefix}")
PY

- name: Install the wheel in a clean env and smoke-test the CLI
run: |
python -m venv /tmp/smoke
/tmp/smoke/bin/pip install dist/*.whl
/tmp/smoke/bin/beaconmcp --help

docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- uses: docker/setup-buildx-action@v4

- name: Build the image (no push)
uses: docker/build-push-action@v7
with:
context: .
push: false
load: true
tags: beaconmcp:ci
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Smoke-test the entrypoint
run: docker run --rm beaconmcp:ci --help
Loading