Skip to main content
Glama

AI Chatbot & Agents for Amazon Bedrock

Product direction and acceptance milestones: Roadmap.

The source for the WordPress plugin published at https://wordpress.org/plugins/ai-chat-for-amazon-bedrock/. This tree is what the released package is built from, so the code here is the code that gets installed.

Streaming chat and tool-using agents on Amazon Bedrock, an MCP server that exposes the site to AI clients, retrieval over published content, and an evaluation harness for checking answers.

What it does with your AWS account

The plugin signs Bedrock calls with whatever credentials the host already has. On EC2 and in ECS that is the instance or task role, and nothing is stored. Long-lived keys are supported but are not the intended path, and the Diagnostics screen names which source resolved so the answer is not a guess.

Some deliberate limits, which the test suites assert rather than merely document:

  • Guest chat is off by default, and an unknown profile key falls back without unlocking it.

  • Content tools create drafts and write protected editorial editions/attestations on existing posts. They never change a published post's canonical body or publish/send. No order or customer data is exposed.

  • Automatic WeChat selection requires an explicit public edition and independent digest-bound review. See the edition contract.

  • Retrieval indexes published, non-password-protected content only.

  • Tool output is wrapped as untrusted data before it reaches the model.

  • Tokens are stored as SHA-256 only, compared with hash_equals.

  • Credentials never appear in an export file.

  • The generated IAM policy is least-privilege, and the identity line is masked.

Related MCP server: MCP Adapter Implementation Example

Development notes

User facing documentation lives in readme.txt, which is what the plugin directory renders. README.md is for people working on the code and never ships.

Layout

Path

Purpose

ai-chat-for-amazon-bedrock.php

Plugin header, activation and bootstrap

includes/

Bedrock client, MCP, retrieval, embeddings, OAuth, usage, CLI

admin/

Settings screens, dashboards and their assets

public/

Front-end chat, block and assets

tests/

Standalone test suites, run by PHP with no framework

bin/

Release tooling

phpcs.xml.dist

WordPress coding standards for this plugin

.distignore

The only list of what does not ship

The WordPress.org SVN repository is a distribution channel. This tree is the source of truth, including the tests and tooling that never reach SVN.

Requirements

  • PHP 7.4 or newer, matching the plugin header

  • WordPress 6.4 or newer

  • An AWS account with Amazon Bedrock model access for anything that calls a model

  • python3, curl and bash for the release tooling

  • For phpcs: a PHP with the tokenizer, xmlwriter and SimpleXML extensions

Working on it

bin/setup-tools.sh                 # pinned phpcs, WPCS, PHPCSUtils, PHPCSExtra into .tools/
composer test                      # or run each tests/*.php directly
bin/prerelease.sh --php "$(which php)"

Useful options:

bin/prerelease.sh \
  --php /path/to/php \                    # tests and linting
  --phpcs-php /path/to/php-with-tokenizer \  # only if the first lacks the extensions
  --wp-cli "wp --path=/var/www/html"      # enables the official Plugin Check

--skip-phpcs and --skip-plugin-check exist for a quick loop, but a release should run everything.

The gate

bin/prerelease.sh is what must pass before publishing. It checks:

  • every PHP file parses

  • the plugin header, the runtime constant and the readme stable tag agree

  • the changelog documents the version being released

  • readme limits: description plus privacy policy under 2,500 words, short description under 150 characters, every upgrade notice under 300

  • every suite in tests/

  • WordPress coding standards through the pinned phpcs

  • the official Plugin Check, when a WP-CLI command is supplied

  • the file list that would ship, resolved from .distignore, including a scan for anything shaped like a credential

Two behaviours are deliberate:

A check that cannot run reports skip, never ok. An absent linter or a suite that declined to run must not look like a pass. The same applies to a suite that prints SKIP: as its first line.

.distignore is the only exclusion list. bin/build-package.py reads it and the gate asks that script what would ship, so adding a development directory in one place is enough. This mattered in practice: three hand maintained lists once disagreed, and a new tools directory ended up inside the audit.

Testing the gate

tests/tooling.php exercises the tooling. It copies the project to a scratch directory, breaks one thing, and asserts that the responsible check reports a failure. Assertions look for the message on a FAIL line rather than anywhere in the output, because a check that still prints its message while no longer failing is precisely the regression worth catching.

This suite exists because the gate shipped two false passes during development: phpcs failing to start was reported as clean, and the credential scan never ran in the mode the gate called. Each of the gate's checks was then disabled in turn to confirm the suite notices.

The gate marks its environment with AICFAB_GATE_SELFTEST=1 so this suite skips rather than running the gate inside the gate. CI runs it as a separate step.

Accessibility

bin/audit-accessibility.py checks the admin screens for controls without an accessible name, skipped heading levels and tables without scoped headers. It drives a real browser, so it needs a running site and is a manual check rather than a gate step.

It has earned its place twice: once finding twenty unnamed controls, and once finding that every row of a generated table exposed the same name, so a screen reader user could not tell the fields apart. Static analysis found neither, because both only exist once the page is rendered.

bin/audit-frontend.py does the same for the visitor-facing chat: it counts live-region updates during one streamed answer and checks the layout at phone width. It found that streaming rewrote the answer into an aria-live region on every chunk, so a 77 character answer produced fifteen updates and a screen reader read the growing answer out each time. Its known limitation is documented in the file: it does not report the announced text, because reading that from the harness disagreed with a simpler direct check.

Continuous integration

.github/workflows/gate.yml runs on every push and pull request:

  • the gate on PHP 7.4 and 8.3

  • tests/tooling.php

  • a package build, verified against .distignore

  • the official Plugin Check against a real WordPress install

Releasing

  1. Update the version in the plugin header, the AI_CHAT_BEDROCK_VERSION constant and the readme stable tag, and add a changelog entry and an upgrade notice.

  2. Rebuild languages/ai-chat-for-amazon-bedrock.pot from the changed code with wp i18n make-pot. Update both the zh_CN and ja .po files, preserving translation contexts, plural forms and numbered placeholders, then regenerate their .mo files with GNU gettext's msgfmt --check --check-format --no-hash and their .l10n.php files with wp i18n make-php languages/. For example: msgfmt --check --check-format --no-hash -o languages/ai-chat-for-amazon-bedrock-ja.mo languages/ai-chat-for-amazon-bedrock-ja.po. Use the same command for zh_CN. Some wp i18n make-mo versions omit the plural source string in single-form locales; the translation suite verifies the compiled catalogs' contexts, plural sources and translations. The full gate also compares the template with the code; passing the PHP-only jobs is not enough.

  3. Run bin/prerelease.sh with everything enabled. Fix anything it reports.

  4. bin/build-package.py and check the file count and checksum it prints.

  5. Copy the package contents into the SVN working copy, commit trunk, then tag.

  6. Confirm the directory shows the new version and that the package on downloads.wordpress.org contains what you built.

Screenshots in assets/ must be real captures of the current interface. Retake them when a screen changes rather than shipping a stale image.

License

GPL-2.0-or-later.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    A
    maintenance
    Production MCP server that runs as a WordPress plugin, exposing 40+ tools for managing posts, pages, custom post types, WooCommerce products, media, users, and menus from any MCP client. Includes API key + OAuth 2.0 authentication, rate limiting (60 req/min per IP), and activity logging. Free on WordPress.org
    9
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    A comprehensive WordPress plugin that implements the Model Context Protocol (MCP) to expose WordPress functionality through standardized interfaces, enabling AI models and applications to interact with WordPress sites securely using multiple transport protocols and enterprise-grade authentication.
    67 npm
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server for WordPress content management via REST API, supporting posts, pages, media, comments, and terms through natural language interfaces like Cursor, ChatGPT, Codex, and Claude.
    16 npm
    MIT