1111
1212namespace Mcp \Capability ;
1313
14- use Mcp \Capability \Discovery \DiscoveryState ;
1514use Mcp \Capability \Registry \PromptReference ;
1615use Mcp \Capability \Registry \ResourceReference ;
1716use Mcp \Capability \Registry \ResourceTemplateReference ;
@@ -68,44 +67,22 @@ public function __construct(
6867 ) {
6968 }
7069
71- public function registerTool (Tool $ tool , callable |array |string $ handler, bool $ isManual = false ): void
70+ public function registerTool (Tool $ tool , callable |array |string $ handler ): void
7271 {
73- $ toolName = $ tool ->name ;
74- $ existing = $ this ->tools [$ toolName ] ?? null ;
75-
76- if ($ existing && !$ isManual && $ existing ->isManual ) {
77- $ this ->logger ->debug (
78- \sprintf ('Ignoring discovered tool "%s" as it conflicts with a manually registered one. ' , $ toolName ),
79- );
80-
81- return ;
82- }
83-
84- if (!$ this ->nameValidator ->isValid ($ toolName )) {
72+ if (!$ this ->nameValidator ->isValid ($ tool ->name )) {
8573 $ this ->logger ->warning (
86- \sprintf ('Tool name "%s" is invalid. Tool names should only contain letters (a-z, A-Z), numbers, dots, hyphens, underscores, and forward slashes. ' , $ toolName ),
74+ \sprintf ('Tool name "%s" is invalid. Tool names should only contain letters (a-z, A-Z), numbers, dots, hyphens, underscores, and forward slashes. ' , $ tool -> name ),
8775 );
8876 }
8977
90- $ this ->tools [$ toolName ] = new ToolReference ($ tool , $ handler, $ isManual );
78+ $ this ->tools [$ tool -> name ] = new ToolReference ($ tool , $ handler );
9179
9280 $ this ->eventDispatcher ?->dispatch(new ToolListChangedEvent ());
9381 }
9482
95- public function registerResource (Resource $ resource , callable |array |string $ handler, bool $ isManual = false ): void
83+ public function registerResource (Resource $ resource , callable |array |string $ handler ): void
9684 {
97- $ uri = $ resource ->uri ;
98- $ existing = $ this ->resources [$ uri ] ?? null ;
99-
100- if ($ existing && !$ isManual && $ existing ->isManual ) {
101- $ this ->logger ->debug (
102- \sprintf ('Ignoring discovered resource "%s" as it conflicts with a manually registered one. ' , $ uri ),
103- );
104-
105- return ;
106- }
107-
108- $ this ->resources [$ uri ] = new ResourceReference ($ resource , $ handler , $ isManual );
85+ $ this ->resources [$ resource ->uri ] = new ResourceReference ($ resource , $ handler );
10986
11087 $ this ->eventDispatcher ?->dispatch(new ResourceListChangedEvent ());
11188 }
@@ -114,23 +91,10 @@ public function registerResourceTemplate(
11491 ResourceTemplate $ template ,
11592 callable |array |string $ handler ,
11693 array $ completionProviders = [],
117- bool $ isManual = false ,
11894 ): void {
119- $ uriTemplate = $ template ->uriTemplate ;
120- $ existing = $ this ->resourceTemplates [$ uriTemplate ] ?? null ;
121-
122- if ($ existing && !$ isManual && $ existing ->isManual ) {
123- $ this ->logger ->debug (
124- \sprintf ('Ignoring discovered template "%s" as it conflicts with a manually registered one. ' , $ uriTemplate ),
125- );
126-
127- return ;
128- }
129-
130- $ this ->resourceTemplates [$ uriTemplate ] = new ResourceTemplateReference (
95+ $ this ->resourceTemplates [$ template ->uriTemplate ] = new ResourceTemplateReference (
13196 $ template ,
13297 $ handler ,
133- $ isManual ,
13498 $ completionProviders ,
13599 );
136100
@@ -141,56 +105,54 @@ public function registerPrompt(
141105 Prompt $ prompt ,
142106 callable |array |string $ handler ,
143107 array $ completionProviders = [],
144- bool $ isManual = false ,
145108 ): void {
146- $ promptName = $ prompt ->name ;
147- $ existing = $ this ->prompts [$ promptName ] ?? null ;
109+ $ this ->prompts [$ prompt ->name ] = new PromptReference ($ prompt , $ handler , $ completionProviders );
148110
149- if ($ existing && !$ isManual && $ existing ->isManual ) {
150- $ this ->logger ->debug (
151- \sprintf ('Ignoring discovered prompt "%s" as it conflicts with a manually registered one. ' , $ promptName ),
152- );
111+ $ this ->eventDispatcher ?->dispatch(new PromptListChangedEvent ());
112+ }
153113
114+ public function unregisterTool (string $ name ): void
115+ {
116+ if (!isset ($ this ->tools [$ name ])) {
154117 return ;
155118 }
156119
157- $ this ->prompts [ $ promptName ] = new PromptReference ( $ prompt , $ handler , $ isManual , $ completionProviders );
120+ unset( $ this ->tools [ $ name ] );
158121
159- $ this ->eventDispatcher ?->dispatch(new PromptListChangedEvent ());
122+ $ this ->eventDispatcher ?->dispatch(new ToolListChangedEvent ());
160123 }
161124
162- public function clear ( ): void
125+ public function unregisterResource ( string $ uri ): void
163126 {
164- $ clearCount = 0 ;
165-
166- foreach ($ this ->tools as $ name => $ tool ) {
167- if (!$ tool ->isManual ) {
168- unset($ this ->tools [$ name ]);
169- ++$ clearCount ;
170- }
171- }
172- foreach ($ this ->resources as $ uri => $ resource ) {
173- if (!$ resource ->isManual ) {
174- unset($ this ->resources [$ uri ]);
175- ++$ clearCount ;
176- }
177- }
178- foreach ($ this ->prompts as $ name => $ prompt ) {
179- if (!$ prompt ->isManual ) {
180- unset($ this ->prompts [$ name ]);
181- ++$ clearCount ;
182- }
127+ if (!isset ($ this ->resources [$ uri ])) {
128+ return ;
183129 }
184- foreach ($ this ->resourceTemplates as $ uriTemplate => $ template ) {
185- if (!$ template ->isManual ) {
186- unset($ this ->resourceTemplates [$ uriTemplate ]);
187- ++$ clearCount ;
188- }
130+
131+ unset($ this ->resources [$ uri ]);
132+
133+ $ this ->eventDispatcher ?->dispatch(new ResourceListChangedEvent ());
134+ }
135+
136+ public function unregisterResourceTemplate (string $ uriTemplate ): void
137+ {
138+ if (!isset ($ this ->resourceTemplates [$ uriTemplate ])) {
139+ return ;
189140 }
190141
191- if ($ clearCount > 0 ) {
192- $ this ->logger ->debug (\sprintf ('Removed %d discovered elements from internal registry. ' , $ clearCount ));
142+ unset($ this ->resourceTemplates [$ uriTemplate ]);
143+
144+ $ this ->eventDispatcher ?->dispatch(new ResourceTemplateListChangedEvent ());
145+ }
146+
147+ public function unregisterPrompt (string $ name ): void
148+ {
149+ if (!isset ($ this ->prompts [$ name ])) {
150+ return ;
193151 }
152+
153+ unset($ this ->prompts [$ name ]);
154+
155+ $ this ->eventDispatcher ?->dispatch(new PromptListChangedEvent ());
194156 }
195157
196158 public function hasTools (): bool
@@ -338,59 +300,6 @@ public function getPrompt(string $name): PromptReference
338300 return $ this ->prompts [$ name ] ?? throw new PromptNotFoundException ($ name );
339301 }
340302
341- /**
342- * Get the current discovery state (only discovered elements, not manual ones).
343- */
344- public function getDiscoveryState (): DiscoveryState
345- {
346- return new DiscoveryState (
347- tools: array_filter ($ this ->tools , static fn ($ tool ) => !$ tool ->isManual ),
348- resources: array_filter ($ this ->resources , static fn ($ resource ) => !$ resource ->isManual ),
349- prompts: array_filter ($ this ->prompts , static fn ($ prompt ) => !$ prompt ->isManual ),
350- resourceTemplates: array_filter ($ this ->resourceTemplates , static fn ($ template ) => !$ template ->isManual ),
351- );
352- }
353-
354- /**
355- * Set the discovery state, replacing all discovered elements.
356- * Manual elements are preserved.
357- */
358- public function setDiscoveryState (DiscoveryState $ state ): void
359- {
360- // Clear existing discovered elements
361- $ this ->clear ();
362-
363- // Import new discovered elements
364- foreach ($ state ->getTools () as $ name => $ tool ) {
365- $ this ->tools [$ name ] = $ tool ;
366- }
367-
368- foreach ($ state ->getResources () as $ uri => $ resource ) {
369- $ this ->resources [$ uri ] = $ resource ;
370- }
371-
372- foreach ($ state ->getPrompts () as $ name => $ prompt ) {
373- $ this ->prompts [$ name ] = $ prompt ;
374- }
375-
376- foreach ($ state ->getResourceTemplates () as $ uriTemplate => $ template ) {
377- $ this ->resourceTemplates [$ uriTemplate ] = $ template ;
378- }
379-
380- // Dispatch events for the imported elements
381- if ($ this ->eventDispatcher instanceof EventDispatcherInterface) {
382- if (!empty ($ state ->getTools ())) {
383- $ this ->eventDispatcher ->dispatch (new ToolListChangedEvent ());
384- }
385- if (!empty ($ state ->getResources ()) || !empty ($ state ->getResourceTemplates ())) {
386- $ this ->eventDispatcher ->dispatch (new ResourceListChangedEvent ());
387- }
388- if (!empty ($ state ->getPrompts ())) {
389- $ this ->eventDispatcher ->dispatch (new PromptListChangedEvent ());
390- }
391- }
392- }
393-
394303 /**
395304 * Calculate next cursor for pagination.
396305 *
0 commit comments