exceptionfactory commented on code in PR #11863:
URL: https://github.com/apache/nifi/pull/11863#discussion_r4402413635


##########
nifi-extension-bundles/nifi-mcp-bundle/nifi-mcp-processors/src/main/java/org/apache/nifi/mcp/client/StandardMcpClientService.java:
##########
@@ -0,0 +1,521 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.mcp.client;
+
+import io.modelcontextprotocol.client.McpClient;
+import io.modelcontextprotocol.client.McpSyncClient;
+import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport;
+import 
io.modelcontextprotocol.client.transport.HttpClientStreamableHttpTransport;
+import 
io.modelcontextprotocol.client.transport.customizer.McpSyncHttpClientRequestCustomizer;
+import io.modelcontextprotocol.json.McpJsonMapper;
+import io.modelcontextprotocol.json.TypeRef;
+import io.modelcontextprotocol.json.jackson3.JacksonMcpJsonMapper;
+import io.modelcontextprotocol.spec.McpClientTransport;
+import io.modelcontextprotocol.spec.McpError;
+import io.modelcontextprotocol.spec.McpSchema;
+import io.modelcontextprotocol.spec.McpSchema.CallToolRequest;
+import io.modelcontextprotocol.spec.McpSchema.CallToolResult;
+import io.modelcontextprotocol.spec.McpSchema.GetPromptRequest;
+import io.modelcontextprotocol.spec.McpSchema.GetPromptResult;
+import io.modelcontextprotocol.spec.McpSchema.ListPromptsResult;
+import io.modelcontextprotocol.spec.McpSchema.ListResourcesResult;
+import io.modelcontextprotocol.spec.McpSchema.ListToolsResult;
+import io.modelcontextprotocol.spec.McpSchema.ReadResourceRequest;
+import io.modelcontextprotocol.spec.McpSchema.ReadResourceResult;
+import org.apache.nifi.annotation.behavior.SupportsSensitiveDynamicProperties;
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.annotation.lifecycle.OnDisabled;
+import org.apache.nifi.annotation.lifecycle.OnEnabled;
+import org.apache.nifi.components.ConfigVerificationResult;
+import org.apache.nifi.components.ConfigVerificationResult.Outcome;
+import org.apache.nifi.components.DescribedValue;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.controller.AbstractControllerService;
+import org.apache.nifi.controller.ConfigurationContext;
+import org.apache.nifi.controller.VerifiableControllerService;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.logging.ComponentLog;
+import org.apache.nifi.mcp.McpCallResult;
+import org.apache.nifi.mcp.McpClientException;
+import org.apache.nifi.mcp.McpClientService;
+import org.apache.nifi.processor.util.StandardValidators;
+import org.apache.nifi.ssl.SSLContextProvider;
+
+import java.net.URI;
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import javax.net.ssl.SSLContext;
+
+/**
+ * Holds one MCP client session towards a remote MCP server and shares it 
across every
+ * processor referencing this service.
+ *
+ * <p>The session is opened eagerly in {@code onEnabled} but failures there 
are only logged: a
+ * remote server that is briefly down must not leave the service stuck in 
ENABLING and every
+ * referencing processor invalid. Instead each call goes through {@link 
#client()}, which
+ * (re)connects lazily. Any failure that is not a JSON-RPC error answered by 
the server
+ * ({@link McpError}) drops the session, so a restarted server - which no 
longer knows our
+ * {@code Mcp-Session-Id} - is picked up on the next call rather than failing 
forever. Calls are
+ * never retried automatically: a {@code tools/call} is not guaranteed 
idempotent, so whether to
+ * retry is a flow decision (the processor's {@code failure} relationship), 
not this service's.
+ */
+@Tags({"mcp", "model context protocol", "ai", "agent", "client"})
+@CapabilityDescription("Maintains an MCP (Model Context Protocol) client 
session towards a remote MCP server "
+        + "over Streamable HTTP or legacy HTTP+SSE, and shares it with 
processors such as InvokeMcpServer. "
+        + "Dynamic properties are sent as HTTP headers on every request.")
+@SupportsSensitiveDynamicProperties
+public class StandardMcpClientService extends AbstractControllerService
+        implements McpClientService, VerifiableControllerService {
+
+    public enum Transport implements DescribedValue {
+        STREAMABLE_HTTP("Streamable HTTP", "Current MCP HTTP transport (spec 
2025-03-26 and later): one endpoint, "
+                + "e.g. https://host:8080/mcp";),
+        SSE("HTTP+SSE (legacy)", "Deprecated MCP 2024-11-05 transport: Server 
URL is the SSE endpoint, "
+                + "e.g. http://host:8080/sse";);

Review Comment:
   As this format is already deprecated, I don't think it should be supported



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to