Files
sage-mcp-server/.sisyphus/research/mcp-server-architecture.md

3.9 KiB

MCP Server Architecture — Research Findings

Official SDK: @modelcontextprotocol/sdk

Basic Server Pattern

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "my-server",
  version: "1.0.0",
});

// Register a tool
server.tool(
  "tool-name",
  "Tool description for AI agent",
  { param: z.string() },
  async ({ param }) => ({
    content: [{ type: "text", text: `Result: ${param}` }],
  }),
);

// Connect via stdio
const transport = new StdioServerTransport();
await server.connect(transport);

Transport Options

  1. stdio — local process communication (Claude Desktop, Cursor)
  2. Streamable HTTP — network transport (replaces deprecated HTTP+SSE)
    • NodeStreamableHTTPServerTransport for stateful sessions

Three MCP Primitives

  1. Tools — Functions the AI can call (primary focus for ERP integration)
  2. Resources — Data the AI can read (documentation, configs, schemas)
  3. Prompts — Template conversations for common scenarios

Production MCP Server Requirements

What the spec covers:

  • Capability negotiation (initialize)
  • Tool listing/execution (tools/list, tools/call)
  • Resource listing/reading (resources/list, resources/read)
  • Transport: stdio and Streamable HTTP

What production requires beyond spec:

  • Authentication and authorization (OAuth2, JWT)
  • Rate limiting per IP/token/tool
  • Input schema validation before execution
  • Concurrency control
  • Backpressure when saturated
  • Observability (Prometheus metrics, OpenTelemetry traces)
  • CORS, CSP, max request body size
  • Signal handling (SIGTERM, graceful shutdown)
  • Error handling and retry patterns

Tool Design Best Practices

Schema Precision

// BAD — vague schema
inputSchema: { type: "object" }

// GOOD — precise and documented
inputSchema: {
  type: "object",
  properties: {
    query: {
      type: "string",
      description: "SQL SELECT query to execute",
    },
    limit: {
      type: "number",
      minimum: 1,
      maximum: 100,
      default: 10,
      description: "Maximum number of rows to return",
    },
  },
  required: ["query"],
  additionalProperties: false,
}

Tool Granularity for ERP

  • Fine-grained tools: get_invoice, search_customers, check_stock
  • Each tool has clear purpose and precise schema
  • AI agent uses schema + description to decide when to call

Resource Patterns for Documentation

server.registerResource(
  {
    uri: "sage://help/invoicing",
    name: "Invoice Help",
    description: "Sage X3 invoicing documentation",
    mimeType: "text/markdown",
  },
  async () => ({
    text: "# Invoice Help\n...",
  }),
);

Existing ERP MCP Server: @casys/mcp-erpnext

  • Connects AI agents to ERPNext (open-source ERP)
  • Exposes invoices, purchase orders, stock levels, accounting data
  • Good reference for design patterns:
    • Focused scope per tool
    • Strong input validation
    • Read-only defaults with explicit write permissions

Testing

  • mcp-inspector: Official CLI testing tool
  • Programmatic testing: Use SDK's Client class
npx @modelcontextprotocol/inspector

Key Design Decisions for Sage X3 MCP Server

  1. Which API(s) to use: GraphQL (newest, typed) vs REST vs SOAP (legacy but comprehensive)
  2. Tool granularity: Domain-specific (get_invoice, search_orders) vs generic (query_graphql)
  3. Auth strategy: How to manage Sage X3 credentials (env vars, config file)
  4. Resource layer: Sage X3 documentation, schema info as resources
  5. Prompt templates: Common troubleshooting scenarios

IMPORTANT NOTE FOR AGENTS

When using background_task or similar functions, timeouts are in MILLISECONDS not seconds.

  • 60 seconds = 60000 ms
  • 120 seconds = 120000 ms
  • Default timeout: 120000 ms (2 minutes)