PageSourceSearch

https://java2ai.com/assets/js/8f9ac5ce.813d0246.js

js java2ai.com collected 2026-10-03 21:35:40 UTC 26,772 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkspring_ai_alibaba_website=self.webpackChunkspring_ai_alibaba_website||[]).push([[5095],{28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>o});var t=s(96540);const r={},i=t.createContext(r);function a(e){const n=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(i.Provider,{value:n},e.children)}},72860:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>p,frontMatter:()=>a,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"mcps/annotations/mcp-annotations-special-params","title":"MCP Annotations Special Parameters","description":"MCP Annotations \u652f\u6301\u51e0\u79cd\u7279\u6b8a\u53c2\u6570\u7c7b\u578b\uff0c\u4e3a\u5e26\u6ce8\u89e3\u7684\u65b9\u6cd5\u63d0\u4f9b\u989d\u5916\u7684\u4e0a\u4e0b\u6587\u548c\u529f\u80fd\u3002","source":"@site/integration/mcps/annotations/mcp-annotations-special-params.md","sourceDirName":"mcps/annotations","slug":"/mcps/annotations/mcp-annotations-special-params","permalink":"/integration/mcps/annotations/mcp-annotations-special-params","draft":false,"unlisted":false,"editUrl":"https://github.com/spring-ai-alibaba/website/tree/main/integration/mcps/annotations/mcp-annotations-special-params.md","tags":[],"version":"current","lastUpdatedBy":"Ken Liu","lastUpdatedAt":1765761850000,"frontMatter":{},"sidebar":"integrationSidebar","previous":{"title":"MCP Client Annotations","permalink":"/integration/mcps/annotations/mcp-annotations-client"},"next":{"title":"MCP Annotations Examples","permalink":"/integration/mcps/annotations/mcp-annotations-examples"}}');var r=s(74848),i=s(28453);const a={},o="MCP Annotations Special Parameters",l={},c=[{value:"Special Parameter Types",id:"special-parameter-types",level:2},{value:"McpMeta",id:"mcpmeta",level:3},{value:"Overview",id:"overview",level:4},{value:"Usage in Tools",id:"usage-in-tools",level:4},{value:"Usage in Resources",id:"usage-in-resources",level:4},{value:"Usage in Prompts",id:"usage-in-prompts",level:4},{value:"@McpProgressToken",id:"mcpprogresstoken",level:3},{value:"Overview",id:"overview-1",level:4},{value:"Usage in Tools",id:"usage-in-tools-1",level:4},{value:"Usage in Resources",id:"usage-in-resources-1",level:4},{value:"McpSyncRequestContext / McpAsyncRequestContext",id:"mcpsyncrequestcontext--mcpasyncrequestcontext",level:3},{value:"Overview",id:"overview-2",level:4},{value:"McpSyncRequestContext Features",id:"mcpsyncrequestcontext-features",level:4},{value:"McpAsyncRequestContext Features",id:"mcpasyncrequestcontext-features",level:4},{value:"McpTransportContext",id:"mcptransportcontext",level:3},{value:"Overview",id:"overview-3",level:4},{value:"Usage Example",id:"usage-example",level:4},{value:"CallToolRequest",id:"calltoolrequest",level:3},{value:"Overview",id:"overview-4",level:4},{value:"Usage Examples",id:"usage-examples",level:4},{value:"Mixed Parameters",id:"mixed-parameters",level:4},{value:"With Progress Token",id:"with-progress-token",level:4},{value:"Parameter Injection Rules",id:"parameter-injection-rules",level:2},{value:"Automatic Injection",id:"automatic-injection",level:3},{value:"Schema Generation",id:"schema-generation",level:3},{value:"Null Handling",id:"null-handling",level:3},{value:"Best Practices",id:"best-practices",level:2},{value:"Use McpMeta for Context",id:"use-mcpmeta-for-context",level:3},{value:"Progress Token Null Checks",id:"progress-token-null-checks",level:3},{value:"Choose the Right Context",id:"choose-the-right-context",level:3},{value:"Capability Checking",id:"capability-checking",level:3}];function d(e){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"mcp-annotations-special-parameters",children:"MCP Annotations Special Parameters"})}),"\n",(0,r.jsx)(n.p,{children:"MCP Annotations \u652f\u6301\u51e0\u79cd\u7279\u6b8a\u53c2\u6570\u7c7b\u578b\uff0c\u4e3a\u5e26\u6ce8\u89e3\u7684\u65b9\u6cd5\u63d0\u4f9b\u989d\u5916\u7684\u4e0a\u4e0b\u6587\u548c\u529f\u80fd\u3002\n\u8fd9\u4e9b\u53c2\u6570\u7531\u6846\u67b6\u81ea\u52a8\u6ce8\u5165\uff0c\u5e76\u4ece JSON schema \u751f\u6210\u4e2d\u6392\u9664\u3002"}),"\n",(0,r.jsx)(n.h2,{id:"special-parameter-types",children:"Special Parameter Types"}),"\n",(0,r.jsx)(n.h3,{id:"mcpmeta",children:"McpMeta"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"McpMeta"})," \u7c7b\u63d0\u4f9b\u5bf9\u6765\u81ea MCP \u8bf7\u6c42\u3001\u901a\u77e5\u548c\u7ed3\u679c\u7684\u5143\u6570\u636e\u7684\u8bbf\u95ee\u3002"]}),"\n",(0,r.jsx)(n.h4,{id:"overview",children:"Overview"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\u7528\u4f5c\u65b9\u6cd5\u53c2\u6570\u65f6\u81ea\u52a8\u6ce8\u5165"}),"\n",(0,r.jsx)(n.li,{children:"\u4ece\u53c2\u6570\u8ba1\u6570\u9650\u5236\u548c JSON sc
1hema \u751f\u6210\u4e2d\u6392\u9664"}),"\n",(0,r.jsxs)(n.li,{children:["\u901a\u8fc7 ",(0,r.jsx)(n.code,{children:"get(String key)"})," \u65b9\u6cd5\u63d0\u4f9b\u4fbf\u6377\u7684\u5143\u6570\u636e\u8bbf\u95ee"]}),"\n",(0,r.jsxs)(n.li,{children:["\u5982\u679c\u8bf7\u6c42\u4e2d\u6ca1\u6709\u5143\u6570\u636e\uff0c\u5219\u6ce8\u5165\u7a7a\u7684 ",(0,r.jsx)(n.code,{children:"McpMeta"})," \u5bf9\u8c61"]}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"usage-in-tools",children:"Usage in Tools"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'@McpTool(name = "contextual-tool", description = "Tool with metadata access")\npublic String processWithContext(\n        @McpToolParam(description = "Input data", required = true) String data,\n        McpMeta meta) {\n    \n    // Access metadata from the request\n    String userId = (String) meta.get("userId");\n    String sessionId = (String) meta.get("sessionId");\n    String userRole = (String) meta.get("userRole");\n    \n    // Use metadata to customize behavior\n    if ("admin".equals(userRole)) {\n        return processAsAdmin(data, userId);\n    } else {\n        return processAsUser(data, userId);\n    }\n}\n'})}),"\n",(0,r.jsx)(n.h4,{id:"usage-in-resources",children:"Usage in Resources"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'@McpResource(uri = "secure-data://{id}", name = "Secure Data")\npublic ReadResourceResult getSecureData(String id, McpMeta meta) {\n    \n    String requestingUser = (String) meta.get("requestingUser");\n    String accessLevel = (String) meta.get("accessLevel");\n    \n    // Check access permissions using metadata\n    if (!"admin".equals(accessLevel)) {\n        return new ReadResourceResult(List.of(\n            new TextResourceContents("secure-data://" + id, \n                "text/plain", "Access denied")\n        ));\n    }\n    \n    String data = loadSecureData(id);\n    return new ReadResourceResult(List.of(\n        new TextResourceContents("secure-data://" + id, \n            "text/plain", data)\n    ));\n}\n'})}),"\n",(0,r.jsx)(n.h4,{id:"usage-in-prompts",children:"Usage in Prompts"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'@McpPrompt(name = "localized-prompt", description = "Localized prompt generation")\npublic GetPromptResult localizedPrompt(\n        @McpArg(name = "topic", required = true) String topic,\n        McpMeta meta) {\n    \n    String language = (String) meta.get("language");\n    String region = (String) meta.get("region");\n    \n    // Generate localized content based on metadata\n    String message = generateLocalizedMessage(topic, language, region);\n    \n    return new GetPromptResult("Localized Prompt",\n        List.of(new PromptMessage(Role.ASSISTANT, new TextContent(message)))\n    );\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"mcpprogresstoken",children:"@McpProgressToken"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"@McpProgressToken"})," \u6ce8\u89e3\u6807\u8bb0\u4e00\u4e2a\u53c2\u6570\u4ee5\u63a5\u6536\u6765\u81ea MCP \u8bf7\u6c42\u7684\u8fdb\u5ea6\u4ee4\u724c\u3002"]}),"\n",(0,r.jsx)(n.h4,{id:"overview-1",children:"Overview"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\u53c2\u6570\u7c7b\u578b\u5e94\u4e3a ",(0,r.jsx)(n.code,{children:"String"})]}),"\n",(0,r.jsx)(n.li,{children:"\u81ea\u52a8\u4ece\u8bf7\u6c42\u63a5\u6536\u8fdb\u5ea6\u4ee4\u724c\u503c"}),"\n",(0,r.jsx)(n.li,{children:"\u4ece\u751f\u6210\u7684 JSON schema \u4e2d\u6392\u9664"}),"\n",(0,r.jsxs)(n.li,{children:["\u5982\u679c\u6ca1\u6709\u8fdb\u5ea6\u4ee4\u724c\uff0c\u5219\u6ce8\u5165 ",(0,r.jsx)(n.code,{children:"null"})]}),"\n",(0,r.jsx)(n.li,{children:"\u7528\u4e8e\u8ddf\u8e2a\u957f\u65f6\u95f4\u8fd0\u884c\u7684\u64cd\u4f5c"}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"usage-in-tools-1",children:"Usage in Tools"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'@McpTool(name = "long-operation", description = "Long-running operation with progress")\npublic String performLongOperation(\n        @McpProgressToken String progressToken,\n        @McpToolParam(description = "Operation name", required = true) String operation,\n        @McpToolParam(description = "Duration in seconds", required = true) int duration,\n        McpSyncServerExchange exchange) {\n    \n    if (progressToken != null) {\n        // Send initial progress\n        exchange.progressNotification(new ProgressNotification(\n            progressToken, 0.0, 1.0, "Starting " + operation));\n        \n        // Simulate work with progress updates\n        for (int i = 1; i <= duration;
1 i++) {\n            Thread.sleep(1000);\n            double progress = (double) i / duration;\n            \n            exchange.progressNotification(new ProgressNotification(\n                progressToken, progress, 1.0, \n                String.format("Processing... %d%%", (int)(progress * 100))));\n        }\n    }\n    \n    return "Operation " + operation + " completed";\n}\n'})}),"\n",(0,r.jsx)(n.h4,{id:"usage-in-resources-1",children:"Usage in Resources"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'@McpResource(uri = "large-file://{path}", name = "Large File Resource")\npublic ReadResourceResult getLargeFile(\n        @McpProgressToken String progressToken,\n        String path,\n        McpSyncServerExchange exchange) {\n    \n    File file = new File(path);\n    long fileSize = file.length();\n    \n    if (progressToken != null) {\n        // Track file reading progress\n        exchange.progressNotification(new ProgressNotification(\n            progressToken, 0.0, fileSize, "Reading file"));\n    }\n    \n    String content = readFileWithProgress(file, progressToken, exchange);\n    \n    if (progressToken != null) {\n        exchange.progressNotification(new ProgressNotification(\n            progressToken, fileSize, fileSize, "File read complete"));\n    }\n    \n    return new ReadResourceResult(List.of(\n        new TextResourceContents("large-file://" + path, "text/plain", content)\n    ));\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"mcpsyncrequestcontext--mcpasyncrequestcontext",children:"McpSyncRequestContext / McpAsyncRequestContext"}),"\n",(0,r.jsx)(n.p,{children:"\u8bf7\u6c42\u4e0a\u4e0b\u6587\u5bf9\u8c61\u63d0\u4f9b\u5bf9 MCP \u8bf7\u6c42\u4fe1\u606f\u548c\u670d\u52a1\u5668\u7aef\u64cd\u4f5c\u7684\u7edf\u4e00\u8bbf\u95ee\u3002"}),"\n",(0,r.jsx)(n.h4,{id:"overview-2",children:"Overview"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\u4e3a\u6709\u72b6\u6001\u548c\u65e0\u72b6\u6001\u64cd\u4f5c\u63d0\u4f9b\u7edf\u4e00\u63a5\u53e3"}),"\n",(0,r.jsx)(n.li,{children:"\u7528\u4f5c\u53c2\u6570\u65f6\u81ea\u52a8\u6ce8\u5165"}),"\n",(0,r.jsx)(n.li,{children:"\u4ece JSON schema \u751f\u6210\u4e2d\u6392\u9664"}),"\n",(0,r.jsx)(n.li,{children:"\u652f\u6301\u65e5\u5fd7\u8bb0\u5f55\u3001\u8fdb\u5ea6\u901a\u77e5\u3001sampling \u548c elicitation \u7b49\u9ad8\u7ea7\u529f\u80fd"}),"\n",(0,r.jsx)(n.li,{children:"\u9002\u7528\u4e8e\u6709\u72b6\u6001\uff08\u670d\u52a1\u5668\u4ea4\u6362\uff09\u548c\u65e0\u72b6\u6001\uff08\u4f20\u8f93\u4e0a\u4e0b\u6587\uff09\u6a21\u5f0f"}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"mcpsyncrequestcontext-features",children:"McpSyncRequestContext Features"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public record UserInfo(String name, String email, int age) {}\n\n@McpTool(name = "advanced-tool", description = "Tool with full server capabilities")\npublic String advancedTool(\n        McpSyncRequestContext context,\n        @McpToolParam(description = "Input", required = true) String input) {\n    \n    // Send logging notification\n    context.info("Processing: " + input);\n    \n    // Ping the client\n    context.ping();\n    \n    // Send progress updates\n    context.progress(50); // 50% complete\n    \n    // Check if elicitation is supported before using it\n    if (context.elicitEnabled()) {\n        // Request additional information from user\n        StructuredElicitResult<UserInfo> elicitResult = context.elicit(\n            e -> e.message("Need additional information"),\n            UserInfo.class\n        );\n        \n        if (elicitResult.action() == ElicitResult.Action.ACCEPT) {\n            UserInfo userInfo = elicitResult.structuredContent();\n            // Use the user information\n        }\n    }\n    \n    // Check if sampling is supported before using it\n    if (context.sampleEnabled()) {\n        // Request LLM sampling\n        CreateMessageResult samplingResult = context.sample(\n            s -> s.message("Process: " + input)\n                .modelPreferences(pref -> pref.modelHints("gpt-4"))\n        );\n    }\n    \n    return "Processed with advanced features";\n}\n'})}),"\n",(0,r.jsx)(n.h4,{id:"mcpasyncrequestcontext-features",children:"McpAsyncRequestContext Features"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public re
1cord UserInfo(String name, String email, int age) {}\n\n@McpTool(name = "async-advanced-tool", description = "Async tool with server capabilities")\npublic Mono<String> asyncAdvancedTool(\n        McpAsyncRequestContext context,\n        @McpToolParam(description = "Input", required = true) String input) {\n    \n    return context.info("Async processing: " + input)\n        .then(context.progress(25))\n        .then(context.ping())\n        .flatMap(v -> {\n            // Perform elicitation if supported\n            if (context.elicitEnabled()) {\n                return context.elicitation(UserInfo.class)\n                    .map(userInfo -> "Processing for user: " + userInfo.name());\n            }\n            return Mono.just("Processing...");\n        })\n        .flatMap(msg -> {\n            // Perform sampling if supported\n            if (context.sampleEnabled()) {\n                return context.sampling("Process: " + input)\n                    .map(result -> "Completed: " + result);\n            }\n            return Mono.just("Completed: " + msg);\n        });\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"mcptransportcontext",children:"McpTransportContext"}),"\n",(0,r.jsx)(n.p,{children:"\u7528\u4e8e\u65e0\u72b6\u6001\u64cd\u4f5c\u7684\u8f7b\u91cf\u7ea7\u4e0a\u4e0b\u6587\u3002"}),"\n",(0,r.jsx)(n.h4,{id:"overview-3",children:"Overview"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\u63d0\u4f9b\u6700\u5c0f\u4e0a\u4e0b\u6587\uff0c\u65e0\u9700\u5b8c\u6574\u7684\u670d\u52a1\u5668\u4ea4\u6362"}),"\n",(0,r.jsx)(n.li,{children:"\u7528\u4e8e\u65e0\u72b6\u6001\u5b9e\u73b0"}),"\n",(0,r.jsx)(n.li,{children:"\u7528\u4f5c\u53c2\u6570\u65f6\u81ea\u52a8\u6ce8\u5165"}),"\n",(0,r.jsx)(n.li,{children:"\u4ece JSON schema \u751f\u6210\u4e2d\u6392\u9664"}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"usage-example",children:"Usage Example"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'@McpTool(name = "stateless-tool", description = "Stateless tool with context")\npublic String statelessTool(\n        McpTransportContext context,\n        @McpToolParam(description = "Input", required = true) String input) {\n    \n    // Limited context access\n    // Useful for transport-level operations\n    \n    return "Processed in stateless mode: " + input;\n}\n\n@McpResource(uri = "stateless://{id}", name = "Stateless Resource")\npublic ReadResourceResult statelessResource(\n        McpTransportContext context,\n        String id) {\n    \n    // Access transport context if needed\n    String data = loadData(id);\n    \n    return new ReadResourceResult(List.of(\n        new TextResourceContents("stateless://" + id, "text/plain", data)\n    ));\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"calltoolrequest",children:"CallToolRequest"}),"\n",(0,r.jsx)(n.p,{children:"\u9700\u8981\u8bbf\u95ee\u5b8c\u6574\u8bf7\u6c42\u548c\u52a8\u6001 schema \u7684\u5de5\u5177\u7684\u7279\u6b8a\u53c2\u6570\u3002"}),"\n",(0,r.jsx)(n.h4,{id:"overview-4",children:"Overview"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\u63d0\u4f9b\u5bf9\u5b8c\u6574\u5de5\u5177\u8bf7\u6c42\u7684\u8bbf\u95ee"}),"\n",(0,r.jsx)(n.li,{children:"\u652f\u6301\u8fd0\u884c\u65f6\u52a8\u6001 schema \u5904\u7406"}),"\n",(0,r.jsx)(n.li,{children:"\u81ea\u52a8\u6ce8\u5165\u5e76\u4ece schema \u751f\u6210\u4e2d\u6392\u9664"}),"\n",(0,r.jsx)(n.li,{children:"\u9002\u7528\u4e8e\u9002\u5e94\u4e0d\u540c\u8f93\u5165 schema \u7684\u7075\u6d3b\u5de5\u5177"}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'@McpTool(name = "dynamic-tool", description = "Tool with dynamic schema support")\npublic CallToolResult processDynamicSchema(CallToolRequest request) {\n    Map<String, Object> args = request.arguments();\n    \n    // Process based on whatever schema was provided at runtime\n    StringBuilder result = new StringBuilder("Processed:\\n");\n    \n    for (Map.Entry<String, Object> entry : args.entrySet()) {\n        result.append("  ").append(entry.getKey())\n              .append(": ").append(entry.getValue()).append("\\n");\n    }\n    \n    return CallToolResult.builder()\n        .addTextContent(result.toString())\n        .build();\n}\n'})}),"\n",(0,r.jsx)(n.h4,{id:"mixed-parameters",children:"Mixed Parameters"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'@McpTool(name = "hybrid-tool", description = "Tool with typed and dynamic parameters")\npublic String processHybrid(\n        @McpToolParam(description = "Operation", required = true) String operation,\n        @McpToolParam(description = "Priority", required = false) Integer priority,\n        CallToolRequest request) {\n    \n    // Use typed parameters for known fields\n    String result = "Operation: " + operation;\n    if (priority != null) {\n        result += " (Priority: " + priority + ")";\n    }\n    \n    // Access additional dynamic arguments\n    Map<String, Object> allArgs = request.arguments();\n    \n    // Remove known parameters to get only additional ones\n    Map<String, Object> additionalArgs = new HashMap<>(allArgs);\n    additionalArgs.remove("operation");\n    additionalArgs.remove("priority");\n    \n    if (!additionalArgs.isEmpty()) {\n        result += " with " + additionalArgs.size() + " additional parameters";\n    }\n    \n    return result;\n}\n'})}),"\n",(0,r.jsx)(n.h4,{id:"with-progress-token",children:"With Progress Token"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'@McpTool(name = "flexible-with-progress", description = "Flexible tool with progress")\npublic CallToolResult flexibleWithProgress(\n        @McpProgressToken String progressToken,\n        CallToolRequest request,\n        McpSyncServerExchange exchange) {\n    \n    Map<String, Object> args = request.arguments();\n    \n    if (progressToken != null) {\n        exchange.progressNotification(new ProgressNotification(\n            progressToken, 0.0, 1.0, "Processing dynamic request"));\n    }\n    \n    // Process dynamic arguments\n    String result = processDynamicArgs(args);\n    \n    if (progressToken != null) {\n        exchange.progressNotification(new ProgressNotification(\n            progressToken, 1.0, 1.0, "Complete"));\n    }\n    \n    return CallToolResult.builder()\n        .addTextContent(result)\n        .build();\n}\n'})}),"\n",(0,r.jsx)(n.h2,{id:"parameter-injection-rules",children:"Parameter Injection Rules"}),"\n",(0,r.jsx)(n.h3,{id:"automatic-injection",children:"Automatic Injection"}),"\n",(0,r.jsx)(n.p,{children:"\u4ee5\u4e0b\u53c2\u6570\u7531\u6846\u67b6\u81ea\u52a8\u6ce8\u5165\uff1a"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"McpMeta"})," - \u6765\u81ea\u8bf7\u6c42\u7684\u5143\u6570\u636e"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"@McpProgressToken String"})," - \u8fdb\u5ea6\u4ee4\u724c\uff08\u5982\u679c\u53ef\u7528\uff09"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"McpSyncServerExchange"})," / ",(0,r.jsx)(n.code,{children:"McpAsyncServerExchange"})," - \u670d\u52a1\u5668\u4ea4\u6362\u4e0a\u4e0b\u6587"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"McpTransportContext"})," - \u7528\u4e8e\u65e0\u72b6\u6001\u64cd\u4f5c\u7684\u4f20\u8f93\u4e0a\u4e0b\u6587"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"CallToolRequest"}
1)," - \u7528\u4e8e\u52a8\u6001 schema \u7684\u5b8c\u6574\u5de5\u5177\u8bf7\u6c42"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"schema-generation",children:"Schema Generation"}),"\n",(0,r.jsx)(n.p,{children:"\u7279\u6b8a\u53c2\u6570\u4ece JSON schema \u751f\u6210\u4e2d\u6392\u9664\uff1a"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\u5b83\u4eec\u4e0d\u4f1a\u51fa\u73b0\u5728\u5de5\u5177\u7684\u8f93\u5165 schema \u4e2d"}),"\n",(0,r.jsx)(n.li,{children:"\u5b83\u4eec\u4e0d\u8ba1\u5165\u53c2\u6570\u9650\u5236"}),"\n",(0,r.jsx)(n.li,{children:"\u5b83\u4eec\u5bf9 MCP \u5ba2\u6237\u7aef\u4e0d\u53ef\u89c1"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"null-handling",children:"Null Handling"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"McpMeta"})," - \u6c38\u4e0d\u4e3a null\uff0c\u5982\u679c\u6ca1\u6709\u5143\u6570\u636e\u5219\u4e3a\u7a7a\u5bf9\u8c61"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"@McpProgressToken"})," - \u5982\u679c\u6ca1\u6709\u63d0\u4f9b\u4ee4\u724c\uff0c\u53ef\u4ee5\u4e3a null"]}),"\n",(0,r.jsx)(n.li,{children:"Server exchanges - \u5728\u6b63\u786e\u914d\u7f6e\u65f6\u6c38\u4e0d\u4e3a null"}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"CallToolRequest"})," - \u5bf9\u4e8e\u5de5\u5177\u65b9\u6cd5\u6c38\u4e0d\u4e3a null"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"best-practices",children:"Best Practices"}),"\n",(0,r.jsx)(n.h3,{id:"use-mcpmeta-for-context",children:"Use McpMeta for Context"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'@McpTool(name = "context-aware", description = "Context-aware tool")\npublic String contextAware(\n        @McpToolParam(description = "Data", required = true) String data,\n        McpMeta meta) {\n    \n    // Always check for null values in metadata\n    String userId = (String) meta.get("userId");\n    if (userId == null) {\n        userId = "anonymous";\n    }\n    \n    return processForUser(data, userId);\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"progress-token-null-checks",children:"Progress Token Null Checks"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'@McpTool(name = "safe-progress", description = "Safe progress handling")\npublic String safeProgress(\n        @McpProgressToken String progressToken,\n        @McpToolParam(description = "Task", required = true) String task,\n        McpSyncServerExchange exchange) {\n    \n    // Always check if progress token is available\n    if (progressToken != null) {\n        exchange.progressNotification(new ProgressNotification(\n            progressToken, 0.0, 1.0, "Starting"));\n    }\n    \n    // Perform work...\n    \n    if (progressToken != null) {\n        exchange.progressNotification(new ProgressNotification(\n            progressToken, 1.0, 1.0, "Complete"));\n    }\n    \n    return "Task completed";\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"choose-the-right-context",children:"Choose the Right Context"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\u4f7f\u7528 ",(0,r.jsx)(n.code,{children:"McpSyncRequestContext"})," / ",(0,r.jsx)(n.code,{children:"McpAsyncRequestContext"})," \u7edf\u4e00\u8bbf\u95ee\u8bf7\u6c42\u4e0a\u4e0b\u6587\uff0c\u652f\u6301\u6709\u72b6\u6001\u548c\u65e0\u72b6\u6001\u64cd\u4f5c\uff0c\u5e76\u63d0\u4f9b\u4fbf\u6377\u7684\u8f85\u52a9\u65b9\u6cd5"]}),"\n",(0,r.jsxs)(n.li,{children:["\u4f7f\u7528 ",(0,r.jsx)(n.code,{children:"McpTransportContext"})," \u8fdb\u884c\u7b80\u5355\u7684\u65e0\u72b6\u6001\u64cd\u4f5c\uff0c\u5f53\u60a8\u53ea\u9700\u8981\u4f20\u8f93\u7ea7\u4e0a\u4e0b\u6587\u65f6"]}),"\n",(0,r.jsx)(n.li,{children:"\u5bf9\u4e8e\u6700\u7b80\u5355\u7684\u60c5\u51b5\uff0c\u5b8c\u5168\u7701\u7565\u4e0a\u4e0b\u6587\u53c2\u6570"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"capability-checking",children:"Capability Checking"}),"\n",(0,r.jsx)(n.p,{children:"\u5728\u4f7f\u7528\u5ba2\u6237\u7aef\u529f\u80fd\u4e4b\u524d\uff0c\u59cb\u7ec8\u68c0\u67e5\u80fd\u529b\u652f\u6301\uff1a"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'@McpTool(name = "capability-aware", description = "Tool that checks capabilities")\npublic String capabilityAware(\n        McpSyncRequestContext context,\n        @McpToolParam(description = "Data", required = true) String data) {\n    \n    // Check if elicitation is supported before using it\n    if (context.elicitEnabled()) {\n        // Safe to use elicitation\n        var result = context.elicit(UserInfo.class);\n        // Process result...\n    }\n    \n    // Check if sampling is supported before using it\n    if (context.sampleEnabled()) {\n        // Safe to use sampling\n        var samplingResult = context.sample("Process: " + data);\n        // Process result...\n    }\n    \n    // Note: Stateless servers do not support bidirectional operations\n    // (roots, elicitation, sampling) and will return false for these checks\n    \n    return "Processed with capability awareness";\n}\n'})})]})}function p(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.