@@ -6,6 +6,11 @@ It is the implementation-oriented guide aligned with `PRD.md` and `SPEC.md`.
66Contract boundary:
77- ` SPEC.md ` and ` TOOLSET.md ` are normative.
88- ` DOCS.md ` describes how to implement and operate those contracts.
9+ - ` OPERATIONS.md ` is the day-2 operator runbook (profiles, health checks, triage).
10+
11+ Status marker:
12+ - Contract target: ` SPEC 1.0-contract ` .
13+ - Runtime baseline in current repository: ` Gate C baseline implemented (full validation pending) ` .
914
1015## 1) Overview
1116` eMCP ` is a thin Evo-native adapter around ` laravel/mcp ` .
@@ -32,6 +37,43 @@ Implementation order is mandatory:
3237
3338Minimal first release is Gate A only.
3439
40+ ## 2.1) Laravel MCP Parity Contract
41+ eMCP keeps upstream ` laravel/mcp ` behavior as the baseline:
42+ - ` GET ` on MCP transport route returns ` 405 ` .
43+ - ` POST ` processes JSON-RPC messages.
44+ - ` MCP-Session-Id ` is passed through request/response.
45+ - ` 202 ` is preserved for no-reply notification flows.
46+ - SSE transport response uses ` text/event-stream ` when streaming is enabled.
47+ - Upstream command surface (` make:mcp-* ` , ` mcp:start ` , ` mcp:inspector ` ) remains available.
48+
49+ eMCP-specific logic is additive (ACL/scopes/policies), not a protocol rewrite.
50+
51+ ## 2.2) Ecosystem Interop Map
52+ - ` sApi ` : external exposure for MCP endpoints through route providers and JWT scopes.
53+ - ` sTask ` : async dispatch for long-running MCP calls (` emcp_dispatch ` worker).
54+ - ` eAi ` : AI runtime can consume eMCP tools in manager or API mode.
55+ - ` dAi ` : manager orchestration UI can consume stable eMCP tool contracts.
56+
57+ Boundary rule:
58+ - eMCP provides protocol/runtime/policy contracts.
59+ - orchestration concepts live in consuming packages, not in eMCP core.
60+
61+ ## 2.3) Fast Path: One MCP Server, Internal + External
62+ 1 . Generate primitives:
63+ ``` bash
64+ php artisan make:mcp-server ContentServer
65+ php artisan make:mcp-tool HealthTool
66+ ```
67+ Generated classes are placed under ` core/custom/app/Mcp/... ` .
68+ 2 . Register server entry in ` core/custom/config/mcp.php ` .
69+ 3 . Verify manager/internal call:
70+ - ` POST /{manager_prefix}/{handle} ` with manager session and ` emcp ` permission.
71+ 4 . Verify external API call (with ` sApi ` installed):
72+ - ` POST /{SAPI_BASE_PATH}/{SAPI_VERSION}/mcp/{handle} `
73+ - ` Authorization: Bearer <jwt> ` with required ` mcp:* ` scopes.
74+ 5 . Optional async mode:
75+ - ` queue.driver=stask ` + dispatch endpoint + task progress tracking.
76+
3577## User Guide
3678
3779## 3) Requirements
@@ -122,6 +164,8 @@ return [
122164
123165 'limits' => [
124166 'max_payload_kb' => 256,
167+ 'max_result_items' => 100,
168+ 'max_result_bytes' => 1048576,
125169 ],
126170
127171 'logging' => [
@@ -143,6 +187,7 @@ return [
143187 'max_offset' => 5000,
144188 ],
145189 'models' => [
190+ 'max_offset' => 5000,
146191 'allow' => [
147192 'SiteTemplate', 'SiteTmplvar', 'SiteTmplvarContentvalue',
148193 'SiteSnippet', 'SitePlugin', 'SiteModule', 'Category',
@@ -176,21 +221,25 @@ return [
176221 'handle' => 'content',
177222 'transport' => 'web',
178223 'route' => '/mcp/content',
179- 'class' => App\Mcp \Servers\ContentServer::class,
224+ 'class' => EvolutionCMS\eMCP \Servers\ContentServer::class,
180225 'enabled' => true,
181226 'auth' => 'sapi_jwt',
182227 'scopes' => ['mcp:read', 'mcp:call'],
183228 ],
184229 [
185230 'handle' => 'content-local',
186231 'transport' => 'local',
187- 'class' => App\Mcp \Servers\ContentServer::class,
188- 'enabled' => true ,
232+ 'class' => EvolutionCMS\eMCP \Servers\ContentServer::class,
233+ 'enabled' => false ,
189234 ],
190235 ],
191236];
192237```
193238
239+ Note:
240+ - ` content-local ` is disabled by default to avoid duplicate tool-name registration conflicts with ` content ` .
241+ - Enable local transport only when conflicting server entries are disabled or use non-overlapping tool names.
242+
194243Validation rules:
195244- ` handle ` must be unique
196245- ` class ` must exist and extend ` Laravel\Mcp\Server `
@@ -208,6 +257,23 @@ Route semantics:
208257- Gate A manager endpoint is ` /{manager_prefix}/{handle} ` .
209258- ` servers[*].route ` is the web transport route binding and is externally relevant in API mode (Gate B+).
210259
260+ ## 6.3 Configuration Presets (Practical)
261+ Use these presets to reduce setup friction:
262+
263+ - ` manager-only ` :
264+ - ` mode.internal=true ` , ` mode.api=false `
265+ - use manager endpoint only (` /{manager_prefix}/{handle} ` )
266+ - ` api-only ` :
267+ - ` mode.internal=false ` , ` mode.api=true `
268+ - require ` sApi ` + JWT scopes
269+ - ` hybrid ` (recommended default):
270+ - ` mode.internal=true ` , ` mode.api=true `
271+ - same tool contract available for manager and API consumers
272+
273+ Async add-on (any preset):
274+ - ` queue.driver=stask ` for long-running calls.
275+ - ` queue.failover=sync ` for resilient fallback on installations without ` sTask ` .
276+
211277## 7) Server Registration Model
212278Upstream Laravel MCP expects ` routes/ai.php ` .
213279` eMCP ` replaces this with config-first registration for Evo.
@@ -254,6 +320,16 @@ Safety constraints:
254320- allow only approved operators/casts
255321- enforce ` depth/limit/offset ` caps from config
256322
323+ Contract-first execution style:
324+ - each tool call follows ` validate -> authorize -> query -> map -> paginate `
325+ - one tool should map to one explicit handler/procedure
326+ - hidden query/policy side effects outside the pipeline are discouraged
327+
328+ Orchestration execution profile (post-MVP):
329+ - ` Intent -> PolicyCheck -> Task(s) -> EvidenceTrace -> ApprovalGate `
330+ - planner actions should be constrained by policy-valid action sets
331+ - intent/task/evidence linkage should be auditable end-to-end
332+
257333Model catalog profile (read-only by default):
258334- ` evo.model.list `
259335- ` evo.model.get `
@@ -324,11 +400,13 @@ Via `McpRouteProvider` (`RouteProviderInterface`):
324400- ` POST /mcp/{server}/dispatch `
325401
326402Recommended middleware chain:
327- - ` sapi .jwt`
403+ - ` emcp .jwt`
328404- ` emcp.scope `
329405- ` emcp.actor `
330406- ` emcp.rate `
331407
408+ ` McpRouteProvider ` removes upstream ` sapi.jwt ` from MCP routes and uses ` emcp.jwt ` as the single JWT middleware.
409+
332410Error handling policy:
333411- transport/auth/middleware failures -> HTTP status (` 401/403/405/413/415 ` ) with non-JSON-RPC error body.
334412- JSON-RPC dispatch failures -> HTTP ` 200 ` + JSON-RPC ` error ` (` -32700 ` , ` -32600 ` , ` -32601 ` , ` -32602 ` , ` -32603 ` ).
@@ -445,12 +523,17 @@ php artisan mcp:start content-local
445523php artisan mcp:inspector content-local
446524```
447525
448- Planned eMCP operational commands:
526+ Before ` mcp:start content-local ` , enable ` content-local ` in ` core/custom/config/mcp.php ` and disable conflicting server entries if they expose identical tool names.
527+
528+ Available eMCP operational commands:
449529
450530``` bash
451531php artisan emcp:test
452- php artisan emcp:sync-workers
453532php artisan emcp:list-servers
533+ php artisan emcp:sync-workers
534+ composer run governance:update-lock
535+ composer run ci:check
536+ EMCP_INTEGRATION_ENABLED=1 EMCP_BASE_URL=" https://example.org" EMCP_API_PATH=" /api/v1/mcp/{server}" EMCP_API_TOKEN=" <jwt>" composer run test:integration:runtime
454537```
455538
456539## 16) Troubleshooting
0 commit comments