Policy-controlled access to configured services for agents
Project description
Arbiter
Arbiter is a capability firewall between AI agents and services. Today it exposes policy-controlled access through MCP and a client CLI; additional interfaces may be added later. The current service surface covers sending mail over SMTP and reading IMAP folders through explicit account policies.
Project Status
Current implementation status:
- MCP server over stdio, SSE, or streamable HTTP via FastMCP
- capability discovery with SMTP and IMAP account and operation metadata
- SMTP submission with configured sender identity, TLS/auth settings, text/HTML bodies, and Bcc kept out of message headers
- IMAP list/get/search/move/mark-read/delete tools scoped to configured accounts and folders
arbiter.account.<service>and reusablearbiter.policy.<service>objects for per-service account policyarbiterclient CLI andarbiter-serverserver/operator CLI- Docker deployment files for a standard SMTP gateway and a hardened read-only IMAP variant
Known open gaps:
- durable audit storage is parked for post-v1, while startup/runtime logging is the v1 observability focus
- normalized error-code responses are still a design contract, while the implementation currently surfaces Python/MCP errors
- the agent-facing skill integration path is intentionally not implemented in this repository yet
Development
Create and use the repo-local virtualenv with:
python3 -m venv .venv.venv/bin/python -m pip install --upgrade pip.venv/bin/python -m pip install -e ".[dev]" -e core -e smtp -e imap
Run the test suite from the repo root with:
.venv/bin/python -m nox -s tests.venv/bin/python -m nox -s lint
The lint session runs both black --check and the Arbiter mypy passes.
For focused local runs without nox, use the same environment directly, for example:
.venv/bin/python -m pytest core/tests/unit/test_config.py.venv/bin/python -m pytest core/tests/unit/test_app.py
The Docusaurus website lives in website/:
cd website && npm installcd website && npm run startcd website && npm run build
The design is documented in the docs/ structure used by the MCP server template:
- docs/overview.md
- docs/architecture.md
- docs/BACKLOG.md
- docs/config.md
- docs/config_bootstrap.md
- docs/policies.md
- docs/errors.md
- docs/todo.md
- docs/testing_backlog.md
- docs/tools/account_summaries.md
- docs/tools/smtp_send_email.md
- docs/tools/imap.md
Local Streamable HTTP Run
For local Codex or VS Code integration, run Arbiter as a streamable HTTP MCP server and point the client at:
http://127.0.0.1:8025/mcp
Arbiter does not ship a runnable service config. Bootstrap a Hydra
config, edit it, then run the server. The default config directory is
~/.arbiter; pass --config-dir <dir> before a subcommand to use a different
location. config.local/ is ignored scratchspace for repository-local
development.
Plugin-owned object templates are created by the plugin command surface:
arbiter-server bootstrap arbiter
arbiter-server bootstrap plugin smtp account primary
${oc.env:...} reads the process environment that your shell, supervisor,
container runtime, or secret manager provides. For local runs, the root config
can name one optional dotenv-style file to load before composition.
See docs/config_bootstrap.md for the generated file layout and composition flow.
For local development, a shell-owned env file can be useful:
# ~/.arbiter/local.env
SMTP_PRIMARY_ACCOUNT_USERNAME=agent@example.com
SMTP_PRIMARY_ACCOUNT_PASSWORD=change-me
ARBITER_IMAP_USERNAME=agent@example.com
ARBITER_IMAP_PASSWORD=change-me
Point the root config at the env file:
arbiter:
env_file: local.env
Existing process environment variables take precedence over values from the env file. Relative paths are resolved from the config directory.
Build or refresh that file from the active config:
arbiter-server env bootstrap
arbiter-server env check
env bootstrap keeps existing assignments, adds missing config references, and
groups entries under sorted # arbiter-* blocks plus # miscellaneous.
If arbiter.env_file is not set yet, it adds arbiter.env_file: .env to the
root config first.
Then run from this directory:
arbiter-server config check
arbiter-server serve
config check and serve require at least one configured service account.
Use arbiter-server plugins list to inspect installed service plugins before
validating a config. Once the server is running, use the client CLI against the
MCP endpoint:
arbiter mcp tools arbiter.mcp_url=http://127.0.0.1:8025/mcp
arbiter cap arbiter.mcp_url=http://127.0.0.1:8025/mcp
arbiter accounts list arbiter.mcp_url=http://127.0.0.1:8025/mcp
The client can also read the endpoint from a small config file:
~/.arbiter/arbiter-client.yaml.
arbiter:
mcp_url: http://127.0.0.1:8025/mcp
Override config values with Hydra-style key=value arguments after the
command, or bootstrap the client config:
arbiter bootstrap client arbiter.mcp_url=http://127.0.0.1:8025/mcp
IMAP operations use folder-scoped UIDs returned by imap:list_messages and
imap:search_messages; pass those ids back to imap:get_message,
imap:move_message, imap:mark_message_read, or imap:delete_message with
the same account and folder.
Read-Only Real Inbox Docker Run
For a hardened Docker setup that reads a single real IMAP folder with Docker secrets and no SMTP access, see:
License
Arbiter is distributed under the MIT License. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file arbiter_suite-0.9.0.dev1.tar.gz.
File metadata
- Download URL: arbiter_suite-0.9.0.dev1.tar.gz
- Upload date:
- Size: 5.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e854c6053181acbc8174bc967d275d4c6a476c4932a75006daaac03741f7f5fe
|
|
| MD5 |
318bfe446c335026b209d58760be9e5a
|
|
| BLAKE2b-256 |
8e71fefd3caa780d32926034a20ae0eef3b3df40f8b30257122cd0f52da645ef
|
Provenance
The following attestation bundles were made for arbiter_suite-0.9.0.dev1.tar.gz:
Publisher:
publish.yml on omry/arbiter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
arbiter_suite-0.9.0.dev1.tar.gz -
Subject digest:
e854c6053181acbc8174bc967d275d4c6a476c4932a75006daaac03741f7f5fe - Sigstore transparency entry: 1703992996
- Sigstore integration time:
-
Permalink:
omry/arbiter@3aa7afac61727625a8a2924fe4b2a8c06ee99b6f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/omry
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3aa7afac61727625a8a2924fe4b2a8c06ee99b6f -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file arbiter_suite-0.9.0.dev1-py3-none-any.whl.
File metadata
- Download URL: arbiter_suite-0.9.0.dev1-py3-none-any.whl
- Upload date:
- Size: 4.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a8edf2a3c3e7deac42dd1300b4f0fe3b32a8829b606e34c2657a8aea3073939
|
|
| MD5 |
e0a5f3f8245c58c9293fab866c8567b9
|
|
| BLAKE2b-256 |
6b2abae4d7d717da4c6812b022f25213fe870a0721fc71fbe76c915b52f13b14
|
Provenance
The following attestation bundles were made for arbiter_suite-0.9.0.dev1-py3-none-any.whl:
Publisher:
publish.yml on omry/arbiter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
arbiter_suite-0.9.0.dev1-py3-none-any.whl -
Subject digest:
2a8edf2a3c3e7deac42dd1300b4f0fe3b32a8829b606e34c2657a8aea3073939 - Sigstore transparency entry: 1703993060
- Sigstore integration time:
-
Permalink:
omry/arbiter@3aa7afac61727625a8a2924fe4b2a8c06ee99b6f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/omry
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3aa7afac61727625a8a2924fe4b2a8c06ee99b6f -
Trigger Event:
workflow_dispatch
-
Statement type: