Download the PHP package milpa/example-agent-ready-blog without Composer

On this page you can find all versions of the php package milpa/example-agent-ready-blog. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package example-agent-ready-blog

Milpa

# Milpa Example: Agent-Ready Blog > The Milpa loop, live: `plugin → capability → tool → verification → event → result` — > as a tiny agent-ready blog you can run in two commands. [![CI](https://github.com/getmilpa/example-agent-ready-blog/actions/workflows/ci.yml/badge.svg)](https://github.com/getmilpa/example-agent-ready-blog/actions/workflows/ci.yml) [![Packagist](https://img.shields.io/packagist/v/milpa/example-agent-ready-blog.svg)](https://packagist.org/packages/milpa/example-agent-ready-blog) [![PHP](https://img.shields.io/badge/php-%E2%89%A5%208.3-777bb4.svg)](https://www.php.net/) [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) **This repo doesn't teach you how to build a blog. It teaches you how to make a mutation agent-ready without losing human control.** Most examples let agents mutate state directly. This one does not. Every mutation enters through a declared tool, passes through a confirmation/verification seam, and only becomes application state through an event. The blog is just the smallest honest thing worth mutating. Prefer a guided tour? Read [`docs/walkthrough.md`](docs/walkthrough.md) — eight files, in the order that makes the loop click. ## Quickstart You'll be asked to approve or reject a publish request interactively. Here's a real run (`a` typed at the prompt): Now look at it: Prefer non-interactive? `php bin/blog.php --auto-approve` and `php bin/blog.php --reject` drive both paths without a prompt — that's exactly what this repo's own CI runs as its smoke test. ## The loop, stage by stage Every stage below is a real contract from a published package, not an abstraction invented for this example. | Stage | What runs | Published contract | |---|---|---| | **plugin** | `Kernel::boot()` instantiates `StoragePlugin`, `BlogPlugin`, `AgentToolsPlugin` | `Milpa\Interfaces\Plugin\PluginInterface` + `#[Milpa\Attributes\PluginMetadata]` (`milpa/core`) | | **capability** | `Kernel::boot()` gates the plugin graph through the architecture resolver *before* anything boots: plugins boot in the report's `loadOrder[]`, and a `requires` with no `provides` throws `ArchitectureBlockedException` with a learnable message | `#[Milpa\Attributes\PluginMetadata]` capability records (`milpa/core`) resolved by `milpa/resolver` via `milpa/runtime` | | **tool** | `AgentToolsPlugin::registerTools()` scans `BlogTools`'s three `#[Tool]` methods into the registry | `Milpa\ToolRuntime\{Attributes\Tool,Attributes\Param,ToolScanner,ToolRegistry}` + `Milpa\Interfaces\Tooling\ToolProviderInterface` (`milpa/tool-runtime` on `milpa/core`) | | **verification** | `publish_post` asks `HumanVerifier::verify()`; a human approves or rejects at the terminal prompt | `Milpa\Interfaces\Verification\VerifierInterface` (`milpa/core`) + `Milpa\ToolRuntime\Verification\HumanVerifier` (`milpa/tool-runtime`) | | **event** | Every step above fires through one shared dispatcher — `verification.requested` / `verification.granted` / `verification.rejected` / `post.published` — printed live by name | `Milpa\Interfaces\Event\MilpaEventDispatcherInterface` (`milpa/core`), implemented by `milpa/events`' `EventDispatcher` | | **result** | `BlogPlugin`'s `verification.granted` handler flips the post to `published` and dispatches `post.published` — the result arrives *via event*, not a return value | `src/Plugins/BlogPlugin/BlogPlugin.php` (this repo) | ## What an agent sees The tools are transport-agnostic: what follows is the registry's own `getToolSummaries()` output — the exact catalog an MCP host (or any other transport) would list. This is real output, not documentation prose: The full catalog has five tools, in two categories: | Category | Tools | Purpose | |---|---|---| | **Application** | `create_post`, `list_posts`, `publish_post` | the blog's own operations | | **Runtime / control** | `request_verification`, `resolve_verification` | the verification seam | They are listed together because **MCP exposes tools, not architectural layers** — policy decides which principals may call each one. (Run `$kernel->registry()->getToolSummaries()` to see the whole list.) From the agent's side, publishing is a two-call choreography — it never mutates on the first try: 1. `publish_post(id: 1)` → the registry intercepts (the tool is `mutating`) and returns a `confirm_token` instead of running the tool. 2. `publish_post(id: 1, confirm_token: …)` → the tool runs, asks the verification seam, and returns `pending_verification` with a `request_id`. 3. The actual state change arrives **by event** (`verification.granted` → `post.published`), never as a return value the agent can force. The two verification tools are split (`request_verification` opens, `resolve_verification` closes) precisely so policy can treat them differently — the security boundary below spells out what that means and what this demo deliberately leaves to you. ## The same tools, over MCP `bin/mcp-server.php` puts this exact registry — the same five tools, the same confirm-token gate, the same verification seam — behind a standard MCP stdio transport (`milpa/mcp-server`: JSON-RPC 2.0 over stdin/stdout, one message per line). It is not a second API. It is the same core, wrapped: `Kernel::boot()` and the registry are unchanged; only the outer loop differs (stdin/stdout instead of a terminal prompt). Point an **MCP-compatible host that supports local stdio servers** at it — Claude Desktop, Cursor, Windsurf and similar share this `mcpServers` config shape: Or run it directly to watch the wire, no host required: STDOUT is protocol-only; human-readable status goes to STDERR (a stray `echo` on STDOUT corrupts the wire). `notifications/initialized` gets no response line, per the JSON-RPC spec. ### A minimal session ### Two gates, different jobs Publishing crosses **two** independent gates — a common point of confusion, so be explicit: | Gate | Protects | Asks | |---|---|---| | **Confirm gate** (registry) | tool *execution* | "Are you sure this mutating tool should run at all?" | | **Verification seam** (`HumanVerifier`) | domain *state transition* | "Should this change become real application state?" | The confirm gate is generic registry-level safety; the verification seam is where policy, human, or business approval lives. A mutating tool crosses both. ### ⚠️ Security boundary of this MCP example **This example demonstrates the verification *seam*, not a complete identity/auth model — and that difference is load-bearing.** Over local stdio MCP the transport carries no authentication: the **host is trusted** to decide who may call each tool (process-level trust). `resolve_verification` is a tool like any other on the wire — so **an agent with enough scope could resolve its own verification.** That is not a hole in the idea; it is a responsibility boundary this demo deliberately leaves to the host. Two things keep that boundary honest rather than hand-waved: - **The seam to prevent self-approval already exists.** `request_verification` and `resolve_verification` are separate tools precisely so policy can restrict *who* may resolve — tool-runtime's `resolveScopes` gates it by authenticated principal. This demo doesn't wire an auth policy; production **must**. - **The audit trail already records who resolved it.** Every call emits `tool.executed` carrying its `channel` and `principal` — so even under process-trust the resolver is logged, not anonymous. In production, therefore: The framework hands you the gate; **guarding it is explicitly your half of the contract.** ## The process-loop — a post *as an event-sourced process* The tool-loop above (`create_post` → confirm gate → verification → event) is one shape of control. The `src/Orchestrator/` layer shows the next one: the same publish becomes a **process** that a post walks through — `draft → review_gate[human] → published` — driven by three MCP tools instead of one verification call: - `process_instantiate("publish_post", {post_id})` — starts the process; it auto-advances to the human gate and stops. - `process_list_pending_approvals(assignee)` — the approver's inbox; each pending decision carries a **decision artifact** (a `milpa/live` component whose options map 1:1 to the gate's transitions — what you can click is exactly what the process can do). - `process_submit_decision(instance_id, gate_id, "grant"|"reject", principal)` — resolves the gate; `grant` advances to `published`, `reject` returns to `draft`. Self-approval is refused. Watch it run: The load-bearing property: **state is never stored, only derived.** Every step is an append-only event in `var/events.jsonl`; the current state is a *projection* of that log. A brand-new store over the same file reconstructs `published` independently — which is what makes the whole history auditable and replayable (time-travel for free). The generic engine is `milpa/orchestrator` (the process definition, reducer, auto-advancing runner, and human gate) over `milpa/event-store` (the append-only log) — this example only `require`s them and supplies the **domain**: the `publish_post` definition, a decision surface that renders a post, and a `process.terminal` listener that publishes it. This layer *was* the greenhouse those two packages were extracted from; re-pointing it onto them — and watching this same loop stay green — is the dogfood that proves the extraction. ## What implements what Earlier versions of this repo implemented every framework seam inline (~440 lines: a container, an event dispatcher, a capability graph, a router). Those are gone — since v0.6.0 the app boots on **`milpa/runtime`**, which composes the published family (container + events + core's capability check + http routing) into one `Kernel::boot()`. What was a hand-rolled kernel is now a ~40-line bootstrap. The framework seams live in the packages where they belong; this repo implements only the *domain* on top of them: | Layer | What this repo implements | On top of | |---|---|---| | Boot | A thin bootstrap + a config-driven plugin list | `milpa/runtime` (`Kernel::boot`) | | Domain | The blog plugins (Storage / Blog / AgentTools) + the 5 blog/verification tools | `milpa/core` contracts + `milpa/tool-runtime` | | Transport | `bin/mcp-server.php` wraps the same registry over stdio | `milpa/mcp-server` | | Process | The `publish_post` domain (`src/Orchestrator/`) — definition, decision surface, terminal listener | `milpa/orchestrator` + `milpa/event-store` (engine) over `milpa/workflow` + `milpa/live` + `milpa/events` | The reduction is the point: the inline kernel retired with its tests green (they moved upstream into the packages that now own that behavior). Read the ~40-line bootstrap and the domain — the framework is no longer something you re-read here, it's something you `require`. ## The storage backend is one config line Since `milpa/data` 0.2, `StoragePlugin` names **no backend**. It hands the app's `storage` config block to `RepositoryFactory::fromConfig()` and registers whatever comes back behind the same `RepositoryInterface` capability `BlogPlugin` requires. The block lives in `Kernel::boot()`: This example shipped on `'file'` (the whole collection in one JSON file, `var/posts.json`) until 0.2 landed; today it ships on `'sqlite'` (a real database in one file, `var/blog.db`). The switch touched zero plugin, tool, or test code — the same 36-test suite and the same `php bin/blog.php --auto-approve` loop prove both backends. Flip the driver back and they still do. ## What this example is NOT - **Not production.** Storage is a single-file SQLite database (`var/blog.db`), there's no auth, and the DI container (`milpa/container`, via `milpa/runtime`) does no compiled/cached resolution here. - **Not a template to fork for a real blog.** It's a template for understanding the loop. - **Mutations enter via tools, not HTTP** — that's the point. The web view (`php -S localhost:8080 -t public`) is read-only by design: publishing a post always goes through `create_post` → `publish_post` → human verification, whether the caller is a human running `bin/blog.php` or an agent calling the same tools over MCP (`bin/mcp-server.php`) — the tools are transport-agnostic, and both entry points prove it. ## The family This example consumes the published Milpa family, unmodified, from Packagist — riding the current tree (`milpa/core ^0.6`, `milpa/runtime ^0.5`; `milpa/resolver` and `milpa/command` arrive transitively). The load-bearing packages: - [`milpa/core`](https://packagist.org/packages/milpa/core) — the contracts core · [API reference](https://getmilpa.github.io/core/) - [`milpa/runtime`](https://packagist.org/packages/milpa/runtime) — the bootable kernel (`Kernel::boot()`, the resolver gate) · [API reference](https://getmilpa.github.io/runtime/) - [`milpa/http`](https://packagist.org/packages/milpa/http) — PSR-15-native routing contracts · [API reference](https://getmilpa.github.io/http/) - [`milpa/tool-runtime`](https://packagist.org/packages/milpa/tool-runtime) — the agent-tool-execution engine · [API reference](https://getmilpa.github.io/tool-runtime/) - [`milpa/mcp-server`](https://packagist.org/packages/milpa/mcp-server) — the MCP transport core (JSON-RPC 2.0 over the tool registry) · [API reference](https://getmilpa.github.io/mcp-server/) - [`milpa/orchestrator`](https://packagist.org/packages/milpa/orchestrator) — the event-sourced process engine, over [`milpa/event-store`](https://packagist.org/packages/milpa/event-store), [`milpa/workflow`](https://packagist.org/packages/milpa/workflow) and [`milpa/live`](https://packagist.org/packages/milpa/live) - [`milpa/data`](https://packagist.org/packages/milpa/data) — runtime-native persistence (`EntityInterface` + `RepositoryFactory` over the file / sqlite / mysql / memory backends) ## Contributing Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). Please report security issues via [SECURITY.md](SECURITY.md), and note that this project follows a [Code of Conduct](CODE_OF_CONDUCT.md). ## License [Apache-2.0](LICENSE) © Rodrigo Vicente - TeamX Agency. --- Milpa is designed, built, and maintained by **[Rodrigo Vicente - TeamX Agency](https://teamx.agency/?utm_source=github&utm_medium=readme&utm_campaign=milpa&utm_content=example-agent-ready-blog)**.

All versions of example-agent-ready-blog with dependencies

PHP Build Version
Package Version
Requires php Version >=8.3
milpa/core Version ^0.6
milpa/data Version ^0.2
milpa/event-store Version ^0.1
milpa/http Version ^0.1
milpa/live Version ^0.1
milpa/live-web Version ^0.1
milpa/mcp-server Version ^0.3
milpa/orchestrator Version ^0.2
milpa/runtime Version ^0.5
milpa/tool-runtime Version ^0.6
milpa/workflow Version ^0.1.2
psr/log Version ^3
nyholm/psr7 Version ^1.8
nyholm/psr7-server Version ^1.1
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package milpa/example-agent-ready-blog contains the following files

Loading the files please wait ...