ai-chat-for-amazon-bedrock
Provides streaming chat and tool-using agents on Amazon Bedrock, signing Bedrock calls with the host's AWS credentials (instance/task role or long-lived keys) and generating a least-privilege IAM policy. Includes diagnostics showing which credential source was resolved.
Supports editorial content selection for WeChat, with automatic selection gated behind an explicit public edition and independent digest-bound review. The related content tools can prepare drafts and write protected editorial editions/attestations.
Integrates as a WordPress plugin, adding an MCP server that exposes the site to AI clients, retrieval over published non-password-protected content, front-end chat, admin dashboards, and content tools that create drafts and protected editorial editions/attestations on existing posts without publishing or altering canonical published bodies.
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 |
| Plugin header, activation and bootstrap |
| Bedrock client, MCP, retrieval, embeddings, OAuth, usage, CLI |
| Settings screens, dashboards and their assets |
| Front-end chat, block and assets |
| Standalone test suites, run by PHP with no framework |
| Release tooling |
| WordPress coding standards for this plugin |
| 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,curlandbashfor the release toolingFor
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
phpcsthe 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.phpa package build, verified against
.distignorethe official Plugin Check against a real WordPress install
Releasing
Update the version in the plugin header, the
AI_CHAT_BEDROCK_VERSIONconstant and the readme stable tag, and add a changelog entry and an upgrade notice.Rebuild
languages/ai-chat-for-amazon-bedrock.potfrom the changed code withwp i18n make-pot. Update both thezh_CNandja.pofiles, preserving translation contexts, plural forms and numbered placeholders, then regenerate their.mofiles with GNU gettext'smsgfmt --check --check-format --no-hashand their.l10n.phpfiles withwp 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 forzh_CN. Somewp i18n make-moversions 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.Run
bin/prerelease.shwith everything enabled. Fix anything it reports.bin/build-package.pyand check the file count and checksum it prints.Copy the package contents into the SVN working copy, commit trunk, then tag.
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
Federated commerce search across independent WooCommerce merchants. Keyless, read-only MCP server.
WordPress MCP server: publish posts, AI images, SEO and full site management, self-hosted
Security-first WordPress MCP server. 129 tools for Claude, ChatGPT, Gemini. Free on wp.org.
WordPress MCP server: generate SEO posts, AI images, autoblog & WooCommerce on your self-hosted site
Related MCP Servers
FlicenseNot gradedqualityAmaintenanceProduction 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.org9-- FlicenseNot gradedqualityFmaintenanceEnables WordPress content management (posts, metadata, taxonomies, Gutenberg blocks) via the Model Context Protocol, demonstrating MCP Adapter integration patterns.-
- AlicenseNot gradedqualityDmaintenanceA 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 npmMIT
- AlicenseNot gradedqualityCmaintenanceMCP 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 npmMIT