PHPackages                             rasuvaeff/yii3-mcp - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. rasuvaeff/yii3-mcp

ActiveLibrary[HTTP &amp; Networking](/categories/http)

rasuvaeff/yii3-mcp
==================

MCP server integration for Yii3: PSR-15 Streamable HTTP endpoint, DI tool registry, and stdio transport over the official mcp/sdk

v2.2.0(3w ago)15673BSD-3-ClausePHPPHP 8.3 - 8.5CI passing

Since Jul 4Pushed 1mo agoCompare

[ Source](https://github.com/rasuvaeff/yii3-mcp)[ Packagist](https://packagist.org/packages/rasuvaeff/yii3-mcp)[ Docs](https://github.com/rasuvaeff/yii3-mcp)[ RSS](/packages/rasuvaeff-yii3-mcp/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependencies (44)Versions (16)Used By (3)

rasuvaeff/yii3-mcp
==================

[](#rasuvaeffyii3-mcp)

[![Stable Version](https://camo.githubusercontent.com/2403d3761577f2a626e5b3dca60aef78c8723b42d4988fb3e112604f8baf2025/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7261737576616566662f796969332d6d63703f6c6162656c3d737461626c6526736f72745f73656d7665723d31)](https://packagist.org/packages/rasuvaeff/yii3-mcp)[![Total Downloads](https://camo.githubusercontent.com/af1cd5de49910c24ef6f556b2ea28e5fabc360c8248466f0fd261295cdb7eeac/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7261737576616566662f796969332d6d6370)](https://packagist.org/packages/rasuvaeff/yii3-mcp)[![Build](https://camo.githubusercontent.com/ba711ee96eb5594335b04f47c7bf9fcd35ee2441d8b03f6c65fc373a30be1f0e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7261737576616566662f796969332d6d63702f6275696c642e796d6c3f6272616e63683d6d6173746572)](https://github.com/rasuvaeff/yii3-mcp/actions)[![Static analysis](https://camo.githubusercontent.com/9f9aeadf8e4d11424e8b48a001cc87859d0c233394f340d025cf5220567a20e0/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7261737576616566662f796969332d6d63702f7374617469632d616e616c797369732e796d6c3f6272616e63683d6d6173746572266c6162656c3d737461746963253230616e616c79736973)](https://github.com/rasuvaeff/yii3-mcp/actions)[![Psalm level](https://camo.githubusercontent.com/96f0376e917393dc04f5e50ef34fa74f202272a3100aa70c66ece3282f6a2e36/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7073616c6d2d6c6576656c253230312d3134314634383f6c6f676f3d7073616c6d266c6f676f436f6c6f723d7768697465)](https://github.com/rasuvaeff/yii3-mcp/blob/master/psalm.xml)[![PHP](https://camo.githubusercontent.com/adf374398a3d0ef528bed5e55f30a4a9f1fdca8f21123d08c48aff74a61004a7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f7261737576616566662f796969332d6d63702f706870)](https://packagist.org/packages/rasuvaeff/yii3-mcp)[![License](https://camo.githubusercontent.com/7e9530c47cf463c03d0f5dc212a28e452ccd0edcb52969fb899979216c3106d1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7261737576616566662f796969332d6d6370)](LICENSE.md)

[Model Context Protocol](https://modelcontextprotocol.io) server integration for Yii3 over the **official** [`mcp/sdk`](https://packagist.org/packages/mcp/sdk)(PHP Foundation + Symfony): expose your application's domain operations as MCP tools/resources for AI agents (Claude Code, Claude Desktop, …) through a PSR-15 Streamable HTTP endpoint, with tools resolved through the Yii3 DI container.

> **Using an AI coding assistant?** [llms.txt](llms.txt) contains a compact API reference you can share with the model. Contributors: see [AGENTS.md](AGENTS.md).

Requirements
------------

[](#requirements)

RequirementVersionPHP8.3 – 8.5`mcp/sdk``~0.6.0` (experimental until 1.0 — hence the tilde pin)MCP protocol2025-06-18 (via SDK)`ext-fileinfo`required by the SDKInstallation
------------

[](#installation)

```
composer require rasuvaeff/yii3-mcp
```

Usage
-----

[](#usage)

### 1. Declare a tool

[](#1-declare-a-tool)

Tools are ordinary Yii3 services. Capability methods are annotated with the SDK's own attributes — this package invents no protocol structures:

```
use Mcp\Capability\Attribute\McpTool;

final readonly class OrderTools
{
    public function __construct(private OrderRepository $orders) {}

    /**
     * Returns the current status of an order.
     */
    #[McpTool(name: 'order.status')]
    public function status(string $orderId): string
    {
        return $this->orders->get($orderId)->status->value;
    }
}
```

Input schemas are generated by the SDK from the method signature and DocBlock. `#[McpResource]`, `#[McpResourceTemplate]` and `#[McpPrompt]` methods work the same way — all four SDK capability attributes are recognized.

To gate a capability class (feature flag, environment check), implement `ConditionalToolInterface` — the instance is resolved through the container at build time and skipped when `shouldRegister()` returns `false`:

```
final readonly class BetaTools implements ConditionalToolInterface
{
    public function __construct(private FeatureFlags $flags) {}

    public function shouldRegister(): bool
    {
        return $this->flags->isEnabled('mcp-beta-tools');
    }

    #[McpTool(name: 'beta.op')]
    public function betaOp(): string { ... }
}
```

### 2. Register it

[](#2-register-it)

```
// config/params.php
return [
    'rasuvaeff/yii3-mcp' => [
        'server_name' => 'my-app',
        'server_version' => '1.0.0',
        'tools' => [OrderTools::class],
        'endpoint_secret' => getenv('MCP_SECRET'),
    ],
];
```

Handlers are registered as `[class, method]` references — the SDK resolves the instance through the Yii3 container on call, so constructor dependencies are injected the normal way.

### 3. Route the endpoint

[](#3-route-the-endpoint)

```
// config/routes.php
Route::methods(['POST', 'GET', 'DELETE', 'OPTIONS'], '/mcp')
    ->middleware(SharedSecretMiddleware::class)
    ->action(McpAction::class),
```

An MCP client connects with the secret header:

```
{
    "mcpServers": {
        "my-app": {
            "type": "http",
            "url": "https://example.com/mcp",
            "headers": { "X-Mcp-Secret": "..." }
        }
    }
}
```

### stdio for local development

[](#stdio-for-local-development)

```
// add McpServeCommand to your console commands
./yii mcp:serve
```

Claude Code config: `claude mcp add my-app -- ./yii mcp:serve`.

### Introspection: what is actually served

[](#introspection-what-is-actually-served)

`mcp:list` prints every registered tool, resource, resource template and prompt — with argument summaries (`name*` = required) — without an MCP client. It goes through the same in-process JSON-RPC path a real client uses, so attribute tools, OpenAPI-bridged operations and Markdown prompts all show up:

```
// add McpListCommand to your console commands
./yii mcp:list
```

The command (like `McpTester`) needs PSR-17 factories (`ServerRequestFactoryInterface`, `ResponseFactoryInterface`, `StreamFactoryInterface`) in the container.

### Sessions (important for PHP-FPM)

[](#sessions-important-for-php-fpm)

The MCP Streamable HTTP session spans several HTTP requests (`initialize`first, then `tools/call` with the returned `Mcp-Session-Id`). The SDK's default in-memory store would lose the session between FPM workers, so this package **defaults to a file-based store** (`sys_get_temp_dir()`, override via `session.dir` param). For multi-host setups rebind the interface:

```
// config/common/di/mcp.php
use Mcp\Server\Session\Psr16SessionStore;
use Mcp\Server\Session\SessionStoreInterface;

return [
    SessionStoreInterface::class => static fn (CacheInterface $cache) =>
        new Psr16SessionStore($cache),
];
```

### Prompts from Markdown files

[](#prompts-from-markdown-files)

Prompts are content, not code — keep them in a directory and every `*.md`file becomes an MCP prompt (edited without a deployment, versioned like any other file):

```
'rasuvaeff/yii3-mcp' => [
    'prompts_path' => __DIR__ . '/../resources/prompts',
],
```

```
---
name: code-review          # defaults to the file name
title: Code review assistant
description: Reviews a diff with a given focus
arguments:
  - name: diff
    description: The diff to review
    required: true
  - focus                  # simple form: optional argument
---
Review the following diff focusing on {{focus}}:

{{diff}}
```

Declared `{{argument}}` placeholders are substituted from the request (missing ones become empty strings); undeclared placeholders are left intact. Malformed frontmatter, an unreadable file or a duplicate prompt name fail the server build with `Prompts\Exception\InvalidPromptFileException`— never a silently missing prompt.

> The file format is intentionally compatible with — and inspired by — [vjik/my-prompts-mcp](https://github.com/vjik/my-prompts-mcp) by Sergei Predvoditelev: the same prompt file works in a personal stdio prompt manager and on an application server.

Interceptors: wrap every tools/call
-----------------------------------

[](#interceptors-wrap-every-toolscall)

`Interceptor\ToolCallInterceptorInterface` is the package's public extension point around tool execution. The chain wraps **every** registration path — attribute tools, OpenAPI-bridged operations, configurator-registered handlers — so tracing, rate limiting or ACL live in one place, without touching the tools:

```
use Rasuvaeff\Yii3Mcp\Interceptor\ToolCallContext;
use Rasuvaeff\Yii3Mcp\Interceptor\ToolCallInterceptorInterface;

final readonly class TracingInterceptor implements ToolCallInterceptorInterface
{
    public function __construct(private LoggerInterface $logger) {}

    public function intercept(ToolCallContext $context, callable $next): mixed
    {
        // $context->toolName, $context->arguments, $context->session,
        // $context->getClientInfo() — who is calling what with which input
        $this->logger->info('tools/call', ['tool' => $context->toolName]);

        return $next();   // skip $next() to short-circuit
    }
}
```

```
// config/params.php — resolved through the container, first = outermost
'rasuvaeff/yii3-mcp' => [
    'interceptors' => [TracingInterceptor::class],
],
```

Throwing `Mcp\Exception\ToolCallException` from an interceptor rejects the call with a regular MCP tool-error envelope (the agent sees the reason); any other exception becomes an opaque internal error.

### Session budget: stop agent loops

[](#session-budget-stop-agent-loops)

A hard cap on `tools/call` per MCP session (from `initialize` until the TTL expires). An agent stuck in a loop burns the budget and gets an explanatory tool error instead of hammering the application:

```
'rasuvaeff/yii3-mcp' => [
    'session' => ['budget' => 50],   // 0 = unlimited (default)
],
```

This is loop protection **inside one session**, not a client quota: a re-initialize starts a fresh counter. Client quotas belong to an application-level rate limiter. The budget guard is always the outermost interceptor, so it rejects before any other interceptor does work.

### Per-session tool visibility

[](#per-session-tool-visibility)

`ConditionalToolInterface` gates registration globally at build time. When different **sessions** must see different tools (admin vs public client, tenant plans), implement `Visibility\ToolVisibilityInterface` — the decision runs per session, against the handshake data:

```
use Mcp\Schema\Tool;
use Mcp\Server\Session\SessionInterface;
use Rasuvaeff\Yii3Mcp\Visibility\ToolVisibilityInterface;

final readonly class PlanBasedVisibility implements ToolVisibilityInterface
{
    public function isVisible(Tool $tool, ?SessionInterface $session): bool
    {
        // decide from $session->get('client_info'), tenant data, …
        return !str_starts_with($tool->name, 'admin.') || $this->isAdmin($session);
    }
}
```

```
'rasuvaeff/yii3-mcp' => [
    'tool_visibility' => PlanBasedVisibility::class,   // DI-resolved
],
```

The filter applies in two places, consistently: `tools/list` omits invisible tools, and `tools/call` **fail-closed** rejects them — a client that guesses a hidden name still gets a tool error, and the call never reaches the interceptor chain or the tool. This is an early filter, not a replacement for application-level ACL.

### Server configurators

[](#server-configurators)

Beyond the built-in Markdown-prompts and OpenAPI bridge, register your own `ServerConfiguratorInterface` implementations (or a companion package's) to contribute capabilities to the SDK server builder before it is built. The core resolves the FQCNs through the container (after its own configurators) and applies them in order:

```
'rasuvaeff/yii3-mcp' => [
    'configurators' => [MyServerConfigurator::class],   // DI-resolved
],
```

```
final readonly class MyServerConfigurator implements ServerConfiguratorInterface
{
    #[\Override]
    public function configure(Builder $builder): void
    {
        // $builder->addTool(...) / addResource(...) / addPrompt(...) …
    }
}
```

Multi-tenant serving (rasuvaeff/yii3-tenancy)
---------------------------------------------

[](#multi-tenant-serving-rasuvaeffyii3-tenancy)

With [rasuvaeff/yii3-tenancy](https://github.com/rasuvaeff/yii3-tenancy) the MCP endpoint serves every tenant from one route — tools are ordinary Yii3 services, so a constructor-injected `CurrentTenant` scopes their data access as anywhere else in the application. The recipe is middleware order: resolve the tenant **before** the MCP action runs:

```
// config/routes.php — secret first (fail-closed), then tenant, then MCP
Route::methods(['POST', 'GET', 'DELETE', 'OPTIONS'], '/mcp')
    ->middleware(SharedSecretMiddleware::class)
    ->middleware(TenantResolutionMiddleware::class)   // e.g. HeaderTenantResolver('X-Tenant-Id')
    ->action(McpAction::class),
```

```
// an MCP client carries both headers
"headers": { "X-Mcp-Secret": "...", "X-Tenant-Id": "acme" }
```

Isolate sessions per tenant so a session id can never cross tenants — bind the session store to a per-tenant directory:

```
// config/common/di/mcp.php
SessionStoreInterface::class => static fn (CurrentTenant $tenant) =>
    new FileSessionStore(
        directory: sys_get_temp_dir() . '/mcp-sessions/' . $tenant->get()->getId(),
    ),
```

Per-tenant tool sets come free with `tool_visibility` (see above): decide from the resolved tenant instead of `client_info`.

> **Honest scope:** the shared secret stays global — anyone holding it may present any `X-Tenant-Id`. That fits the trusted-only endpoint model (the secret already grants application access); tenant isolation here protects against accidents, not against a malicious secret holder. Per-tenant secrets (a secret resolver instead of the single-value middleware) are a planned extension — ask if you need it.

OpenAPI bridge: expose an existing REST API
-------------------------------------------

[](#openapi-bridge-expose-an-existing-rest-api)

If the application already maintains an OpenAPI document, allow-listed operations can be bridged as MCP tools with zero duplication — names come from `operationId`, descriptions from `summary`/`description`, input schemas from parameters/request body. Calls are executed as real HTTP requests against the API, passing its full middleware stack (validation, rate limiting, auth) — unlike hand-written tools that invoke handlers directly.

```
// config/params.php
'rasuvaeff/yii3-mcp' => [
    'openapi' => [
        // file path OR http(s) URL — e.g. the app's own spec endpoint,
        // always current; fetched with the same `headers` (auth included)
        'spec_path' => 'https://api.example.com/rest/json-url',
        'base_url' => 'https://api.example.com',
        'operations' => ['getBlogTags', 'getPage'],   // allow-list, empty = nothing
        'headers' => ['Authorization' => 'Bearer ' . getenv('MCP_API_TOKEN')],
        'safe_methods_only' => true,   // read-only bridge: non-GET in the list => build error
    ],
],
```

The DI wiring requires PSR-18/PSR-17 services (`ClientInterface`, `RequestFactoryInterface`, `StreamFactoryInterface`) in the container. Request bodies are passed as a single `body` tool argument; an operationId missing from the document throws `UnknownOperationException` at server build time, a non-GET operation under `safe_methods_only` throws `UnsafeOperationException` (fail-fast). Local `#/components/...` `$ref`s are resolved inline (up to 32 chained hops); external (URL/file) `$ref`s pass through unresolved. Tool arguments are keyed by name, so an operation with a path and a query parameter sharing one name — or a parameter named `body`alongside a request body — cannot be bridged and throws `InvalidSpecException` at build time.

For custom scenarios use the pieces directly: `SpecIndex` + `HttpOperationExecutor` + `OpenApiServerConfigurator` (a `ServerConfiguratorInterface` — the generic extension point accepted by `McpServerFactory::create(tools, configurators)`).

Components
----------

[](#components)

ClassRole`McpServerFactory`list of tool FQCNs → configured SDK `Server` (reads `#[McpTool]`/`#[McpResource]` attributes, wires the DI container and session store)`McpAction`PSR-15 handler running the SDK `StreamableHttpTransport` for the current request`SharedSecretMiddleware`fail-closed `hash_equals()` guard; an empty secret rejects every request with an explanatory 503 — an unprotected endpoint must be an explicit decision`McpServeCommand``mcp:serve` — stdio transport for local MCP clients`McpListCommand``mcp:list` — console introspection of every served tool/resource/prompt with argument summaries`Exception\InvalidToolClassException`configured tool class missing or without capability attributes (fail-fast)`ConditionalToolInterface`capability class opts out of registration at build time (`shouldRegister()`)`Testing\McpTester`in-process test client: initialize/listTools/callTool/readResource`Testing\SchemaSnapshot`contract canary: committed JSON snapshot of all served capability schemas; drift fails the build`Prompts\MarkdownPromptsConfigurator`a directory of `*.md` files as MCP prompts (vjik/my-prompts-mcp-compatible format)`ServerConfiguratorInterface`generic extension point for contributing capabilities to the builder; register your own via the `configurators` params list`Interceptor\ToolCallInterceptorInterface`wraps every tools/call (tracing, ACL, rate limits); configured via `interceptors` params`Interceptor\ToolCallContext`what an interceptor sees: tool name, arguments, session, `getClientInfo()``Interceptor\SessionBudgetInterceptor`per-session tools/call cap (`session.budget` param) — anti-loop guard`Interceptor\InterceptingReferenceHandler`the decorator wiring the chain into the SDK (used by `McpServerFactory`)`Visibility\ToolVisibilityInterface`per-session tool filter (`tool_visibility` param): tools/list omits, tools/call fail-closed rejects`OpenApi\OpenApiServerConfigurator`bridges allow-listed OpenAPI operations as tools (HTTP execution)`OpenApi\Exception\*``InvalidSpecException`, `UnknownOperationException`, `UnsafeOperationException`, `OperationFailedException`Security
--------

[](#security)

- **The endpoint is trusted-only.** MCP tools execute application code; treat the endpoint like an admin API. Ship it behind `SharedSecretMiddleware` (an empty secret rejects every request with an explanatory 503) or an explicit network ACL.
- Tool errors are returned as MCP error envelopes by the SDK — internals are not leaked as 500 traces.
- The core registers **no tools by default**; every exposed operation is an explicit entry in `params['rasuvaeff/yii3-mcp']['tools']`.
- OAuth from the MCP authorization spec is deliberately out of scope until it stabilizes; shared-secret/ACL only.

Examples
--------

[](#examples)

See [examples/](examples/) — every script runs offline.

ScriptShowsNeeds server?[`http-handshake.php`](examples/http-handshake.php)Full in-process MCP cycle: initialize + tools/callno[`stdio-serve.php`](examples/stdio-serve.php)The stdio transport `mcp:serve` runs, over in-memory streamsno[`conditional.php`](examples/conditional.php)`ConditionalToolInterface` registration gatingno[`prompts.php`](examples/prompts.php)Markdown files served as MCP promptsno[`openapi-bridge.php`](examples/openapi-bridge.php)OpenAPI operations bridged as MCP toolsno[`interceptors.php`](examples/interceptors.php)Tracing interceptor + session budget guardno[`visibility.php`](examples/visibility.php)Per-session tool visibility: filtered listing + fail-closed callnoTesting your tools
------------------

[](#testing-your-tools)

`Testing\McpTester` drives the real Streamable HTTP code path in-process — no HTTP server, no stdio process:

```
$tester = new McpTester($server, $psr17, $psr17, $psr17);

$result = $tester->callTool('order.status', ['orderId' => '42']);
$this->assertSame('paid', $result['content'][0]['text']);

$tester->listTools();                 // tool definitions
$tester->readResource('app://x');     // resource contents
$tester->request('prompts/list');     // any raw JSON-RPC method
```

### Schema snapshot: catch accidental contract drift

[](#schema-snapshot-catch-accidental-contract-drift)

A changed method signature silently changes the generated `inputSchema` — and breaks agents mid-flight. `Testing\SchemaSnapshot` snapshots every served capability definition into a committed JSON file; drift fails the test until the snapshot is regenerated deliberately (delete the file and re-run):

```
SchemaSnapshot::assert($tester, __DIR__ . '/mcp-schema.json');
// first run writes the file; a mismatch throws with a per-section summary:
// "tools: changed [order.status]; prompts: added [code-review]"
```

When bumping the `mcp/sdk` pin, expect to regenerate: schema serialization may legitimately change between SDK minors.

For interactive debugging use the official MCP Inspector:

```
npx @modelcontextprotocol/inspector
# transport: Streamable HTTP, URL: https://your-app/rest/mcp,
# header: X-Mcp-Secret:
```

Roadmap
-------

[](#roadmap)

Planned direction (tool-call interceptors, AI audit trail, session budgets, tenant-scoped serving, per-session tool visibility): see [ROADMAP.md](ROADMAP.md).

Development
-----------

[](#development)

No PHP/Composer on the host — run in Docker via the `composer:2` image:

```
docker run --rm -v "$PWD":/app -w /app composer:2 composer build
```

Or with Make: `make build`, `make cs-fix`, `make psalm`, `make test`.

License
-------

[](#license)

BSD-3-Clause. See [LICENSE.md](LICENSE.md).

###  Health Score

49

—

FairBetter than 94% of packages

Maintenance93

Actively maintained with recent releases

Popularity21

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

15

Last Release

23d ago

Major Versions

v1.8.0 → v2.0.02026-07-27

### Community

Maintainers

![](https://www.gravatar.com/avatar/b0812d5572a7041dfe36e222d295b2e6dc55833a605350fcde58a51a5965ed30?d=identicon)[rasuvaeff](/maintainers/rasuvaeff)

---

Top Contributors

[![rasuvaeff](https://avatars.githubusercontent.com/u/1352718?v=4)](https://github.com/rasuvaeff "rasuvaeff (4 commits)")

---

Tags

aillmmcpmodel-context-protocolphppsr-15yii3mcpaipsr-15llmyii3Model Context Protocol

###  Code Quality

Static AnalysisPsalm, Rector

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/rasuvaeff-yii3-mcp/health.svg)

```
[![Health](https://phpackages.com/badges/rasuvaeff-yii3-mcp/health.svg)](https://phpackages.com/packages/rasuvaeff-yii3-mcp)
```

###  Alternatives

[tempest/framework

The PHP framework that gets out of your way.

2.3k37.6k21](/packages/tempest-framework)[typo3/cms

TYPO3 CMS is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.

1.2k1.9M122](/packages/typo3-cms)[typo3/cms-core

TYPO3 CMS Core

3313.6M5.6k](/packages/typo3-cms-core)[flow-php/flow

PHP ETL - Extract Transform Load - Data processing framework

86337.5k](/packages/flow-php-flow)[cakephp/cakephp

The CakePHP framework

8.9k20.0M1.9k](/packages/cakephp-cakephp)[laravel/framework

The Laravel Framework.

34.9k556.2M21.5k](/packages/laravel-framework)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
