@@ -91,6 +91,55 @@ public function testReadModeCallsKnownReadMethodByModuleAndActionSelector(): voi
9191 self ::assertIsString ($ content ['result ' ]);
9292 }
9393
94+ public function testReadModeAcceptsEmptyParametersList (): void
95+ {
96+ McpTestHelper::setRawApiAccessMode ('read ' );
97+
98+ $ server = McpTestHelper::buildServer ();
99+ $ sessionId = McpTestHelper::initializeSession ($ server );
100+ $ content = McpTestHelper::callToolAndAssertSuccess (
101+ $ server ,
102+ $ sessionId ,
103+ ApiCallRead::TOOL_NAME ,
104+ ['method ' => 'API.getMatomoVersion ' , 'parameters ' => []],
105+ __METHOD__
106+ );
107+
108+ $ resolvedMethod = $ content ['resolvedMethod ' ] ?? null ;
109+ self ::assertIsArray ($ resolvedMethod );
110+ self ::assertSame ('API.getMatomoVersion ' , $ resolvedMethod ['method ' ] ?? null );
111+ self ::assertIsString ($ content ['result ' ] ?? null );
112+ }
113+
114+ public function testReadModeAcceptsEmptyParametersObject (): void
115+ {
116+ McpTestHelper::setRawApiAccessMode ('read ' );
117+
118+ $ server = McpTestHelper::buildServer ();
119+ $ sessionId = McpTestHelper::initializeSession ($ server );
120+ $ payload = json_encode ([
121+ 'jsonrpc ' => '2.0 ' ,
122+ 'id ' => __METHOD__ ,
123+ 'method ' => 'tools/call ' ,
124+ 'params ' => [
125+ 'name ' => ApiCallRead::TOOL_NAME ,
126+ 'arguments ' => [
127+ 'method ' => 'API.getMatomoVersion ' ,
128+ 'parameters ' => new \stdClass (),
129+ ],
130+ ],
131+ ], JSON_THROW_ON_ERROR );
132+
133+ $ response = McpTestHelper::postJson ($ server , $ payload , ['Mcp-Session-Id ' => $ sessionId ]);
134+ $ message = McpTestHelper::decodeResponse ($ response );
135+ $ result = McpTestHelper::parseCallTool ($ message );
136+ $ content = McpTestHelper::assertToolSuccess ($ result );
137+ $ resolvedMethod = $ content ['resolvedMethod ' ] ?? null ;
138+ self ::assertIsArray ($ resolvedMethod );
139+ self ::assertSame ('API.getMatomoVersion ' , $ resolvedMethod ['method ' ] ?? null );
140+ self ::assertIsString ($ content ['result ' ] ?? null );
141+ }
142+
94143 public function testReadModeRejectsWriteOnlyMethod (): void
95144 {
96145 McpTestHelper::setRawApiAccessMode ('read ' );
@@ -329,6 +378,29 @@ public function testRejectsReservedParameterKeys(): void
329378 );
330379 }
331380
381+ public function testRejectsNonEmptyParametersListAtSchemaLevel (): void
382+ {
383+ McpTestHelper::setRawApiAccessMode ('read ' );
384+
385+ $ server = McpTestHelper::buildServer ();
386+ $ sessionId = McpTestHelper::initializeSession ($ server );
387+ $ message = McpTestHelper::callToolExpectInvalidParams (
388+ $ server ,
389+ $ sessionId ,
390+ ApiCallRead::TOOL_NAME ,
391+ [
392+ 'method ' => 'API.getMatomoVersion ' ,
393+ 'parameters ' => ['flat ' ],
394+ ],
395+ __METHOD__
396+ );
397+
398+ self ::assertStringContainsString (
399+ "Invalid parameters for tool ' " . ApiCallRead::TOOL_NAME . "': " ,
400+ $ message ->message
401+ );
402+ }
403+
332404 public function testRejectsMissingSelectorAtSchemaLevel (): void
333405 {
334406 McpTestHelper::setRawApiAccessMode ('full ' );
0 commit comments