<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: HideyukiMORI</title>
    <description>The latest articles on DEV Community by HideyukiMORI (@hideyukimori).</description>
    <link>https://dev.to/hideyukimori</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3995621%2Fd22faba8-a5e8-4ded-a514-1558d81cc5db.jpg</url>
      <title>DEV Community: HideyukiMORI</title>
      <link>https://dev.to/hideyukimori</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hideyukimori"/>
    <language>en</language>
    <item>
      <title>I built a tiny PHP framework for AI-readable business APIs</title>
      <dc:creator>HideyukiMORI</dc:creator>
      <pubDate>Mon, 22 Jun 2026 13:25:37 +0000</pubDate>
      <link>https://dev.to/hideyukimori/i-built-a-tiny-php-framework-for-ai-readable-business-apis-48eo</link>
      <guid>https://dev.to/hideyukimori/i-built-a-tiny-php-framework-for-ai-readable-business-apis-48eo</guid>
      <description>&lt;p&gt;I have been building a small PHP framework called &lt;strong&gt;NENE2&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is not a Laravel replacement.&lt;br&gt;
It is not a full-stack framework.&lt;br&gt;
It is not trying to hide everything behind magic.&lt;/p&gt;

&lt;p&gt;NENE2 is a tiny, API-first PHP foundation for building &lt;strong&gt;AI-readable business APIs&lt;/strong&gt;: small services with explicit HTTP boundaries, OpenAPI contracts, Problem Details errors, and optional MCP tool catalogs for AI agents.&lt;/p&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/hideyukiMORI/NENE2" rel="noopener noreferrer"&gt;hideyukiMORI/NENE2&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Why build another PHP framework?
&lt;/h2&gt;

&lt;p&gt;Most business software does not start as a beautiful greenfield platform.&lt;/p&gt;

&lt;p&gt;It starts as a request like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Can we expose this workflow as an API?"&lt;/li&gt;
&lt;li&gt;"Can an internal tool call this safely?"&lt;/li&gt;
&lt;li&gt;"Can an AI agent look up the status without touching the database?"&lt;/li&gt;
&lt;li&gt;"Can we keep this small enough that a team can actually understand it?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Large frameworks are great when you need their ecosystem.&lt;/p&gt;

&lt;p&gt;But for small business APIs, I often want something quieter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;explicit routes&lt;/li&gt;
&lt;li&gt;small handlers&lt;/li&gt;
&lt;li&gt;use cases that do not know about HTTP&lt;/li&gt;
&lt;li&gt;repository interfaces&lt;/li&gt;
&lt;li&gt;OpenAPI as the public contract&lt;/li&gt;
&lt;li&gt;predictable error responses&lt;/li&gt;
&lt;li&gt;tests that prove the behavior&lt;/li&gt;
&lt;li&gt;a clean boundary for AI / MCP tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the design space where NENE2 lives.&lt;/p&gt;
&lt;h2&gt;
  
  
  The core idea: API first, AI readable
&lt;/h2&gt;

&lt;p&gt;NENE2 assumes that the API is the primary surface.&lt;/p&gt;

&lt;p&gt;Server-rendered HTML can exist, and a React frontend starter can exist, but the backend should not become frontend build glue. The stable contract is the HTTP API.&lt;/p&gt;

&lt;p&gt;The framework is organized around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PSR-7 / PSR-15 / PSR-17&lt;/strong&gt; HTTP runtime direction&lt;/li&gt;
&lt;li&gt;explicit routing and middleware&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenAPI 3.1&lt;/strong&gt; contract documentation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RFC 9457 Problem Details&lt;/strong&gt; for errors&lt;/li&gt;
&lt;li&gt;typed configuration objects&lt;/li&gt;
&lt;li&gt;PSR-11 dependency injection&lt;/li&gt;
&lt;li&gt;PDO database adapters and transaction boundaries&lt;/li&gt;
&lt;li&gt;optional React + TypeScript frontend starter&lt;/li&gt;
&lt;li&gt;local MCP server support behind the same API boundary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to make the code clever.&lt;/p&gt;

&lt;p&gt;The goal is to make the code easy to inspect by a human developer, a reviewer, or an AI coding agent.&lt;/p&gt;
&lt;h2&gt;
  
  
  A boring architecture on purpose
&lt;/h2&gt;

&lt;p&gt;The reference domain example follows a simple flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP Handler
  -&amp;gt; Use Case
  -&amp;gt; Repository Interface
  -&amp;gt; PDO Adapter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, the Note CRUD reference implementation includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;route + handler classes&lt;/li&gt;
&lt;li&gt;use case classes&lt;/li&gt;
&lt;li&gt;readonly input/output DTOs&lt;/li&gt;
&lt;li&gt;repository interface&lt;/li&gt;
&lt;li&gt;PDO repository&lt;/li&gt;
&lt;li&gt;exception-to-Problem-Details mapping&lt;/li&gt;
&lt;li&gt;OpenAPI paths and schemas&lt;/li&gt;
&lt;li&gt;unit, HTTP, and PDO integration tests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is intentionally boring.&lt;/p&gt;

&lt;p&gt;I want application behavior to be visible in the file tree instead of being implied by framework convention.&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenAPI is the handoff document
&lt;/h2&gt;

&lt;p&gt;For NENE2, OpenAPI is not an afterthought.&lt;/p&gt;

&lt;p&gt;The repository ships an OpenAPI 3.1 document, Swagger UI, and runtime contract tests for example endpoints.&lt;/p&gt;

&lt;p&gt;Locally, after starting the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt; app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful URLs include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:8200/health
http://localhost:8200/examples/ping
http://localhost:8200/openapi.php
http://localhost:8200/docs/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This matters because the OpenAPI file is also the bridge to other tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generated clients&lt;/li&gt;
&lt;li&gt;contract tests&lt;/li&gt;
&lt;li&gt;documentation&lt;/li&gt;
&lt;li&gt;MCP tool catalogs&lt;/li&gt;
&lt;li&gt;AI-assisted development workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The API contract is the shared language.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP should not mean "let AI touch the database"
&lt;/h2&gt;

&lt;p&gt;One of the ideas behind NENE2 is that AI agents should operate through documented API boundaries.&lt;/p&gt;

&lt;p&gt;I do not want an agent to directly query or mutate production tables.&lt;/p&gt;

&lt;p&gt;Instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI Agent
  -&amp;gt; MCP Tool
  -&amp;gt; documented HTTP API
  -&amp;gt; application use case
  -&amp;gt; repository / transaction boundary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NENE2 includes local MCP server support and guidance for mapping tools to OpenAPI-backed operations.&lt;/p&gt;

&lt;p&gt;Read tools can inspect state.&lt;br&gt;
Write tools require explicit authentication.&lt;br&gt;
The application still owns validation, authorization, logging, and error handling.&lt;/p&gt;

&lt;p&gt;That boundary is the important part.&lt;/p&gt;
&lt;h2&gt;
  
  
  Field-tested through real apps
&lt;/h2&gt;

&lt;p&gt;NENE2 is not only a framework repository.&lt;/p&gt;

&lt;p&gt;I have been using it as the foundation for a family of self-hosted business OSS projects, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NeNe Invoice&lt;/strong&gt; — quote and invoice management for Japan qualified invoices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NeNe Vault&lt;/strong&gt; — received-document archive for electronic record retention&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NeNe Records&lt;/strong&gt; — typed headless CMS / flexible entity platform&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NeNe Deal&lt;/strong&gt; — lightweight B2B deal pipeline&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NeNe Contact&lt;/strong&gt; — embeddable contact forms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;nene-mcp&lt;/strong&gt; — stdio MCP bridge for OpenAPI-backed HTTP APIs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;nene2-python&lt;/strong&gt; — Python reference implementation of the same philosophy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;nene2-js&lt;/strong&gt; / &lt;strong&gt;nene2-node&lt;/strong&gt; — TypeScript ecosystem pieces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some of these products are Japan-specific.&lt;br&gt;
That is fine.&lt;/p&gt;

&lt;p&gt;The point is that the framework is tested against real business shapes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;authentication&lt;/li&gt;
&lt;li&gt;multi-tenancy&lt;/li&gt;
&lt;li&gt;OpenAPI&lt;/li&gt;
&lt;li&gt;admin UIs&lt;/li&gt;
&lt;li&gt;Docker local stacks&lt;/li&gt;
&lt;li&gt;database migrations&lt;/li&gt;
&lt;li&gt;exports&lt;/li&gt;
&lt;li&gt;audit logs&lt;/li&gt;
&lt;li&gt;MCP catalogs&lt;/li&gt;
&lt;li&gt;AI-readable documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Framework design gets better when it is forced through real applications.&lt;/p&gt;
&lt;h2&gt;
  
  
  What NENE2 is not
&lt;/h2&gt;

&lt;p&gt;NENE2 is deliberately small.&lt;/p&gt;

&lt;p&gt;It is not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a Laravel or Symfony replacement&lt;/li&gt;
&lt;li&gt;a no-code platform&lt;/li&gt;
&lt;li&gt;an ORM-first framework&lt;/li&gt;
&lt;li&gt;a CMS&lt;/li&gt;
&lt;li&gt;a frontend framework&lt;/li&gt;
&lt;li&gt;an AI agent runtime&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is a small foundation for teams or solo developers who want explicit PHP APIs and documented handoff points.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick start
&lt;/h2&gt;

&lt;p&gt;Clone the repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/hideyukiMORI/NENE2.git
&lt;span class="nb"&gt;cd &lt;/span&gt;NENE2
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
docker compose build
docker compose run &lt;span class="nt"&gt;--rm&lt;/span&gt; app composer &lt;span class="nb"&gt;install
&lt;/span&gt;docker compose run &lt;span class="nt"&gt;--rm&lt;/span&gt; app composer check
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt; app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or install it as a Composer dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require hideyukimori/nene2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NENE2 targets PHP 8.4+ and uses Docker as the standard development runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "AI-readable" matters
&lt;/h2&gt;

&lt;p&gt;AI-assisted development is not only about generating code.&lt;/p&gt;

&lt;p&gt;It is also about whether the system is readable enough for an agent to help safely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can it find the route?&lt;/li&gt;
&lt;li&gt;Can it understand the request and response shape?&lt;/li&gt;
&lt;li&gt;Can it see the use case?&lt;/li&gt;
&lt;li&gt;Can it run the focused tests?&lt;/li&gt;
&lt;li&gt;Can it avoid bypassing validation?&lt;/li&gt;
&lt;li&gt;Can it call a documented tool instead of guessing a database query?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NENE2 tries to make those answers obvious.&lt;/p&gt;

&lt;p&gt;Not by adding more magic.&lt;/p&gt;

&lt;p&gt;By removing ambiguity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;NENE2: &lt;a href="https://github.com/hideyukiMORI/NENE2" rel="noopener noreferrer"&gt;https://github.com/hideyukiMORI/NENE2&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Packagist: &lt;a href="https://packagist.org/packages/hideyukimori/nene2" rel="noopener noreferrer"&gt;https://packagist.org/packages/hideyukimori/nene2&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;nene2-python: &lt;a href="https://github.com/hideyukiMORI/nene2-python" rel="noopener noreferrer"&gt;https://github.com/hideyukiMORI/nene2-python&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;nene2-js: &lt;a href="https://github.com/hideyukiMORI/nene2-js" rel="noopener noreferrer"&gt;https://github.com/hideyukiMORI/nene2-js&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;nene-mcp: &lt;a href="https://github.com/hideyukiMORI/nene-mcp" rel="noopener noreferrer"&gt;https://github.com/hideyukiMORI/nene-mcp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub profile: &lt;a href="https://github.com/hideyukiMORI" rel="noopener noreferrer"&gt;https://github.com/hideyukiMORI&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am still refining the framework and the surrounding NeNe OSS series.&lt;/p&gt;

&lt;p&gt;If you are interested in API-first PHP, OpenAPI, MCP, or AI-readable business software, feedback is very welcome.&lt;/p&gt;

</description>
      <category>php</category>
      <category>opensource</category>
      <category>api</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
