You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-`src/ManagedCode.MCPGateway/Abstractions/` contains public interfaces, grouped by concern when needed.
168
-
-`src/ManagedCode.MCPGateway/Configuration/` contains public configuration types and service keys.
169
-
-`src/ManagedCode.MCPGateway/Models/` contains public contracts grouped by behavior such as search, invocation, catalog, and embeddings.
170
-
-`src/ManagedCode.MCPGateway/Embeddings/` contains public embedding-store implementations.
171
-
-`src/ManagedCode.MCPGateway/Internal/` contains internal catalog, runtime, and helper implementation details.
172
-
-`src/ManagedCode.MCPGateway/Registration/` contains DI registration extensions.
173
-
-`src/ManagedCode.MCPGateway/McpGateway.cs` is the public gateway facade.
174
-
-`src/ManagedCode.MCPGateway/Internal/Runtime/` contains the internal runtime orchestration implementation, grouped by core, catalog, search, invocation, and embeddings responsibilities.
175
-
-`src/ManagedCode.MCPGateway/McpGatewayToolSet.cs` exposes the gateway as reusable `AITool` meta-tools.
167
+
-`src/ManagedCode.MCPGateway/Gateway/` contains the public gateway facade, factory, options, DI entry points, runtime core, telemetry, and serialization.
-`src/ManagedCode.MCPGateway/Invocation/` contains invocation models and runtime execution helpers.
172
+
-`src/ManagedCode.MCPGateway/Prompts/` contains prompt contracts, models, and prompt catalog implementation.
173
+
-`src/ManagedCode.MCPGateway/Hosting/` contains MCP server export and warmup integration.
176
174
-`.codex/skills/` contains repo-local MCAF skills for Codex.
177
175
- Keep the source tree explicitly modular: separate public API folders from `Internal/` implementation folders, and group runtime classes by responsibility in dedicated folders instead of dumping search, indexing, invocation, registry, and infrastructure files into the package root, because flat structure hides boundaries and invites god-object design.
176
+
- Prefer vertical-slice package structure for non-trivial areas: group code by feature and subfeature with isolated supporting types nearby instead of accumulating broad cross-cutting buckets that mix unrelated behaviors in one folder, because feature-local structure keeps boundaries auditable.
178
177
179
178
### Skills (ALL TASKS)
180
179
@@ -211,14 +210,16 @@ If no new rule is detected -> do not update the file.
211
210
- Test framework in this repository is TUnit. Never add or keep xUnit here.
212
211
- This repository uses `TUnit` on `Microsoft.Testing.Platform`; never use VSTest-only flags such as `--filter` or `--logger`, because they are not supported here.
213
212
- For TUnit solution runs, always invoke `dotnet test --solution ...`; do not pass the solution path positionally.
214
-
- Coverage in this repository uses the local `coverlet.console` tool against the built test assembly, then renders human-readable output with the local `reportgenerator` tool.
213
+
- Coverage in this repository uses the local `coverlet.console` tool against the built test assembly and must target the built `ManagedCode.MCPGateway.Tests` TUnit application directly; routing coverage through `dotnet test --solution ...` under `Microsoft.Testing.Platform` reports zero hits in this repo.
215
214
- Every behavior change must include or update tests in `tests/ManagedCode.MCPGateway.Tests/`.
216
215
- Add tests only when they close a meaningful behavior or regression gap; avoid low-signal tests that only increase count without improving confidence.
217
216
- Keep tests focused on real gateway behavior:
218
217
- local tool indexing and invocation
219
218
- MCP tool indexing and invocation
220
219
- vector search behavior
221
220
- Markdown-LD graph search and vector-to-graph fallback behavior
221
+
- For MCP protocol coverage, prefer end-to-end integration tests that use the official `ModelContextProtocol` C# SDK on both client and server paths instead of test doubles when the behavior depends on real protocol contracts, because MCP regressions often hide outside mocked flows.
222
+
- When changing MCP discovery, routing, search, or invocation behavior, add multi-step integration cases with realistic tool metadata, side-effect boundaries, and client-driven execution so retrieval and invocation are verified under production-like conditions.
222
223
- Keep embedding-based search covered with deterministic local tests by using a fake or test-only embedding generator.
223
224
- Keep request context behavior covered when search or invocation consumes contextual inputs.
224
225
- Do not remove tests to get green builds.
@@ -307,6 +308,7 @@ If no new rule is detected -> do not update the file.
307
308
### Likes
308
309
309
310
- Explicit package structure
311
+
- Vertical-slice structure with feature and subfeature isolation
310
312
- Reusable library design over app-specific glue
311
313
- Search + execute flows covered by automated tests
-`IMcpGatewayRegistry`: additive tool and source registration
249
254
-`IMcpGatewayCatalogRuntime`: full in-memory catalog clear or reconfiguration
250
255
-`IMcpGatewayPromptCatalog`: list and render aggregated MCP prompts
@@ -315,7 +320,7 @@ var invoke = await gateway.InvokeAsync(new McpGatewayInvokeRequest(
315
320
316
321
## Search Hints
317
322
318
-
If a tool should be easier to find through multilingual aliases or stable domain keywords, register explicit search hints:
323
+
If a tool should be easier to find through multilingual aliases, stable domain keywords, category-first routing, or execution-aware discovery, register explicit search hints:
"Check whether the user has pending notifications."),
358
+
newMcpGatewayToolExample(
359
+
"summarize mentions from the last release thread",
360
+
"{\"mentions\":[\"alice\",\"bob\"]}",
361
+
"Triage release-thread mentions before replying."),
362
+
newMcpGatewayToolExample(
363
+
"list urgent notifications for the mobile workspace",
364
+
"{\"alerts\":[{\"severity\":\"high\"}]}",
365
+
"Filter alerts for a specific workspace and urgency level.")
366
+
],
367
+
ReadOnly: true,
368
+
Idempotent: true,
369
+
CostTier: McpGatewayToolCostTier.Low,
370
+
LatencyTier: McpGatewayToolLatencyTier.Low));
344
371
});
345
372
```
346
373
347
-
Hints are included in descriptors, Markdown-LD graph documents, vector documents, and lexical boosts. They are the preferred way to improve multilingual discovery without hardcoded ranking exceptions.
374
+
Hints are included in descriptors, Markdown-LD graph documents, vector documents, exported MCP metadata, and lexical boosts. They are the preferred way to improve multilingual discovery and category-aware routing without hardcoded ranking exceptions.
375
+
376
+
If a tool should stay out of default discovery until a host explicitly opts into it, set `EnabledByDefault: false`. Standard `SearchAsync(...)` and `RouteToolsAsync(...)` hide those tools unless the request sets `IncludeDisabledTools = true`.
Query: "open a bridge and prepare a failover plan for incident 42",
564
+
MaxCategories: 2,
565
+
MaxToolsPerCategory: 2,
566
+
ContextSummary: "incident already confirmed; the next step is an action tool",
567
+
PreferReadOnly: false,
568
+
IncludeDisabledTools: true));
569
+
```
570
+
571
+
`McpGatewayToolRouteResult` returns:
572
+
573
+
-`Categories` with grouped tool candidates
574
+
-`SuggestedMatches` with the flattened recommended tools
575
+
-`Diagnostics` from the underlying search path
576
+
-`RankingMode` from the underlying graph/vector/hybrid search
577
+
578
+
The router prefers safe read-only tools for discovery/inspection-style requests and uses cost and latency tiers as tie-breakers when tool quality is otherwise similar.
529
579
530
-
The gateway can expose itself as two reusable tools:
580
+
The gateway can expose itself as three reusable tools:
531
581
532
582
-`gateway_tools_search`
583
+
-`gateway_tools_route`
533
584
-`gateway_tool_invoke`
534
585
535
586
From the gateway:
@@ -575,7 +626,7 @@ var response = await chatClient.GetResponseAsync(
575
626
});
576
627
```
577
628
578
-
This flow starts with the two gateway meta-tools and only projects the latest matching tools as direct proxy tools after search.
629
+
This flow starts with the three gateway meta-tools and only projects the latest matching tools as direct proxy tools after search.
579
630
580
631
If the host already has search results and only wants the discovered proxy tools:
Copy file name to clipboardExpand all lines: docs/ADR/ADR-0003-reusable-chat-client-and-agent-tool-modules.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
## Context
4
4
5
-
`ManagedCode.MCPGateway` already exposes the gateway as two reusable meta-tools through `McpGatewayToolSet` and `IMcpGateway.CreateMetaTools(...)`.
5
+
`ManagedCode.MCPGateway` already exposes the gateway as reusable meta-tools through `McpGatewayToolSet` and `IMcpGateway.CreateMetaTools(...)`.
6
6
7
7
The package now also needs to prove that these tools integrate cleanly with two host-side consumption patterns:
8
8
@@ -14,7 +14,7 @@ The user explicitly asked for:
14
14
- very lightweight host integration
15
15
- deterministic scenario-driven tests
16
16
- coverage both without embeddings and with embeddings
17
-
- a staged auto-discovery flow where the model starts with only two gateway tools, then receives only the currently needed direct tools, and then sees those discovered tools replaced when a new search result arrives
17
+
- a staged auto-discovery flow where the model starts with the gateway search, route, and invoke tools, then receives only the currently needed direct tools, and then sees those discovered tools replaced when a new search result arrives
18
18
19
19
At the same time, the repository still wants to keep the core package generic, library-first, and free from unnecessary host-framework dependencies.
20
20
@@ -30,8 +30,8 @@ At the same time, the repository still wants to keep the core package generic, l
30
30
31
31
The recommended host flow is:
32
32
33
-
1. expose only `gateway_tools_search` and `gateway_tool_invoke`
34
-
2. let the model search the gateway
33
+
1. expose only `gateway_tools_search`, `gateway_tools_route`, and `gateway_tool_invoke`
34
+
2. let the model search or route the gateway first
35
35
3. project only the latest search matches as direct proxy tools
36
36
4. replace that discovered proxy set when a new search result arrives
37
37
@@ -42,7 +42,7 @@ The core package will not take a hard runtime dependency on Microsoft Agent Fram
-`McpGatewayToolSet.CreateTools(...)` MUST remain the canonical source of gateway meta-tools.
118
118
-`McpGatewayToolSet.AddTools(...)` MUST preserve existing tool entries and MUST avoid duplicate names.
119
119
-`ChatOptions.AddMcpGatewayTools(...)` MUST preserve existing `ChatOptions.Tools` entries and MUST avoid duplicate names.
120
-
-`McpGatewayAutoDiscoveryChatClient` MUST start each host loop with only the two gateway meta-tools visible unless the host already supplied other non-gateway tools.
120
+
-`McpGatewayAutoDiscoveryChatClient` MUST start each host loop with only the gateway search, route, and invoke meta-tools visible unless the host already supplied other non-gateway tools.
121
121
-`McpGatewayAutoDiscoveryChatClient` MUST replace the discovered proxy-tool set when a newer gateway search result is present instead of accumulating old discovered tools forever.
122
122
- The core package MUST stay generic around `AITool` composition and MUST NOT require Microsoft Agent Framework for normal package use.
123
123
- Chat-client and agent integration tests MUST prove the staged auto-discovery lifecycle against a realistic multi-tool catalog in both default graph mode and opt-in vector mode.
0 commit comments