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.