PHPackages                             trust-medical/laravel-chatwork-api - 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. [Mail &amp; Notifications](/categories/mail)
4. /
5. trust-medical/laravel-chatwork-api

ActiveLibrary[Mail &amp; Notifications](/categories/mail)

trust-medical/laravel-chatwork-api
==================================

A Laravel package for the Chatwork API v2 (HTTP client, Notification channel, OAuth2).

v1.2.0(1mo ago)019MITPHPPHP ^8.3CI passing

Since May 25Pushed 1mo agoCompare

[ Source](https://github.com/trust-medical/laravel-chatwork-api)[ Packagist](https://packagist.org/packages/trust-medical/laravel-chatwork-api)[ Docs](https://github.com/trust-medical/laravel-chatwork-api)[ RSS](/packages/trust-medical-laravel-chatwork-api/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (5)Dependencies (14)Versions (11)Used By (0)

laravel-chatwork-api
====================

[](#laravel-chatwork-api)

[Chatwork API v2](https://developer.chatwork.com/reference) を Laravel から安全に利用するための Composer パッケージです。**Facade / DI / Laravel Notification** の3経路を公式サポートします。

- PHP `^8.3`
- Laravel `^11.0 || ^12.0 || ^13.0`
- Chatwork API v2（Base URI: `https://api.chatwork.com/v2`）

特長
--

[](#特長)

- すべてのエンドポイント（rooms / messages / members / tasks / files / links / contacts / me / my / incoming\_requests）をカバー
- API Token と OAuth2 Bearer Token の両認証に対応（排他は型で構造的に保証）
- 戻り値モードを呼び出し側でチェーン切り替え（DTO / 配列 / Collection / Response / Result）
- `readonly` Response DTO と immutable Request オブジェクトによる型安全な API
- Laravel Notification channel（`ChatworkChannel`）を同梱
- OAuth2 認可フロー（認可URL生成・callback・refresh token、`Cache::lock` による多重 refresh 防止）

インストール
------

[](#インストール)

```
composer require trust-medical/laravel-chatwork-api
```

ServiceProvider と Facade は Laravel のパッケージ自動検出で登録されるため、手動登録は不要です。

設定ファイルを publish します:

```
php artisan vendor:publish --tag="chatwork-config"
```

`.env` に最低限の認証情報を設定します:

```
CHATWORK_API_TOKEN=your-api-token
```

設定
--

[](#設定)

`config/chatwork.php` の主なキー:

キー既定値説明`default``default`使用する connection 名（`CHATWORK_CONNECTION`）`base_uri``https://api.chatwork.com/v2`API ベース URI`timeout``10`リクエストタイムアウト秒`response.mode``dto`既定の戻り値モード（`CHATWORK_RESPONSE_MODE`。無効値は `ChatworkConfigurationException`）`connections`API Token connection 1件複数 connection 定義可`oauth`—OAuth2 設定（後述）`oauth.timeout``10`OAuth トークン要求のタイムアウト秒（`CHATWORK_OAUTH_TIMEOUT`）複数 connection の例:

```
'connections' => [
    'default' => [
        'auth' => 'api_token',
        'token' => env('CHATWORK_API_TOKEN'),
    ],
    'bot' => [
        'auth' => 'api_token',
        'token' => env('CHATWORK_BOT_TOKEN'),
    ],
],
```

基本的な使い方
-------

[](#基本的な使い方)

```
use TrustMedical\LaravelChatworkApi\Facades\Chatwork;

// メッセージ送信
Chatwork::rooms()->messages()->create(123, 'こんにちは');

// 自分の情報を取得（既定は DTO で返る）
$me = Chatwork::me()->get();
echo $me->name;
```

### connection の切り替え

[](#connection-の切り替え)

```
// 設定済み connection を名前で指定
Chatwork::connection('bot')->rooms()->messages()->create(123, 'bot からの通知');

// その場限りのトークンで実行
Chatwork::withApiToken($token)->me()->get();
Chatwork::withBearerToken($oauthAccessToken)->me()->get();
```

`connection()` / `withApiToken()` / `withBearerToken()` / `as*()` は新しい manager を返すイミュータブル設計のため、安全にチェーンできます。`ChatworkManager` はコンテナ singleton ですが、これらは共有インスタンスを mutate せず clone を返すため、**Laravel Octane / Swoole / キューワーカー等の常駐プロセスでもリクエスト間で connection・認証情報・戻り値モードが漏れません**。

戻り値モード
------

[](#戻り値モード)

既定は `asDto()`。呼び出し側でチェーンして変更できます。

モード成功時4xx / 5xx`asDto()`readonly DTO`ChatworkRequestException` を throw`asArray()`配列`ChatworkRequestException` を throw`asCollection()``Illuminate\Support\Collection``ChatworkRequestException` を throw`asResponse()`Laravel HTTP Responsethrow しない`asPsrResponse()`PSR-7 Responsethrow しない`asResult()``Result`（`Http\Result`）throw しない```
$rooms = Chatwork::asCollection()->rooms()->list();
$raw   = Chatwork::asArray()->me()->get();
$res   = Chatwork::asResponse()->rooms()->find(123);
```

> 送信前バリデーション失敗は戻り値モードに関わらず常に `ChatworkValidationException` を throw します。

### メソッド別の戻り値型（`asDto()` 契約）

[](#メソッド別の戻り値型asdto-契約)

各 Resource メソッドのネイティブ署名は `: mixed` です（戻り値型は `ResponseMode`により実行時に変わるため）。下表は **既定の `asDto()` モード** での戻り値型です。 `asArray()` / `asCollection()` / `asResponse()` / `asPsrResponse()` / `asResult()`へ切り替えた場合は宣言型・下表の型と実行時型が乖離し、その型解釈は呼び出し側の 責務になります（設計判断の詳細は `docs/03-package-architecture/response-strategy.md`）。

メソッド`asDto()` 戻り値型`rooms()->list()``list``rooms()->create()``CreatedRoom``rooms()->find()``RoomData``rooms()->update()``UpdatedRoom``rooms()->leaveRoom()` / `deleteRoom()``NoContentData``rooms()->messages()->create()``CreatedMessage``rooms()->messages()->list()``list``rooms()->messages()->find()``MessageData``rooms()->messages()->update()``UpdatedMessage``rooms()->messages()->deleteMessage()``DeletedMessage``rooms()->messages()->markAsRead()``MarkReadResult``rooms()->messages()->markAsUnread()``MarkUnreadResult``rooms()->members()->list()``list``rooms()->members()->replaceMembers()``ReplacedRoomMembers``rooms()->tasks()->list()``list``rooms()->tasks()->create()``CreatedTask``rooms()->tasks()->find()` / `updateStatus()``RoomTaskData``rooms()->files()->list()``list``rooms()->files()->upload()``UploadedRoomFile``rooms()->files()->find()``RoomFileData``rooms()->links()->find()` / `create()` / `update()` / `deleteLink()``RoomLinkData``contacts()->list()``list``me()->get()``MyAccountData``my()->status()``MyStatusData``my()->tasks()``list``incomingRequests()->list()``list``incomingRequests()->accept()``ContactData``incomingRequests()->decline()``NoContentData``list` 系で Chatwork が 204 を返す場合、`asDto()` では `[]` に縮退します （`contacts()->list()` / `my()->tasks()` / `incomingRequests()->list()`）。

リソース別の例
-------

[](#リソース別の例)

### Rooms

[](#rooms)

```
use TrustMedical\LaravelChatworkApi\Data\Requests\CreateRoomRequest;
use TrustMedical\LaravelChatworkApi\Data\Requests\UpdateRoomRequest;
use TrustMedical\LaravelChatworkApi\Enums\IconPreset;

Chatwork::rooms()->list();
Chatwork::rooms()->find(123);

Chatwork::rooms()->create(new CreateRoomRequest(
    name: '新規ルーム',
    membersAdminIds: [101, 102],
    description: 'チーム連絡用',
    iconPreset: IconPreset::Meeting,
));

Chatwork::rooms()->update(123, new UpdateRoomRequest(name: '改名後'));

// 破壊的操作は対象を明示した命名（曖昧な delete() は提供しない）
Chatwork::rooms()->leaveRoom(123);   // action_type=leave
Chatwork::rooms()->deleteRoom(123);  // action_type=delete
```

### Messages

[](#messages)

```
Chatwork::rooms()->messages()->create(123, '本文', selfUnread: true);
Chatwork::rooms()->messages()->list(123, force: true);
Chatwork::rooms()->messages()->find(123, '1024');
Chatwork::rooms()->messages()->update(123, '1024', '編集後の本文');
Chatwork::rooms()->messages()->deleteMessage(123, '1024');
Chatwork::rooms()->messages()->markAsRead(123, '1024');
Chatwork::rooms()->messages()->markAsUnread(123, '1024');
```

### Members

[](#members)

```
use TrustMedical\LaravelChatworkApi\Data\Requests\ReplaceRoomMembersRequest;

Chatwork::rooms()->members()->list(123);

Chatwork::rooms()->members()->replaceMembers(123, new ReplaceRoomMembersRequest(
    membersAdminIds: [101],
    membersMemberIds: [201, 202],
    membersReadonlyIds: [301],
));
```

### Tasks

[](#tasks)

```
use TrustMedical\LaravelChatworkApi\Data\Requests\CreateRoomTaskRequest;
use TrustMedical\LaravelChatworkApi\Enums\LimitType;
use TrustMedical\LaravelChatworkApi\Enums\TaskStatus;

Chatwork::rooms()->tasks()->create(123, new CreateRoomTaskRequest(
    body: '見積もりを確認する',
    toIds: [101, 102],
    limit: 1735718400,
    limitType: LimitType::Time,
));

Chatwork::rooms()->tasks()->list(123, status: TaskStatus::Open);
Chatwork::rooms()->tasks()->find(123, 456);
Chatwork::rooms()->tasks()->updateStatus(123, 456, TaskStatus::Done);
```

### Files

[](#files)

```
use TrustMedical\LaravelChatworkApi\Data\Requests\UploadRoomFileRequest;

Chatwork::rooms()->files()->upload(123, new UploadRoomFileRequest(
    path: storage_path('app/report.pdf'),
    message: '月次レポートです',
));

Chatwork::rooms()->files()->list(123);
Chatwork::rooms()->files()->find(123, 789, createDownloadUrl: true);
```

### Invitation Links

[](#invitation-links)

```
use TrustMedical\LaravelChatworkApi\Data\Requests\RoomLinkRequest;

Chatwork::rooms()->links()->find(123);
Chatwork::rooms()->links()->create(123, new RoomLinkRequest(
    code: 'team-invite',
    needAcceptance: true,
    description: '招待リンク',
));
Chatwork::rooms()->links()->update(123, new RoomLinkRequest(description: '説明更新'));
Chatwork::rooms()->links()->deleteLink(123);
```

### Me / My / Contacts / Incoming Requests

[](#me--my--contacts--incoming-requests)

```
Chatwork::me()->get();
Chatwork::my()->status();
Chatwork::my()->tasks(status: TaskStatus::Open);
Chatwork::contacts()->list();

Chatwork::incomingRequests()->list();
Chatwork::incomingRequests()->accept(456);
Chatwork::incomingRequests()->decline(456);
```

エラーハンドリング
---------

[](#エラーハンドリング)

### 例外

[](#例外)

例外発生条件`ChatworkValidationException`送信前バリデーション失敗（戻り値モードに関わらず常に throw）`ChatworkRequestException`4xx / 5xx（throw 系モード時）`ChatworkAuthenticationException`認証情報の解決失敗（connection 不正・OAuth refresh 失敗等）`ChatworkConfigurationException`設定・配線が不正（`oauth.state_store` / `oauth.token_repository` に不正クラス、`oauth.route_throttle` 形式不正、`base_uri` スキーム不正など）すべての例外は marker interface `ChatworkException` を実装します。本パッケージ由来の例外を一括捕捉したい場合は `catch (ChatworkException $e)` が使えます（`status()` / `violations()` などの固有メソッドは具象例外型で分岐してください）。

```
use TrustMedical\LaravelChatworkApi\Exceptions\ChatworkException;

try {
    Chatwork::rooms()->messages()->create(123, '本文');
} catch (ChatworkException $e) {
    // 本パッケージ由来の全例外をここで捕捉
}
```

`ChatworkRequestException` はエラーボディ2系統を取り出せます:

```
use TrustMedical\LaravelChatworkApi\Exceptions\ChatworkRequestException;

try {
    Chatwork::rooms()->messages()->create(123, '本文');
} catch (ChatworkRequestException $e) {
    $e->status();            // int
    $e->errors();            // string[]（通常 API: {"errors":[...]}）
    $e->error();             // ?string（OAuth: error）
    $e->errorDescription();  // ?string（OAuth: error_description）
    $e->rateLimit();         // ?array（429 時: limit / remaining / reset）
}
```

### `asResult()`（例外を投げない）

[](#asresult例外を投げない)

```
$result = Chatwork::asResult()->rooms()->messages()->create(123, '本文');

if ($result->failed()) {
    $result->status();   // int
    $result->errors();   // string[]
    $result->rateLimit();
    return;
}

$data = $result->data();
```

Notification チャンネル
------------------

[](#notification-チャンネル)

`Notification` から Chatwork へ送信できます。チャンネルは内部的に `asResult()` 固定で、4xx は permanent failure として例外化、5xx / 429 / ネットワークエラーはそのまま伝播してキュー再試行に委譲されます。

`ChatworkMessage` はメッセージ組み立て専用のビルダー / DTO です（`Notification` ではありません）。`ChatworkNotification` を継承すると `via()` は自動で `ChatworkChannel` に接続されるため、`toChatwork()` を実装するだけで送信できます。

```
use TrustMedical\LaravelChatworkApi\Notifications\ChatworkMessage;
use TrustMedical\LaravelChatworkApi\Notifications\ChatworkNotification;

class DeployFinished extends ChatworkNotification
{
    public function toChatwork(object $notifiable): ChatworkMessage
    {
        return (new ChatworkMessage())
            ->toRoom(123)
            ->info('デプロイ完了', "本番反映が完了しました。\nコミット: abc123")
            ->selfUnread();
    }
}
```

`ChatworkNotification` を使わず通常の `Notification` で `via()` に `[ChatworkChannel::class]` を返し、`toChatwork($notifiable): ChatworkMessage` を実装しても構いません（queueable・複数チャンネル併用などはこちら）。

メッセージビルダーは `body()` / `title()` / `code()` / `hr()` / `plain()` / `escape()` / `to()`（TO 付与）/ `toRoom()` / `selfUnread()` を提供します。

送信先は `ChatworkMessage::toRoom()` のほか、notifiable 側の `routeNotificationForChatwork()` でも指定できます（両方指定は競合エラー）:

```
use TrustMedical\LaravelChatworkApi\Notifications\ChatworkRoute;

public function routeNotificationForChatwork(): ChatworkRoute
{
    return ChatworkRoute::room(123)->connection('bot');
}
```

OAuth2
------

[](#oauth2)

`config/chatwork.php` の `oauth` セクションで設定します。

```
CHATWORK_OAUTH_CLIENT_ID=...
CHATWORK_OAUTH_CLIENT_SECRET=...
CHATWORK_OAUTH_REDIRECT_URI=https://example.com/chatwork/oauth/callback
```

> **Confidential / Public Client の自動判定:** Chatwork は OAuth クライアント 種別ごとにトークンエンドポイントの認証方式が異なります。Confidential Client (client\_secret あり) は `Authorization: Basic Base64(client_id:client_secret)`ヘッダーが必須、Public Client (client\_secret なし) は body に `client_id` のみを 含めて Basic 認証ヘッダーを送りません。本ライブラリは `CHATWORK_OAUTH_CLIENT_SECRET`の有無 (空文字含む) で自動判定します。Confidential / Public を切り替える追加 設定キーはありません。

callback ルートは**既定で無効**です（セキュリティのため）。利用する場合は `config/chatwork.php` で有効化します:

```
'oauth' => [
    // ...
    'routes_enabled' => true,
    'route_prefix' => 'chatwork/oauth',
    'redirect_after_callback' => '/dashboard',
    'token_repository' => \App\Chatwork\DatabaseTokenRepository::class,
    'state_store' => null, // 既定は Cache ベース
],
```

有効化すると `GET {route_prefix}/callback`（ルート名 `chatwork.oauth.callback`）が登録されます。callback では `state` 検証が必須で、token は設定した `TokenRepository` に保存されます。取得済みトークンは `Chatwork::connection('oauth-connection')` 経由で利用でき、期限切れ時は `Cache::lock` で多重発行を防ぎつつ自動 refresh されます。

> **本番環境の推奨:** 既定の `StateStore` / `TokenRepository` は Cache ストアを使います。`state` の一度きりの消費（リプレイ攻撃防止）には read-and-delete のアトミック性が必要なため、本番では `redis` または `database` キャッシュドライバを使用してください。`array` / `file` ドライバは read→delete が非アトミックで、同一 `state` の二重消費が理論上成立し得ます。永続トークンには独自の `TokenRepository`（例: DB 実装）を設定することを推奨します。

> **トークンの暗号化:** 既定の `CacheTokenRepository` は access/refresh トークンを Laravel の `Encrypter`（`APP_KEY`）で暗号化してからキャッシュへ保存します。Redis / Memcached を直接参照されてもトークンは平文露出しません。`APP_KEY` 未設定だと `MissingAppKeyException` になります（通常の Laravel アプリでは設定済み）。`APP_KEY` をローテーションした場合、暗号化済みの既存トークンは復号できず「未保存」とみなされ、利用者は再認証が必要になります。独自の `TokenRepository` を使う場合は暗号化も自実装の責務です。

### callback ルートの throttle

[](#callback-ルートの-throttle)

`config/chatwork.php` の `oauth.route_throttle`（既定 `'10,1'` = 1分あたり10回）が callback ルートに `throttle` ミドルウェアとして適用され、`state` / `code` のブルートフォースを抑制します。`"max,decayMinutes"` 形式の文字列、または名前付き rate limiter 名を指定できます。`null` / 空文字で throttle を無効化します。形式不正値は ServiceProvider 起動時に `ChatworkConfigurationException` になります。

### 独自 RouteServiceProvider からの手動登録

[](#独自-routeserviceprovider-からの手動登録)

`routes_enabled` を `false` のままにしつつ、任意の middleware / ドメイン / プレフィックス配下で callback ルートを登録したい場合は、`ChatworkServiceProvider::registerOAuthRoutes()` を独自の `RouteServiceProvider` から呼び出せます（意図的に `public`）。

> **`route:cache` 利用時の注意:** OAuth callback ルートは `packageBooted()` 内のクロージャで登録されます。`php artisan route:cache` が有効な環境ではこのクロージャが実行されず、**callback ルートが登録されず**、また **`route_throttle` の形式検証も行われません**。`registerOAuthRoutes()` を独自 `RouteServiceProvider` から手動呼び出しする場合も `route:cache` 下では同様にスキップされます。`route:cache` を使う環境で OAuth callback を利用する場合は、ルートをアプリ側の実 routes ファイルに明示登録し、`route_throttle` の指定が実際に効いているか（`php artisan route:list` 等で）確認してください。

### 動的 (per-tenant) OAuth コネクション

[](#動的-per-tenant-oauth-コネクション)

Laravel のユーザーごとに別の OAuth access\_token を持つ SaaS / マルチテナント環境では、`Chatwork::forOAuthKey($key)` を使うと `TokenRepository` の検索キーをランタイムに指定して OAuth コネクションを組み立てられます。

```
// ユーザー単位の OAuth トークンで API を叩く
Chatwork::forOAuthKey((string) $user->id)
    ->rooms()
    ->messages()
    ->create($roomId, $body);

// レスポンスモードはどちら順で chain しても効く
Chatwork::asResult()->forOAuthKey((string) $user->id)->me()->get();
Chatwork::forOAuthKey((string) $user->id)->asResult()->me()->get();
```

固定 OAuth connection（`config/chatwork.php` で `auth: 'oauth'` を宣言する方式）との違い:

固定 OAuth connection`forOAuthKey()``config/chatwork.php` への connection 定義必要不要`TokenRepository` の検索キーconfig 固定（`connection_name`）ランタイム指定（`$key`）`Cache::lock` による refresh 直列化ありあり（同じ `OAuthTokenProvider` 経由）baseUri / timeout当該 connection から`$base` 引数（省略時は `config('chatwork.default')` の connection）から継承`$base` を明示すると、その connection の `base_uri` / `timeout` を継承しつつ `TokenRepository` のキーには `$key` を使います（`$base` は `auth` 値を問わず baseUri / timeout のメタデータ源としてのみ参照されます）。`$base` 指定が config に存在しない場合は `ChatworkAuthenticationException` を投げます。

> **`$key` の選び方:** `$key` は `TokenRepository::find()` / `save()` および `Cache::lock` のキー（`chatwork:oauth:refresh:`）として使われます。メールアドレス等の PII を直接渡さず、DB の User PK 等の安定 ID を使ってください。`Connection::$name` は `"oauth:{$key}"` 形式となり、例外メッセージ・ログに現れます。

> **manager を長期保持しない:** `forOAuthKey()` は呼び出し時点で `BearerTokenCredentials` を確定して `Connection` に焼き込みます（`connection()` と同じ resolve-at-bind セマンティクス）。access\_token の expire 後に再利用できないため、Queue worker / Octane でもリクエスト直前に都度呼び出してください。

テスト
---

[](#テスト)

```
composer test          # Pest 全件
composer test:coverage # カバレッジ（目標 80%+）
composer analyse       # PHPStan
composer lint          # Pint で整形
composer ci            # lint:test + analyse + test
```

すべてのテストは `Http::fake()` で実 API を叩かずに検証しています。

セキュリティ
------

[](#セキュリティ)

- API token / client secret / refresh token をログ・例外メッセージに含めません
- OAuth2 callback は `state` 検証を必須とし、ルートは既定で無効です
- API Token（`x-chatworktoken`）と OAuth2 Bearer（`Authorization: Bearer`）は1リクエストで同時送信されません（`Credentials` 実装で構造的に保証）
- OAuth2 `state` のリプレイ防止には read-and-delete のアトミック性が必要なため、本番では `redis` / `database` キャッシュドライバを推奨します（`array` / `file` は非アトミック）

脆弱性を発見した場合は公開 issue ではなく非公開でご連絡ください。

ライセンス
-----

[](#ライセンス)

[MIT License](LICENSE)

###  Health Score

42

—

FairBetter than 88% of packages

Maintenance89

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity55

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

5

Last Release

57d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/68323089?v=4)[web-tac](/maintainers/web-tac)[@web-tac](https://github.com/web-tac)

---

Top Contributors

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

---

Tags

laravelnotificationoauth2chatworkchatwork-api

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/trust-medical-laravel-chatwork-api/health.svg)

```
[![Health](https://phpackages.com/badges/trust-medical-laravel-chatwork-api/health.svg)](https://phpackages.com/packages/trust-medical-laravel-chatwork-api)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.5k30.2M151](/packages/laravel-cashier)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k15.1M136](/packages/laravel-pulse)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

77922.3M186](/packages/laravel-mcp)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9762.4M133](/packages/roots-acorn)

PHPackages © 2026

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