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
Copy file name to clipboardExpand all lines: README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -330,7 +330,7 @@ services.AddMcpServer()
330
330
- task-backed tool execution through MCP `tools/call` with `task` metadata plus MCP `tasks/list`, `tasks/get`, `tasks/result`, and `tasks/cancel`
331
331
- forwarded `notifications/tasks/status` for exported gateway tasks
332
332
333
-
Exported MCP tool names are canonical lowercase MCP-safe gateway ids. A unique upstream tool such as `notion-fetch` is exported as `notion-fetch`; when multiple sources expose the same normalized tool name, the gateway uses a source-qualified safe id such as `docs_search_repository` or `ops_search_repository`. `McpGatewayToolDescriptor.ToolId`, downstream MCP `Tool.Name`, and downstream `tools/call` names are the same value, and gateway-owned name resolution is case-insensitive so callers can vary casing without creating a different tool identity. Prompt names and exported resource names use the same lowercase MCP-safe source qualification, for example `ops_deployment_review_system_prompt` or `local_release_review_bundle`, while raw upstream `SourceId`, prompt name, tool name, and resource URI remain available as routing metadata and `_meta` values. Exported MCP resource URIs and URI templates are rewritten into gateway-owned opaque URIs so downstream `resources/read` calls route back to the correct upstream source even when multiple servers expose overlapping URI spaces. The same source-aware rewrite is also used for `completion/complete`, forwarded prompt list changes, and forwarded resource update notifications, so downstream clients always talk in terms of gateway-owned prompt names and resource URIs while the gateway proxies the corresponding upstream MCP operations. When an upstream MCP tool already advertises task support, the gateway preserves that contract on the exported tool and proxies the corresponding upstream task flow. Local gateway tools are exported as optional task-capable tools and are executed through the gateway-owned task store.
333
+
Exported MCP tool names are canonical lowercase MCP-safe gateway ids. A unique upstream tool such as `notion-fetch` is exported as `notion-fetch`; when multiple sources expose the same normalized tool name, the gateway uses a source-qualified safe id such as `docs_search_repository` or `ops_search_repository`. Hash suffixes are added only when length or collision handling requires them. Names that would exceed 64 characters keep a readable normalized prefix and receive a deterministic hash suffix instead of being blindly truncated. `McpGatewayToolDescriptor.ToolId`, downstream MCP `Tool.Name`, and downstream `tools/call` names are the same value, and gateway-owned name resolution is case-insensitive so callers can vary casing without creating a different tool identity. Prompt names and exported resource names use the same lowercase MCP-safe source qualification, for example `ops_deployment_review_system_prompt` or `local_release_review_bundle`, while raw upstream `SourceId`, prompt name, tool name, and resource URI remain available as routing metadata and `_meta` values. Exported MCP resource URIs and URI templates are rewritten into gateway-owned opaque URIs so downstream `resources/read` calls route back to the correct upstream source even when multiple servers expose overlapping URI spaces. The same source-aware rewrite is also used for `completion/complete`, forwarded prompt list changes, and forwarded resource update notifications, so downstream clients always talk in terms of gateway-owned prompt names and resource URIs while the gateway proxies the corresponding upstream MCP operations. When an upstream MCP tool already advertises task support, the gateway preserves that contract on the exported tool and proxies the corresponding upstream task flow. Local gateway tools are exported as optional task-capable tools and are executed through the gateway-owned task store.
334
334
335
335
The exported task store uses the official SDK `InMemoryMcpTaskStore` with MCPGateway-owned bounded defaults: task TTL 30 minutes, maximum task TTL 2 hours, cleanup every minute, maximum 10,000 tasks globally, and maximum 1,000 tasks per downstream session. Hosts can override those limits through `McpGatewayOptions.McpTaskStore`, or replace `McpServerOptions.TaskStore` with a durable production store when tasks must survive process restarts:
Copy file name to clipboardExpand all lines: docs/ADR/ADR-0013-mcp-safe-canonical-protocol-names.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,6 +18,8 @@ Gateway-owned protocol names use one canonical lowercase MCP-safe identity.
18
18
- Unique tools use the normalized upstream tool name, for example `notion-fetch`.
19
19
- Colliding normalized tool names receive deterministic source-qualified safe ids, for example `docs_search_repository`.
20
20
- Exact duplicate source/tool pairs receive a deterministic suffix instead of being skipped.
21
+
- Hash suffixes are added only when length or collision handling requires them; normal short names such as `notion-fetch` remain unchanged.
22
+
- Names that exceed the bounded host limit keep a readable normalized prefix and receive a deterministic hash suffix within 64 characters instead of being blindly truncated.
21
23
- Prompt ids and exported resource names are lowercase MCP-safe source-qualified names.
22
24
- Gateway-owned name resolution is case-insensitive for tools, prompts, task support maps, and embedding-store lookups.
23
25
- Raw upstream `SourceId`, tool name, prompt name, resource name, and URI remain separate routing metadata and `_meta` values.
Copy file name to clipboardExpand all lines: docs/Architecture/Overview.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,7 +36,7 @@ Graph-specific search and indexing operations deliberately sit on `IMcpGatewayGr
36
36
37
37
The package also keeps chat-client and agent integration generic: `McpGatewayToolSet` is the source of reusable `AITool` search, route, invoke, graph schema-describe, tool index-build, graph schema-search, graph federated-search, and graph export meta-tools plus discovered proxy tools, `ChatOptions.AddMcpGatewayTools(...)` and `ChatOptions.AddMcpGatewayGraphTools(...)` remain the low-level bridges, and `McpGatewayAutoDiscoveryChatClient` plus `UseMcpGatewayAutoDiscovery(...)` provide the recommended staged host wrapper that starts with the gateway search/route/invoke tools and replaces the discovered proxy set on each new search result without introducing a hard Agent Framework dependency into the core package.
38
38
39
-
For MCP interoperability in the other direction, the package also exposes `WithMcpGatewayCatalog()` as a server-builder extension. Hosts can take one aggregated gateway catalog and re-export it as a downstream MCP server that exposes the combined tools, prompts, and resources from multiple upstream MCP sources plus gateway-owned prompts. That export also proxies MCP completions, forwarded prompt list-change notifications, resource subscriptions, forwarded resource-updated notifications, logging level changes, and task-backed tool execution through the MCP tasks surface. Tool ids, downstream MCP tool names, prompt ids, and exported resource names are normalized to lowercase MCP-safe names; unique tools keep their normalized upstream tool name, collisions get deterministic source-qualified ids, and gateway-owned name resolution is case-insensitive while raw `SourceId` and upstream protocol names stay in routing metadata. Resource URIs are rewritten into gateway-owned source-qualified URIs during export so downstream reads, completions, and forwarded update notifications stay unambiguous even when upstream servers reuse the same URI spaces. Exported task storage uses the official SDK in-memory task store with MCPGateway-owned bounded TTL, cleanup, and task-count limits by default. Gateway-owned per-session prompt notification, resource subscription, and active task binding state is removed both on protocol cleanup paths and, for Streamable HTTP hosting, through the official SDK `HttpServerTransportOptions.RunSessionHandler` lifecycle when the SDK-owned HTTP session ends. By default the export binds to the singleton gateway services in DI, but hosts can override that binding per request or per downstream MCP session through `IMcpGatewayServerBindingResolver`, which allows route-specific or tenant-specific gateway instances without forking the exported MCP handler stack.
39
+
For MCP interoperability in the other direction, the package also exposes `WithMcpGatewayCatalog()` as a server-builder extension. Hosts can take one aggregated gateway catalog and re-export it as a downstream MCP server that exposes the combined tools, prompts, and resources from multiple upstream MCP sources plus gateway-owned prompts. That export also proxies MCP completions, forwarded prompt list-change notifications, resource subscriptions, forwarded resource-updated notifications, logging level changes, and task-backed tool execution through the MCP tasks surface. Tool ids, downstream MCP tool names, prompt ids, and exported resource names are normalized to lowercase MCP-safe names; unique tools keep their normalized upstream tool name, collisions get deterministic source-qualified ids, hash suffixes appear only when length or collision handling requires them, and gateway-owned name resolution is case-insensitive while raw `SourceId` and upstream protocol names stay in routing metadata. Resource URIs are rewritten into gateway-owned source-qualified URIs during export so downstream reads, completions, and forwarded update notifications stay unambiguous even when upstream servers reuse the same URI spaces. Exported task storage uses the official SDK in-memory task store with MCPGateway-owned bounded TTL, cleanup, and task-count limits by default. Gateway-owned per-session prompt notification, resource subscription, and active task binding state is removed both on protocol cleanup paths and, for Streamable HTTP hosting, through the official SDK `HttpServerTransportOptions.RunSessionHandler` lifecycle when the SDK-owned HTTP session ends. By default the export binds to the singleton gateway services in DI, but hosts can override that binding per request or per downstream MCP session through `IMcpGatewayServerBindingResolver`, which allows route-specific or tenant-specific gateway instances without forking the exported MCP handler stack.
40
40
41
41
The repository now uses feature-first package slices for `Gateway`, `Discovery`, `Catalog`, `Search`, `Invocation`, `Prompts`, `Resources`, and `Hosting`. The durable policy decision behind that structure is captured in [`docs/ADR/ADR-0007-vertical-slice-package-organization.md`](../ADR/ADR-0007-vertical-slice-package-organization.md).
Copy file name to clipboardExpand all lines: src/ManagedCode.MCPGateway/AGENTS.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -72,6 +72,7 @@ For this .NET project:
72
72
- Keep `McpGateway` focused on search and invoke orchestration; registry mutation belongs in catalog and registration collaborators.
73
73
- Keep transport-specific logic inside registration and source abstractions, not scattered through runtime code.
74
74
- When production behavior changes here, update the integration-style tests under `tests/ManagedCode.MCPGateway.Tests/` in the same task.
75
+
- Keep package-owned production string values such as source ids, fallback names, protocol metadata keys, tool kinds, and default runtime identifiers behind named constants instead of inline literals, because gateway naming contracts must stay auditable and reusable.
75
76
- Do not hide shared runtime services such as `ILoggerFactory` inside options bags for public factory APIs; when custom gateway instances need host-owned shared dependencies, expose a DI-registered factory service that resolves those dependencies from the container and accepts only gateway-specific configuration at creation time.
76
77
- For public runtime-mutation APIs in this package, use precise lifecycle verbs such as `Reconfigure` or `Reset`; avoid ambiguous or alarming names like `Replace` when the operation only rebuilds in-memory registry configuration.
77
78
- For public factory APIs in this package, prefer explicit overloads over nullable optional delegate parameters; use `Create()` plus `Create(Action<T>)` when both cases are supported.
0 commit comments