Skip to main content

Model Context Protocol server for the Accela Construct API

Project description

Accela MCP

A Model Context Protocol (MCP) server that wraps the Accela Construct API as a curated, capability-grouped tool set. Designed for production deployment by government IT staff and implementation partners running Accela Civic Platform.

The server is safe by default — every install ships read-only. Destructive and financial capability groups must be explicitly enabled in configuration. Tokens are stored encrypted at rest, refreshed automatically, and never logged.

Status: v0.1.0 — implements the default read-only v1 tool catalog. Write tools are deferred to v0.2.


Prerequisites

  • Python 3.11+.
  • An Accela Developer Portal account at https://developer.accela.com.
  • An app registered there (My Apps → Add New App):
    • Targeted Users: Agency
    • Stage: Under Development (move to Published when ready)
    • Authorized Redirect URIs must include the value you'll set in ACCELA_REDIRECT_URI (e.g., http://localhost:8765/oauth/callback).
  • An agency to authenticate against. For sandbox use NULLISLAND (newer) or ISLANDTON (legacy, more variety).

Install

# From PyPI (after publish)
pip install accela-mcp

# From source
git clone https://github.com/Donatoni/accela-mcp.git
cd accela-mcp
pip install -e ".[dev]"

# Or with uv (recommended)
uv tool install accela-mcp

Easy Setup

For most users, run the guided setup wizard:

accela-mcp setup

It asks for:

  • Accela App ID
  • Accela App Secret
  • Agency, such as NULLISLAND
  • Environment, usually TEST
  • Redirect URI, usually http://localhost:8765/oauth/callback
  • Where to install the MCP entry: Claude Desktop, Codex, both, or neither

Then it:

  • Generates the local encryption key automatically.
  • Creates a private user-level env file.
  • Creates a safe read-only capabilities.yaml.
  • Opens the browser so you can sign in to Accela.
  • Saves encrypted OAuth tokens.
  • Adds the MCP server to the selected app config without putting Accela secrets in Claude or Codex config files.

After setup finishes, restart the selected app(s).

To check the installation later:

accela-mcp doctor

doctor checks the private setup file, capabilities config, encrypted token file, refresh-token expiry, and selected app config. Add --online if you also want it to call Accela's token-info endpoint. Use --apps claude, --apps codex, or --apps both to choose which app configs to check.

Manual Setup

Use this only if you are deploying for an agency, scripting setup, or need custom paths. The wizard above writes these values for you.

Required Environment Variables

Var Purpose
ACCELA_APP_ID Your Developer Portal app ID.
ACCELA_APP_SECRET App secret used for token exchange / refresh.
ACCELA_REDIRECT_URI Must match a registered redirect URI on the Developer Portal. The CLI binds a one-shot loopback listener on its host:port during the auth flow.
ACCELA_MCP_KEY Local Fernet key for token storage. Generate with: python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" and treat like a password. If lost, you must re-run accela-mcp auth.

Optional Environment Variables

Var Default Purpose
ACCELA_MCP_ENV_PATH user config .env, then repo-local .env Path to the private setup env file generated by setup.
ACCELA_MCP_CONFIG_PATH user config capabilities.yaml Path to the YAML config.
ACCELA_MCP_TOKEN_PATH user config tokens.json Path to the encrypted token bundle.
ACCELA_MCP_LOG_LEVEL INFO DEBUG / INFO / WARNING / ERROR.
ACCELA_MCP_LOG_FORMAT json json (production) or console (human-readable, dev only).
ACCELA_AUTH_BASE_URL https://auth.accela.com Override for regional / on-prem deployments.
ACCELA_API_BASE_URL https://apis.accela.com Same.

The default user config directory is platform-specific:

  • macOS: ~/Library/Application Support/accela-mcp/
  • Linux: ~/.config/accela-mcp/
  • Windows: %APPDATA%\accela-mcp\

capabilities.yaml

Drop a copy of capabilities.yaml.example at the path ACCELA_MCP_CONFIG_PATH points to and edit:

version: 1
agency: NULLISLAND
environment: TEST

# Optional — replaces the spec defaults if present.
enabled_groups:
    - discovery
    - records_read
    - inspections_read
    - documents_read
    - property_read
    - people_read
    - workflow_read
    - fees_read
    - reference_data
    - search

discovery is always enabled. The full validation rules and every optional knob are documented in capabilities.yaml.example.

Manual Quickstart

export ACCELA_APP_ID="your_app_id"
export ACCELA_APP_SECRET="your_app_secret"
export ACCELA_REDIRECT_URI="http://localhost:8765/oauth/callback"
export ACCELA_MCP_KEY="$(python3 -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())')"

accela-mcp auth --agency NULLISLAND --environment TEST
accela-mcp status
accela-mcp serve

accela-mcp auth creates a default capabilities.yaml if one does not exist. Edit that file to opt into additional groups, the escape hatch, or different rate-limit settings.

Connecting to MCP Clients

Claude Desktop

Choose claude or both during accela-mcp setup to update Claude Desktop automatically. The generated entry looks like this:

{
    "mcpServers": {
        "accela": {
            "command": "accela-mcp",
            "args": ["serve"],
            "env": {
                "ACCELA_MCP_ENV_PATH": "/path/to/private/accela-mcp/.env"
            }
        }
    }
}

The ACCELA_MCP_ENV_PATH value is not secret; it points to the private file where the real Accela credentials live. After config changes, restart Claude Desktop.

Codex

Choose codex or both during accela-mcp setup to update Codex automatically. The setup wizard writes or updates this block in ~/.codex/config.toml (or %USERPROFILE%\.codex\config.toml on Windows):

[mcp_servers.accela]
command = "accela-mcp"
args = ["serve"]

[mcp_servers.accela.env]
ACCELA_MCP_ENV_PATH = "/path/to/private/accela-mcp/.env"

The setup wizard creates a timestamped backup before changing an existing Codex config. Restart Codex after setup.

Claude Code

For Claude Code CLI, point it at the generated env file:

claude mcp add accela --command accela-mcp --args serve \
  -e ACCELA_MCP_ENV_PATH=/path/to/private/accela-mcp/.env

Or use the manual environment-variable form:

claude mcp add accela --command accela-mcp --args serve \
  -e ACCELA_APP_ID=... \
  -e ACCELA_APP_SECRET=... \
  -e ACCELA_REDIRECT_URI=http://localhost:8765/oauth/callback \
  -e ACCELA_MCP_KEY=...

Capability groups

Group Default Purpose
discovery always on List capabilities, agency info, record-type and custom-form metadata.
records_read on Search records, get record details, get my records, read custom data.
inspections_read on List inspections, get details, history, checklists.
documents_read on List record documents, download (≤25 MB inline).
property_read on Address, parcel, owner lookups.
people_read on Contacts and licensed professionals.
workflow_read on Workflow tasks and history for a record.
fees_read on List fees, estimate fees, list invoices.
reference_data on Record types, statuses, departments, fee schedules (TTL-cached).
search on Cross-entity global search.
records_write / inspections_write / documents_write / workflow_write off (v2) Write tools, deferred.
payments_read / payments_write off (v2) Financial tools.
gis / reports off (v2) Geocoding and report generation.
admin_escape_hatch off accela_raw_request for endpoints not wrapped — gated by a regex path allowlist and an HTTP-method allowlist (default GET only).

Operational behavior

  • Auth. OAuth 2.0 Authorization Code flow with PKCE (always on). The refresh token is rotated on every refresh; the 7-day refresh window is honored, and accela-mcp status warns when within 24 hours of expiry.
  • Retries. 429 / 5xx / transient network errors are retried with jittered exponential backoff (configurable via rate_limit.max_retries etc. in YAML). 401 forces a refresh and retries exactly once.
  • Logging. One JSON line per API call to stderr, including method, path, status, duration, attempt number, and Accela traceId on errors. Rate-limit headers are surfaced when present.
  • Caching. Reference-data endpoints (record types, departments, etc.) are cached with a 1-hour TTL by default. Every reference-data tool exposes cache_bypass: bool = False for forced refresh.
  • Document downloads. Inline base64; refused for files >25 MB.

Troubleshooting

Start with:

accela-mcp doctor
Symptom Cause Fix
accela-mcp setup or auth errors with "Failed to bind ..." Port in use Pick a different port in the redirect URI and update the registered redirect on the Developer Portal.
OAuth state mismatch Stale browser session, possible CSRF Close the auth tab, retry.
Refresh token expired More than 7 days since last successful auth/refresh Re-run accela-mcp setup or accela-mcp auth.
Failed to decrypt token file ACCELA_MCP_KEY changed since tokens were saved Re-run accela-mcp setup (or restore the original key).
capabilities.yaml agency 'X' does not match the persisted token agency 'Y' YAML and tokens disagree Re-run setup/auth for the right agency, or update capabilities.yaml.
Claude Desktop or Codex does not show Accela tools App config not updated or app not restarted Run accela-mcp doctor --apps both, then restart the affected app.
Tool returns { "error": "accela_api_error", ... } API returned 4xx Check trace_id and Accela's docs; surface to your agency admin if persistent.

Development

# Install dev deps.
uv pip install -e ".[dev]"

# Lint + format.
ruff check
ruff format --check

# Unit tests (mocked HTTP — no real API).
pytest tests/unit -v

# Coverage.
pytest tests/unit --cov=accela_mcp --cov-report=term-missing

# Integration tests (real sandbox; gated).
ACCELA_INTEGRATION_TEST=1 pytest tests/integration -v

Limitations (v0.1.0)

  • Single-agency, single-environment per running server.
  • Read-only tools shipped by default; write capabilities are v0.2 work.
  • Document upload via legacy /v4/documents only; ACDS chunked upload is deferred.
  • No webhook support — Accela does not expose a native webhook API (EMSE is agency-side and not in scope).

License

Apache 2.0 — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

accela_mcp-0.1.0.tar.gz (133.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

accela_mcp-0.1.0-py3-none-any.whl (64.8 kB view details)

Uploaded Python 3

File details

Details for the file accela_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: accela_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 133.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for accela_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 47e9b66adf60ec6e9a2836a3aff7f7a47fae537b00f43664f72b9debf537b4b5
MD5 99db080fa34436f00c9c2d14a83afd90
BLAKE2b-256 aa0aaa661ec8dcc641f8de270b5501c6143ee06b9210d0c4adefa58d8e2dbba3

See more details on using hashes here.

Provenance

The following attestation bundles were made for accela_mcp-0.1.0.tar.gz:

Publisher: publish.yml on Donatoni/accela-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file accela_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: accela_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 64.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for accela_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bcbd8bf928ecbf1682b17c66de3d62e2d3086cce0ec5bc235f044c4df4015a09
MD5 449c8bff516223c2aacbe3570eb9baee
BLAKE2b-256 2333d1a3433a0eec1d24d4085c9734ba1051cf78f31221d25bd9fe105601ccfd

See more details on using hashes here.

Provenance

The following attestation bundles were made for accela_mcp-0.1.0-py3-none-any.whl:

Publisher: publish.yml on Donatoni/accela-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page