MCP annotations

The nine MCP annotations that define an agent-facing server, its topics and its tools, with real examples.

Source: framework/mcp/src/com/ilscipio/scipio/mcp/def/. These annotations define the MCP servers and tools an AI agent calls; see Agents for the access model.

@McpServer#

Defines one MCP server profile, usually one per application component.

AttributeTypeDefaultMeaning
nameStringrequiredServer name.
titleString""Human-readable title.
descriptionString""Server description, shown to the agent.
componentString""Component directory name the server belongs to.
webappsString[]{}Webapps the server is exposed on.
featuredServicesString[]{}Services ranked first in tool search.
serviceAllowString[]{}Services explicitly allowed through the gateway.
serviceDenyString[]{}Services denied on this server.
entitiesString[]{}Entities the server may read through entity tools.
allowAnonymousbooleanfalseWhether the server accepts calls without a token.
requiredPermissionString""Permission required to use the server.
hubbooleanfalseWhether this is the cross-application hub server.
topicsMcpTopic[]{}Topics this server declares; a topic is one tool with an action argument.
serviceToolsMcpServiceTool[]{}Services wrapped directly as tools.
providersClass<? extends McpToolProvider>[]{}Tool providers that build tools at run time.

@McpServiceTool#

Wraps one existing service as a tool, inside @McpServer(serviceTools = {...}) or @McpServerExtension(serviceTools = {...}).

AttributeTypeDefaultMeaning
serviceStringrequiredService name to wrap.
nameString""Tool name. Defaults to the service name in snake_case.
descriptionString""Tool description. Defaults to the service description.
featuredbooleanfalseWhether the tool is ranked first.
orderint100Sort order among tools; lower first.
readOnlybooleanfalseWhether the tool only reads data.
destructiveString""Whether the tool is destructive.
idempotentString""Whether repeat calls are safe.
permissionString""Permission required, beyond the default gate.
requiresConfirmationbooleanfalseClient-side confirmation hint.
topicString""Topic this service tool joins.
excludeString[]{}Service parameters to hide from the tool schema.
fixedString[]{}Service parameters fixed to a set value.
tagsString[]{}Free-form tags.

@McpTool#

Marks a hand-written static method as one tool.

AttributeTypeDefaultMeaning
topicString""Topic this method joins. The topic is the tool the agent sees.
nameStringrequiredTool name, or, with a topic, the action value.
titleString""Human-readable title.
descriptionStringrequiredTool description, shown to the agent.
featuredbooleanfalseWhether the tool is ranked first.
orderint100Sort order among tools; lower first.
readOnlybooleanfalseWhether the tool only reads data.
destructiveString""Whether the tool is destructive.
idempotentString""Whether repeat calls are safe.
permissionString""Permission required, beyond the default gate.
accessMcpAccessMcpAccess.AUTHAUTH (token required) or PUBLIC.
requiresConfirmationbooleanfalseClient-side confirmation hint.
tagsString[]{}Free-form tags.

@McpTopic#

Declares one topic: the tool an agent sees, with the methods of that topic as its action values. Declare it on @McpServer(topics = ...) or @McpServerExtension(topics = ...).

AttributeTypeDefaultMeaning
nameStringrequiredTopic name. This is the tool name the agent calls.
titleString""Human-readable title.
descriptionString""Topic description, shown to the agent.
orderint100Sort order among tools; lower first.
featuredbooleanfalseWhether the topic is ranked first.

@McpParam#

One parameter of an @McpTool method.

AttributeTypeDefaultMeaning
nameStringrequiredParameter name.
descriptionString""Parameter description.
requiredbooleantrueWhether the parameter is required.
enumValuesString[]{}Allowed values, if the parameter is an enum-like string.
typeString""Explicit type override for the schema.
exampleString""Example value shown to the agent.

@McpPrompt#

Defines one reusable prompt template the server exposes.

AttributeTypeDefaultMeaning
nameStringrequiredPrompt name.
descriptionString""Prompt description.
argumentsArg[]{}Prompt arguments (nested @Arg: name, description, required default false).

@McpResource#

Defines one static or templated resource the server exposes.

AttributeTypeDefaultMeaning
uriStringrequiredResource URI, for example scipio://skills/<name>.
nameStringrequiredResource name.
descriptionString""Resource description.
mimeTypeString"text/plain"MIME type of the resource content.

@McpServerExtension#

Adds tools to a server owned by another component, without changing that server’s source.

AttributeTypeDefaultMeaning
serverStringrequiredName of the server to extend.
featuredServicesString[]{}Extra featured services.
serviceAllowString[]{}Extra allowed services.
serviceDenyString[]{}Extra denied services.
entitiesString[]{}Extra entities.
topicsMcpTopic[]{}Extra topics this extension declares.
serviceToolsMcpServiceTool[]{}Extra services wrapped as tools.
providersClass<? extends McpToolProvider>[]{}Extra tool providers.

@McpAccess#

Enum, not an annotation: the access level of one tool, used by @McpTool(access = ...).

ValueMeaning
AUTHRequires a valid token.
PUBLICAvailable without a token when the server sets allowAnonymous = true.

Example: the manufacturing server#

applications/manufacturing/src/com/ilscipio/scipio/manufacturing/mcp/ManufacturingMcp.java, lines 27-40.

java
@McpServer(name = "manufacturing", title = "Scipio Manufacturing", component = "manufacturing",
        description = "Manufacturing: explode a bill of material, find and inspect production runs, create a production run and change its status.",
        featuredServices = {"createProductionRun", "updateProductionRun", "changeProductionRunStatus",
                "createBOMAssoc", "updateProductManufacturingRule", "createMrpEvent", "getProductRouting", "getManufacturingComponents",
                "quickRunAllProductionRunTasks", "executeMrp", "getWorkCenterLoad", "getManufacturingDashboard", "getShopFloorTasks",
                "declareProductionRunTaskReject", "getProductionRunRejects", "getProductStandardCost", "getProductWhereUsed",
                "createProductionRunsForOrder", "changeProductionRunTaskStatus", "updateProductionRunTask"},
        entities = {"ProductManufacturingRule", "TechDataCalendar", "TechDataCalendarExcDay", "WorkEffortGoodStandard",
                "TechDataCalendarExcWeek", "TechDataCalendarWeek", "MrpEventType", "MrpEvent", "MrpEventView", "MrpRun", "ProductionRunReject"},
        serviceTools = {
            @McpServiceTool(service = "createProductionRun", name = "production_run_create",
                    description = "Create a production run: productId, pRQuantity, startDate, facilityId, optional routingId and workEffortName.",
                    featured = true, readOnly = false, destructive = "false", requiresConfirmation = true, order = 40),
            @McpServiceTool(service = "changeProductionRunStatus", name = "production_run_update_status",
                    description = "Move a production run to the next status (PRUN_SCHEDULED, PRUN_DOC_PRINTED, PRUN_RUNNING, PRUN_COMPLETED, PRUN_CLOSED) or to the given statusId.",
                    featured = true, readOnly = false, destructive = "true", requiresConfirmation = true, order = 50),

The server declares its name, the entities it may read, and a set of existing services wrapped directly as tools with agent-facing names and descriptions.

Example: an @McpTool method#

applications/accounting/src/com/ilscipio/scipio/accounting/mcp/AccountingMcp.java.

java
@McpTool(topic = "invoice", name = "find", description = "Find invoices by id, type, status, party or invoice date range.",
        readOnly = true, order = 10)
public static Object findInvoices(McpCallContext ctx,
        @McpParam(name = "invoiceId", required = false) String invoiceId,
        @McpParam(name = "invoiceTypeId", description = "e.g. SALES_INVOICE, PURCHASE_INVOICE", required = false) String invoiceTypeId,
        @McpParam(name = "statusId", description = "e.g. INVOICE_IN_PROCESS, INVOICE_READY, INVOICE_PAID", required = false) String statusId,
        @McpParam(name = "partyId", description = "Bill-to party (partyId) or bill-from party (partyIdFrom)", required = false) String partyId,
        @McpParam(name = "fromDate", description = "Invoice date on/after", required = false) Timestamp fromDate,
        @McpParam(name = "thruDate", description = "Invoice date on/before", required = false) Timestamp thruDate,
        @McpParam(name = "limit", required = false) Integer limit) throws McpToolException {

Every parameter but ctx carries an @McpParam. None is required, so the agent can call the tool invoice with action find and any subset of filters.

Topics: one tool, many actions#

An application has hundreds of operations and an agent works better with few tools. @McpTopic groups them: the methods that name the same topic become one tool, and the method’s name becomes the action argument of that tool. The install ships 31 application topics with 318 actions, plus six core tools.

java
@McpServer(name = "order", topics = {
    @McpTopic(name = "order", description = "Sales and purchase orders: find, create, approve, pay, ship, return."),
    @McpTopic(name = "purchase_order", description = "Requirements, purchase orders and their supplier."),
    @McpTopic(name = "quote", description = "Quotes and customer requests.")
})
public final class OrderMcp { }

topic exists on @McpTool and on @McpServiceTool; topics exists on @McpServer and on @McpServerExtension. A method with no topic stays a tool of its own.

Ask the people who wrote it.

Support, development and training from the team that builds Scipio ERP.