Skip to content

Commit b63c79d

Browse files
refactor: Cleanup internal architecture and dependencies
1 parent d849316 commit b63c79d

File tree

34 files changed

+486
-454
lines changed

34 files changed

+486
-454
lines changed

README.md

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -135,16 +135,10 @@ The server uses a decoupled architecture:
135135

136136
* **`ServerBuilder`:** Fluent interface (`Server::make()->...`) for configuration. Collects server identity, dependencies (Logger, Cache, Container, Loop), capabilities, and **manual** element registrations. Calls `build()` to create the `Server` instance.
137137
* **`Configuration`:** A value object holding the resolved configuration and dependencies.
138-
* **`Server`:** The central object holding the configured state and core logic components (`Registry`, `Processor`, `ClientStateManager`, `Configuration`). It's transport-agnostic. Provides methods to `discover()` elements and `listen()` via a specific transport.
138+
* **`Server`:** The central object holding the configured state and core logic components (`Registry`, `Protocol`, `Configuration`). It's transport-agnostic. Provides methods to `discover()` elements and `listen()` via a specific transport.
139+
* **`Protocol`:** Internal bridge listening to transport events and processes JSON-RPC messages from the transport.
139140
* **`Registry`:** Stores MCP element definitions. **Distinguishes between manually registered and discovered elements.** Handles optional caching of *discovered* elements only. Loads cached discovered elements upon instantiation if available.
140-
* **`Processor`:** Processes parsed JSON-RPC requests/notifications, executes handlers (via DI Container), formats results, handles errors.
141-
* **`SchemaGenerator`:** Generates JSON Schema for method parameters from PHP type hints and DocBlocks.
142-
* **`SchemaValidator`:** Validates incoming data against the generated JSON Schema.
143-
* **`ClientStateManager`:** Manages client runtime state (initialization, subscriptions, activity) using the configured cache.
144141
* **`ServerTransportInterface`:** Event-driven interface for server-side transports (`StdioServerTransport`, `HttpServerTransport`). Handles communication, emits events.
145-
* **`Protocol`:** Internal bridge listening to transport events, interacting with `Processor` and `ClientStateManager`.
146-
* **`discover()` Method:** An **explicit** method on the `Server` instance to trigger attribute discovery. Takes path configurations as arguments. By default, it clears previously discovered/cached elements before scanning and saves the new results to cache (if enabled).
147-
* **`listen()` Method:** Starts the server using a specific transport. Binds the `Protocol`, starts the transport listener, and **runs the event loop (blocking)**. Performs a pre-check and warns if no elements are registered and discovery hasn't run.
148142

149143
## Defining MCP Elements
150144

examples/01-discovery-stdio-calculator/server.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public function log($level, \Stringable|string $message, array $context = []): v
5656
}
5757

5858
try {
59-
$logger = new StderrLogger;
59+
$logger = new StderrLogger();
6060
$logger->info('Starting MCP Stdio Calculator Server...');
6161

6262
$server = Server::make()
@@ -66,7 +66,7 @@ public function log($level, \Stringable|string $message, array $context = []): v
6666

6767
$server->discover(__DIR__, ['.']);
6868

69-
$transport = new StdioServerTransport;
69+
$transport = new StdioServerTransport();
7070

7171
$server->listen($transport);
7272

examples/02-discovery-http-userprofile/server.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ public function log($level, \Stringable|string $message, array $context = []): v
5555
}
5656

5757
try {
58-
$logger = new StderrLogger;
58+
$logger = new StderrLogger();
5959
$logger->info('Starting MCP HTTP User Profile Server...');
6060

6161
// --- Setup DI Container for DI in McpElements class ---
62-
$container = new BasicContainer;
62+
$container = new BasicContainer();
6363
$container->set(LoggerInterface::class, $logger);
6464

6565
$server = Server::make()

examples/03-manual-registration-stdio/server.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ public function log($level, \Stringable|string $message, array $context = []): v
5151
}
5252

5353
try {
54-
$logger = new StderrLogger;
54+
$logger = new StderrLogger();
5555
$logger->info('Starting MCP Manual Registration (Stdio) Server...');
5656

57-
$container = new BasicContainer;
57+
$container = new BasicContainer();
5858
$container->set(LoggerInterface::class, $logger);
5959

6060
$server = Server::make()
@@ -67,7 +67,7 @@ public function log($level, \Stringable|string $message, array $context = []): v
6767
->withResourceTemplate([SimpleHandlers::class, 'getItemDetails'], 'item://{itemId}/details', 'get_item_details', mimeType: 'application/json')
6868
->build();
6969

70-
$transport = new StdioServerTransport;
70+
$transport = new StdioServerTransport();
7171
$server->listen($transport);
7272

7373
$logger->info('Server listener stopped gracefully.');

examples/04-combined-registration-http/server.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ public function log($level, \Stringable|string $message, array $context = []): v
5858
}
5959

6060
try {
61-
$logger = new StderrLogger;
61+
$logger = new StderrLogger();
6262
$logger->info('Starting MCP Combined Registration (HTTP) Server...');
6363

64-
$container = new BasicContainer;
64+
$container = new BasicContainer();
6565
$container->set(LoggerInterface::class, $logger); // ManualHandlers needs LoggerInterface
6666

6767
$server = Server::make()

examples/05-stdio-env-variables/EnvToolHandler.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77
class EnvToolHandler
88
{
9-
public function __construct() {}
9+
public function __construct()
10+
{
11+
}
1012

1113
/**
1214
* Performs an action that can be modified by an environment variable.

examples/05-stdio-env-variables/server.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function log($level, \Stringable|string $message, array $context = []): v
5151
}
5252

5353
try {
54-
$logger = new StderrLogger;
54+
$logger = new StderrLogger();
5555
$logger->info('Starting MCP Stdio Environment Variable Example Server...');
5656

5757
$server = Server::make()
@@ -61,7 +61,7 @@ public function log($level, \Stringable|string $message, array $context = []): v
6161

6262
$server->discover(__DIR__, ['.']);
6363

64-
$transport = new StdioServerTransport;
64+
$transport = new StdioServerTransport();
6565
$server->listen($transport);
6666

6767
$logger->info('Server listener stopped gracefully.');

examples/06-custom-dependencies-stdio/server.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@ public function log($level, \Stringable|string $message, array $context = []): v
6969
}
7070

7171
try {
72-
$logger = new StderrLogger;
72+
$logger = new StderrLogger();
7373
$logger->info('Starting MCP Custom Dependencies (Stdio) Server...');
7474

75-
$container = new BasicContainer;
75+
$container = new BasicContainer();
7676
$container->set(LoggerInterface::class, $logger);
7777

7878
$taskRepo = new Services\InMemoryTaskRepository($logger);
@@ -89,7 +89,7 @@ public function log($level, \Stringable|string $message, array $context = []): v
8989

9090
$server->discover(__DIR__, ['.']);
9191

92-
$transport = new StdioServerTransport;
92+
$transport = new StdioServerTransport();
9393
$server->listen($transport);
9494

9595
$logger->info('Server listener stopped gracefully.');

examples/07-complex-tool-schema-http/server.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ public function log($level, \Stringable|string $message, array $context = []): v
6868
}
6969

7070
try {
71-
$logger = new StderrLogger;
71+
$logger = new StderrLogger();
7272
$logger->info('Starting MCP Complex Schema HTTP Server...');
7373

74-
$container = new BasicContainer;
74+
$container = new BasicContainer();
7575
$container->set(LoggerInterface::class, $logger);
7676

7777
$server = Server::make()

src/Attributes/Schema.php

Lines changed: 58 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class Schema
1313
{
1414
/** @var Property[] */
1515
protected array $properties = [];
16-
16+
1717
/**
1818
* @param string|null $format String format (email, date-time, uri, etc.)
1919
* @param int|null $minLength Minimum string length
@@ -63,26 +63,52 @@ public function __construct(
6363
public function toArray(): array
6464
{
6565
$schema = [];
66-
66+
6767
// String constraints
68-
if ($this->format !== null) $schema['format'] = $this->format;
69-
if ($this->minLength !== null) $schema['minLength'] = $this->minLength;
70-
if ($this->maxLength !== null) $schema['maxLength'] = $this->maxLength;
71-
if ($this->pattern !== null) $schema['pattern'] = $this->pattern;
72-
68+
if ($this->format !== null) {
69+
$schema['format'] = $this->format;
70+
}
71+
if ($this->minLength !== null) {
72+
$schema['minLength'] = $this->minLength;
73+
}
74+
if ($this->maxLength !== null) {
75+
$schema['maxLength'] = $this->maxLength;
76+
}
77+
if ($this->pattern !== null) {
78+
$schema['pattern'] = $this->pattern;
79+
}
80+
7381
// Numeric constraints
74-
if ($this->minimum !== null) $schema['minimum'] = $this->minimum;
75-
if ($this->maximum !== null) $schema['maximum'] = $this->maximum;
76-
if ($this->exclusiveMinimum !== null) $schema['exclusiveMinimum'] = $this->exclusiveMinimum;
77-
if ($this->exclusiveMaximum !== null) $schema['exclusiveMaximum'] = $this->exclusiveMaximum;
78-
if ($this->multipleOf !== null) $schema['multipleOf'] = $this->multipleOf;
79-
82+
if ($this->minimum !== null) {
83+
$schema['minimum'] = $this->minimum;
84+
}
85+
if ($this->maximum !== null) {
86+
$schema['maximum'] = $this->maximum;
87+
}
88+
if ($this->exclusiveMinimum !== null) {
89+
$schema['exclusiveMinimum'] = $this->exclusiveMinimum;
90+
}
91+
if ($this->exclusiveMaximum !== null) {
92+
$schema['exclusiveMaximum'] = $this->exclusiveMaximum;
93+
}
94+
if ($this->multipleOf !== null) {
95+
$schema['multipleOf'] = $this->multipleOf;
96+
}
97+
8098
// Array constraints
81-
if ($this->items !== null) $schema['items'] = $this->items->toArray();
82-
if ($this->minItems !== null) $schema['minItems'] = $this->minItems;
83-
if ($this->maxItems !== null) $schema['maxItems'] = $this->maxItems;
84-
if ($this->uniqueItems !== null) $schema['uniqueItems'] = $this->uniqueItems;
85-
99+
if ($this->items !== null) {
100+
$schema['items'] = $this->items->toArray();
101+
}
102+
if ($this->minItems !== null) {
103+
$schema['minItems'] = $this->minItems;
104+
}
105+
if ($this->maxItems !== null) {
106+
$schema['maxItems'] = $this->maxItems;
107+
}
108+
if ($this->uniqueItems !== null) {
109+
$schema['uniqueItems'] = $this->uniqueItems;
110+
}
111+
86112
// Object constraints
87113
if (!empty($this->properties)) {
88114
$props = [];
@@ -91,21 +117,27 @@ public function toArray(): array
91117
}
92118
$schema['properties'] = $props;
93119
}
94-
95-
if ($this->required !== null) $schema['required'] = $this->required;
96-
120+
121+
if ($this->required !== null) {
122+
$schema['required'] = $this->required;
123+
}
124+
97125
if ($this->additionalProperties !== null) {
98126
if ($this->additionalProperties instanceof self) {
99127
$schema['additionalProperties'] = $this->additionalProperties->toArray();
100128
} else {
101129
$schema['additionalProperties'] = $this->additionalProperties;
102130
}
103131
}
104-
132+
105133
// General constraints
106-
if ($this->enum !== null) $schema['enum'] = $this->enum;
107-
if ($this->default !== null) $schema['default'] = $this->default;
108-
134+
if ($this->enum !== null) {
135+
$schema['enum'] = $this->enum;
136+
}
137+
if ($this->default !== null) {
138+
$schema['default'] = $this->default;
139+
}
140+
109141
return $schema;
110142
}
111-
}
143+
}

0 commit comments

Comments
 (0)