enterprise-mcp-gateway
This server is an enterprise MCP gateway that exposes CRM capabilities to AI agents with security, redaction, and auditing.
List and filter customer accounts (
listCustomers)Retrieve full customer details including address, tax ID, and email (
getCustomerDetails)View billing history and payment methods (
getBillingHistory)Query support tickets by customer or priority (
listSupportTickets)Open new support tickets (
createSupportTicket)Enforces role-based access control (RBAC) for tool visibility and execution
Redacts PII, secrets, and sensitive keys from tool responses in real time
Emits structured JSON audit logs with hashed parameters and latency metrics
Supports both stdio and HTTP SSE transports
Dynamically registers tools from OpenAPI/Swagger specs
Allows AI agents to connect to and invoke APIs of Java/Spring Boot enterprise backends through the gateway.
Dynamically creates MCP tools from OpenAPI/Swagger specifications, enabling AI agents to call any compatible backend API.
Enterprise MCP Gateway
๐ Key Features
โก Blazing Fast & Lightweight: Single static Go binary (<25MB resident memory footprint, sub-millisecond routing overhead, zero external runtime dependencies).
๐ก๏ธ High-Performance PII & Secret Redaction: Real-time stream and JSON-key masking (Credit Cards with Luhn checksum validation, SSNs, emails, phone numbers, AWS keys, JWTs, GitHub PATs, and custom regex rules) before tool responses reach LLMs.
๐ Role-Based Tool Governance (RBAC): Token-to-role resolution that limits tool visibility in
tools/listand enforces execution permissions duringtools/call.๐ Dynamic OpenAPI / Swagger Connector: Instantly registers validated MCP tools directly from OpenAPI 3.0/Swagger YAML or JSON specs without writing backend glue code.
๐ Structured JSON Audit Logging: Emits tamper-resistant, structured JSON logs containing caller identity, tool invoked, SHA-256 hashed parameters, execution latency, and PII redaction metrics.
๐ Dual Transport Support: Fully compliant JSON-RPC 2.0 engine supporting both standard
stdio(for Claude Desktop / Cursor) and HTTP Server-Sent Events (SSE) for distributed microservices.
Related MCP server: Nervora
๐๏ธ Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ AI Client (Claude / Cursor / Agent) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ JSON-RPC 2.0 (stdio or SSE)
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Enterprise MCP Gateway (Single Go Binary) โ
โ โ
โ 1. Transport Layer (pkg/mcp/transport) โ
โ - Stdio & HTTP-SSE Transceivers โ
โ 2. Security & Auth Guard (pkg/governance/rbac) โ
โ - Token authentication & least-privilege filtering โ
โ 3. Router & Tool Registry (pkg/mcp/protocol) โ
โ - JSON-RPC 2.0 & MCP handshake engine โ
โ 4. Backend Dispatcher (pkg/connector/openapi) โ
โ - Dynamic OpenAPI 3.0 path/query/body mapper โ
โ 5. Sanitization Engine (pkg/sanitizer/pii) โ
โ - Zero-alloc PII, secret, & JSON key redactor โ
โ 6. Structured Audit Logger (pkg/audit) โ
โ - Cryptographic JSON event trail for SIEM โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Authorized & Sanitized Calls
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Internal Enterprise Services (Java / Go / DBs) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ๐ฆ Quick Start
1. Build from Source
Ensure you have Go 1.24+ installed:
# Clone the repository
git clone https://github.com/BenjaminJ/enterprise-mcp-gateway.git
cd enterprise-mcp-gateway
# Build gateway and mock backend server
go build -o bin/mcp-gateway ./cmd/gateway
go build -o bin/mockserver ./cmd/mockserver2. Run the Mock Enterprise Backend (Terminal 1)
./bin/mockserver --port 80813. Run the Gateway with Sample Config (Terminal 2)
Option A: Stdio Mode (Default)
./bin/mcp-gateway --config ./examples/config.yaml --token "agent-support-key"Option B: HTTP Server-Sent Events (SSE) Mode
./bin/mcp-gateway --config ./examples/config.yaml --transport sse --port 80804. Stream Live Audit Logs in Real-Time (Terminal 3)
Follow and format structured audit records as tools execute:
PowerShell (Windows):
Get-Content -Path .\audit.log -Wait -Tail 10 | ForEach-Object {
if ($_ -match '^\s*\{') {
$e = $_ | ConvertFrom-Json
$time = ([DateTime]$e.timestamp).ToLocalTime().ToString("HH:mm:ss")
$statusColor = if ($e.status -eq "SUCCESS") { "Green" } else { "Red" }
$redactColor = if ($e.pii_redacted_count -gt 0) { "Yellow" } else { "DarkGray" }
Write-Host "[$time] " -NoNewline -ForegroundColor DarkGray
Write-Host "[$($e.status)] " -NoNewline -ForegroundColor $statusColor
Write-Host "$($e.tool) " -NoNewline -ForegroundColor Cyan
Write-Host "(Role: $($e.role), Latency: $($e.duration_ms)ms, Redacted: $($e.pii_redacted_count))" -ForegroundColor $redactColor
}
}Bash / Linux / macOS (jq):
tail -f audit.log | jq -c '{time: .timestamp, status: .status, tool: .tool, role: .role, latency_ms: .duration_ms, redacted: .pii_redacted_count}'๐ Verification with Anthropic Official MCP Inspector
You can test and inspect the gateway using Anthropic's official @modelcontextprotocol/inspector:
Test via Stdio:
npx @modelcontextprotocol/inspector ./bin/mcp-gateway --config ./examples/config.yaml --token agent-support-keyTest via SSE:
Start the gateway in SSE mode:
./bin/mcp-gateway --config ./examples/config.yaml --transport sse --port 8080Open the inspector pointing to the SSE endpoint:
npx @modelcontextprotocol/inspector http://localhost:8080/sse
๐ป Claude Desktop Integration
To connect Claude Desktop to your enterprise systems through enterprise-mcp-gateway:
Open your Claude Desktop configuration file:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
Add
enterprise-mcp-gatewayto themcpServersobject:
{
"mcpServers": {
"enterprise-gateway": {
"command": "/absolute/path/to/enterprise-mcp-gateway/bin/mcp-gateway",
"args": [
"--config",
"/absolute/path/to/enterprise-mcp-gateway/examples/config.yaml",
"--token",
"agent-support-key"
]
}
}
}Restart Claude Desktop. The enterprise tools (
listCustomers,getCustomerDetails,createSupportTicket, etc.) will appear with a hammer icon in the prompt interface.
โ๏ธ Configuration Guide (config.yaml)
server:
name: "enterprise-mcp-gateway"
version: "1.0.0"
transport: "stdio" # "stdio" or "sse"
host: "0.0.0.0"
port: 8080
governance:
enabled: true
default_role: "support_agent"
tokens:
"agent-ro-secret": "readonly_agent"
"agent-support-secret": "support_agent"
"admin-master-secret": "admin"
roles:
readonly_agent:
allowed_tools:
- "list*"
- "get*"
support_agent:
allowed_tools:
- "list*"
- "get*"
- "createSupportTicket"
admin:
allowed_tools:
- "*"
sanitizer:
enabled: true
mask_card_numbers: true # Luhn-verified Credit Card masking
mask_ssn: true # US SSN masking
mask_secrets: true # Private keys, AWS keys, JWTs, PATs
sensitive_keys:
- "password"
- "secret"
- "token"
- "apiKey"
- "ssn"
- "creditCard"
custom_regex:
- name: "Internal Employee ID"
pattern: "\\bEMP-[0-9]{6}\\b"
replacement: "[REDACTED-EMP-ID]"
audit:
enabled: true
log_path: "stdout" # "stdout" or path to file e.g. "/var/log/mcp-audit.log"
hash_inputs: true # SHA-256 hashes tool arguments for compliance
connectors:
- name: "enterprise-crm"
type: "openapi"
spec_file: "./examples/crm-openapi.yaml"
base_url: "http://localhost:8081"
headers:
Authorization: "Bearer backend-secret-token"
X-Gateway-Source: "enterprise-mcp-gateway"
timeout_seconds: 15๐งช Testing
Run all unit and end-to-end integration tests:
# Run all unit and integration tests
go test -v ./...
# Run tests with the Go race detector enabled
go test -race ./...๐ณ Docker Deployment
# Build lightweight Docker image
docker build -t enterprise-mcp-gateway:latest .
# Run container in SSE mode
docker run -d -p 8080:8080 -p 8081:8081 enterprise-mcp-gateway:latest --transport sse --port 8080๐ License
MIT License.
Available Tools
5 toolscreateSupportTicketA
Open and route a new customer support incident ticket - Creates a new support incident or customer inquiry ticket in the CRM queue.
[Usage Guidelines]
When to use: Use this tool to escalate customer technical issues, report system bugs, or file service requests that require support team intervention.
When NOT to use: Do NOT use this tool before checking if a similar ticket already exists; use 'listSupportTickets' first to prevent duplicate tickets. Do NOT use to reset passwords; use 'adminResetPassword' instead.
Prerequisites: Requires a confirmed customerId obtained from 'listCustomers' or 'getCustomerDetails'.
[Behavior]
Operation: Mutating and non-idempotent. Each invocation assigns a new unique ticket ID and dispatches notifications to support engineers.
Side effects: Creates a persistent ticket record and routes to on-call queues.
Authorization: Requires 'support_agent' or 'admin' role ('readonly_agent' tokens are rejected with 403).
[Parameters & Validation]
'customerId' (string, required): Customer identifier string (e.g. 'cust-001') the ticket is filed on behalf of.
'subject' (string, required): Concise summary line of the incident (10 to 120 characters).
'description' (string, required): Detailed problem statement, reproduction steps, or error messages.
'priority' (string, optional): Urgency level: 'low', 'normal', 'high', or 'urgent'. Defaults to 'normal' if omitted.
[Returns]
Returns HTTP 201 Created with JSON object: ticketId (e.g. 'tick-902'), customerId, subject, priority, status ('open'), and createdAt timestamp.
| Name | Required | Description | Default |
|---|---|---|---|
| subject | Yes | Concise summary line or title describing the core problem (e.g., 'Database latency issue on invoice generation'). Between 10 and 120 characters. | |
| priority | No | Urgency priority level for routing and SLA dispatch. Defaults to 'normal' when omitted. Use 'urgent' only for total outages. | normal |
| customerId | Yes | Unique customer ID associated with this support request (e.g., 'cust-001'). Must be an existing account identifier. | |
| description | Yes | Full detailed explanation of the incident, steps to reproduce, user impact, or relevant error codes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses that the operation is mutating and non-idempotent, that each call assigns a new ticket ID and dispatches notifications, that it creates a persistent record, and that authorization requires support_agent or admin with readonly_agent rejected. This exceeds the burden normally placed on the description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is organized into labeled sections and front-loaded with the core operation. The opening line is slightly redundant ('Open and route' vs 'Creates a new support incident'), but the structure makes the content immediately scannable and every section carries actionable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-parameter mutating tool with no annotations and no output schema, the description covers operation semantics, side effects, authorization guards, usage exclusions, prerequisites, parameter validation rules, and the exact HTTP response shape. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema itself documents all four parameters with types, defaults, enums, and examples. The description's Parameters & Validation section largely restates the schema, adding minor context (e.g., 'filed on behalf of') but no substantial new meaning, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Creates', 'Open and route'), resource ('customer support incident ticket'), and context ('CRM queue'). It clearly distinguishes from sibling listSupportTickets by framing this as creation rather than retrieval, and names the operation the tool performs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Contains explicit When to use / When NOT to use sections, naming listSupportTickets as a duplicate-prevention step and adminResetPassword as the alternative for password resets. Also gives a concrete prerequisite: confirmed customerId from listCustomers or getCustomerDetails.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getBillingHistoryA
Retrieve customer billing statements, balances, and payment methods - Retrieves complete billing statements, current account balance due, payment methods on file, and historical invoice IDs for a specific customer.
[Usage Guidelines]
When to use: Use this tool to answer customer inquiries regarding outstanding balances, billing disputes, invoice history, or active payment methods.
When NOT to use: Do NOT use this tool for customer account profile details; use 'getCustomerDetails' instead. Do NOT use to search for customer IDs; use 'listCustomers' first. Do NOT use to check customer support issues; use 'listSupportTickets' instead.
Prerequisites: Requires a valid customerId (e.g., 'cust-001') previously discovered using 'listCustomers'.
[Behavior]
Operation: Read-only and idempotent. No financial transactions, charges, or balance mutations are executed.
Authorization: Requires 'readonly_agent', 'support_agent', or 'admin' role.
DLP / Sanitization: All payment card numbers, bank account numbers, and CVVs in responses are automatically masked with [REDACTED] by the zero-allocation gateway sanitizer.
[Parameters]
'customerId' (path, required): Unique customer identifier string (e.g. 'cust-001'). Must correspond to an active or archived customer account.
[Returns]
Returns HTTP 200 with JSON object containing: customerId, currency, balanceDue (decimal), paymentMethods (array of masked card tokens), and invoices (array of invoice objects with id, date, amount, status). Returns HTTP 404 if customerId is not found.
| Name | Required | Description | Default |
|---|---|---|---|
| customerId | Yes | Unique customer identifier in format 'cust-XXX' (e.g., 'cust-001'). Prerequisite is a valid customerId discovered from listCustomers. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility for behavioral disclosure, and it delivers thoroughly. It explicitly states the operation is read-only and idempotent, lists the required authorization roles, and reveals that payment data is automatically redacted via DLP sanitization. This goes well beyond a typical tool description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized into Purpose, Usage Guidelines, Behavior, Parameters, and Returns sections. Each section is dense with actionable information and does not repeat details already present in the schema unnecessarily. The structure front-loads the tool's purpose and then logically covers when, how, and what to expect.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description correctly explains the return payload: HTTP 200 with a JSON object containing customerId, currency, balanceDue, paymentMethods, and invoices, plus HTTP 404 handling. It also covers prerequisites, authorization, and alternative tools, making the description complete for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents customerId with an example and prerequisite, giving 100% schema coverage. The description adds extra meaning by specifying that the parameter is a path parameter, required, and must correspond to an active or archived customer account. This is meaningful enrichment beyond the schema, though only modestly so.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb and resource: 'Retrieve customer billing statements, balances, and payment methods,' then enumerates the exact outputs: complete billing statements, balance due, payment methods, and invoice IDs. This clearly distinguishes it from sibling tools like getCustomerDetails and listSupportTickets, which are about profile or support data, not billing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit 'When to use' and 'When NOT to use' sections, naming specific sibling tools (getCustomerDetails, listCustomers, listSupportTickets) and the conditions that rule them in or out. It also states the prerequisite that a valid customerId must be discovered via listCustomers first, leaving no ambiguity about when to invoke this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getCustomerDetailsA
Retrieve full profile record for a specific customer by ID - Retrieves comprehensive account profile metadata for an individual enterprise customer.
[Usage Guidelines]
When to use: Use this tool when you have an exact customerId and need full profile information such as registered tax ID, billing address, account tier, and primary contact details.
When NOT to use: Do NOT use this tool to search or discover customers; use 'listCustomers' instead. Do NOT use to view invoices or payment methods; use 'getBillingHistory' instead.
Prerequisites: Requires a valid 'customerId' (format 'cust-XXX') previously obtained via 'listCustomers'.
[Behavior]
Operation: Read-only and idempotent. Calling this tool causes no mutations or side effects.
Authorization: Requires 'readonly_agent', 'support_agent', or 'admin' role.
DLP / Sanitization: Sensitive personal attributes (such as SSN or tax identifiers) are automatically masked by the gateway DLP engine before response delivery.
[Parameters]
'customerId' (path, required): Unique customer identifier string in 'cust-XXX' format (e.g. 'cust-001'). Must match an existing customer record.
[Returns]
Returns HTTP 200 with full customer profile: customerId, name, email, taxId (redacted), address, serviceTier, and status. Returns HTTP 404 if the customerId does not exist.
| Name | Required | Description | Default |
|---|---|---|---|
| customerId | Yes | Unique customer identifier in format 'cust-XXX' (e.g., 'cust-001', 'cust-002'). Must correspond to an existing customer record discovered via listCustomers. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so thoroughly: it declares the operation is read-only and idempotent, lists required authorization roles, and discloses DLP redaction of sensitive identifiers. This is strong behavioral disclosure beyond the bare schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized with clear headings and front-loaded purpose. There is some redundancy between the opening sentence and the usage/returns sections, but overall every major section earns its place and the structure supports quick scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema and no annotations, the description compensates completely: it covers when to use, when not to use, prerequisites, behavior, authorization, DLP sanitization, parameter semantics, return payload, and error status. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The tool description adds the path-binding detail and restates the 'cust-XXX' format and existence requirement, but most parameter meaning is already present in the schema. It adds value only marginally.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Retrieve full profile record for a specific customer by ID'. It clearly frames the tool as returning account profile metadata for one enterprise customer, which differentiates it from list-oriented or billing-related siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'When to use' and 'When NOT to use' sections name alternatives (listCustomers, getBillingHistory) and the conditions for choosing them. It also states the prerequisite of having a valid customerId from listCustomers, leaving no ambiguity about when the tool applies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listCustomersA
List and search enterprise customer profiles - Retrieves a paginated list of enterprise customer profiles.
[Usage Guidelines]
When to use: Use this tool to discover, search, or browse customer records across the organization, or to find a customerId before calling detail tools.
When NOT to use: Do NOT use this tool if you already have a specific customerId and need full profile or contact attributes; use 'getCustomerDetails' instead. Do NOT use to inspect customer billing or invoices; use 'getBillingHistory' instead.
Alternatives: Use 'getCustomerDetails' for single-record deep inspection.
[Behavior]
Operation: Read-only and idempotent. Safe to call multiple times with identical parameters without side effects.
Authorization: Requires 'readonly_agent', 'support_agent', or 'admin' role.
DLP / Sanitization: Customer email addresses and account statuses are returned. Any internal notes are scrubbed.
[Parameters & Interactions]
'status' (query, optional): Filter by lifecycle state ('active', 'inactive', 'suspended'). If omitted, customers in all lifecycle states are returned.
'limit' (query, optional): Integer between 1 and 100 specifying maximum records to return per page. Defaults to 20 if omitted.
[Returns]
Returns a JSON array of customer summary objects, each containing: customerId (string, e.g. 'cust-001'), name (string), email (string), and status (string).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of customer records to return in a single page (integer between 1 and 100). Defaults to 20 when omitted. Use smaller limits (e.g. 5-10) for faster LLM processing context. | |
| status | No | Filter customers by account lifecycle status. Valid values are 'active' (in good standing), 'inactive' (dormant), or 'suspended' (past due or locked). Leave empty to retrieve accounts across all lifecycle states. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden, and it succeeds: it declares the operation read-only and idempotent, lists required authorization roles, and discloses DLP sanitization behavior. This goes well beyond a generic API description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear labeled sections and a concise front-loaded summary. It is slightly repetitive with the schema in the parameters section, but the overall organization makes the length acceptable and scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter list tool with no annotations and no output schema, the description covers returns, authorization, sanitization, and usage guidance well. The only notable gap is that 'paginated' is mentioned but no pagination navigation mechanism (e.g., cursor, offset, or next-page token) is described, and 'search' in the title is not backed by a search-text parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description largely restates the schema's parameter details for 'status' and 'limit' without adding significant new semantics beyond what the schema already documents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'List and search enterprise customer profiles' and clarifies it returns a paginated list of summaries. It distinguishes itself from siblings by directing deep single-record lookups to 'getCustomerDetails' and billing to 'getBillingHistory'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The [Usage Guidelines] section explicitly states when to use the tool, when NOT to use it, and names alternatives with exact tool names. An agent can confidently route between listCustomers, getCustomerDetails, and getBillingHistory without ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listSupportTicketsA
Query and filter customer support tickets across the organization - Queries open, in-progress, and resolved support incident tickets across enterprise accounts.
[Usage Guidelines]
When to use: Use this tool to check existing service tickets, verify SLA status, review customer incident history, or ensure an issue is not already logged before filing a new ticket.
When NOT to use: Do NOT use this tool to open or submit a new ticket; use 'createSupportTicket' instead. Do NOT use to check billing issues; use 'getBillingHistory' instead.
Recommended Flow: Call 'listSupportTickets' first to inspect existing tickets for a customer before creating a duplicate with 'createSupportTicket'.
[Behavior]
Operation: Read-only and idempotent. Querying tickets produces zero side effects or ticket state modifications.
Authorization: Requires 'readonly_agent', 'support_agent', or 'admin' role.
DLP / Sanitization: Ticket descriptions containing secrets or credentials are redacted prior to LLM presentation.
[Parameters & Interactions]
'customerId' (query, optional): Restricts ticket query to a single customer ID (e.g., 'cust-001'). If omitted, tickets across all enterprise accounts are queried.
'priority' (query, optional): Filter by ticket urgency level ('low', 'normal', 'high', 'urgent').
Parameter Interaction: If both 'customerId' and 'priority' are provided, tickets matching BOTH filters are returned (AND logic).
[Returns]
Returns HTTP 200 with JSON array of ticket objects, each containing: ticketId (e.g. 'tick-101'), customerId, subject, description, priority, status ('open', 'in_progress', 'resolved'), and createdAt timestamp.
| Name | Required | Description | Default |
|---|---|---|---|
| priority | No | Filter tickets by urgency level ('low', 'normal', 'high', 'urgent'). When combined with customerId, returns only tickets matching both filters. Leave empty to retrieve tickets of all priority tiers. | |
| customerId | No | Optional filter to retrieve support tickets specifically for a single customer ID (e.g., 'cust-001'). When omitted, tickets across all customer accounts are returned. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden, and it fully delivers: states the operation is read-only and idempotent with zero side effects, lists required authorization roles, and discloses DLP redaction of secrets. This is strong behavioral disclosure beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but organized into clear sections (Usage, Behavior, Parameters, Returns), with every section earning its place. The summary line front-loads the core purpose before detail, making it easy for an agent to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the Returns section correctly fills that gap by specifying HTTP 200, a JSON array shape, and all fields including an example ticketId. Combined with usage, behavior, authorization, and parameter coverage, nothing needed to invoke this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters and their filter behavior. The description adds a clear AND-logic note, but this is largely redundant with the priority parameter's schema description, so it does not significantly extend parameter meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Query and filter customer support tickets across the organization,' and adds scope (statuses, enterprise accounts). This distinguishes it clearly from siblings like listCustomers and createSupportTicket.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use scenarios, explicit when-not-to-use exclusions with named alternatives ('createSupportTicket', 'getBillingHistory'), and a recommended pre-flight flow to avoid duplicate tickets. This is ideal routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
5 tool updates
v1.0.3- Changed
createSupportTicket4 fields changed- changed
Input schema / properties / customerId / descriptionPrevious value: -"The customer ID associated with this support request (e.g., 'cust-001')."New value: +"Unique customer ID associated with this support request (e.g., 'cust-001'). Must be an existing account identifier." - changed
Input schema / properties / description / descriptionPrevious value: -"Detailed explanation of the customer issue, reproduction steps, or question."New value: +"Full detailed explanation of the incident, steps to reproduce, user impact, or relevant error codes." - changed
Input schema / properties / priority / descriptionPrevious value: -"Urgency priority level for the ticket routing."New value: +"Urgency priority level for routing and SLA dispatch. Defaults to 'normal' when omitted. Use 'urgent' only for total outages." - changed
Input schema / properties / subject / descriptionPrevious value: -"Brief summary or title of the support issue (e.g., 'Database latency issue')."New value: +"Concise summary line or title describing the core problem (e.g., 'Database latency issue on invoice generation'). Between 10 and 120 characters."
- Changed
getBillingHistory1 field changed- changed
Input schema / properties / customerId / descriptionPrevious value: -"Unique customer identifier in format 'cust-XXX' (e.g., 'cust-001')."New value: +"Unique customer identifier in format 'cust-XXX' (e.g., 'cust-001'). Prerequisite is a valid customerId discovered from listCustomers."
- Changed
getCustomerDetails1 field changed- changed
Input schema / properties / customerId / descriptionPrevious value: -"Unique customer identifier in format 'cust-XXX' (e.g., 'cust-001', 'cust-002')."New value: +"Unique customer identifier in format 'cust-XXX' (e.g., 'cust-001', 'cust-002'). Must correspond to an existing customer record discovered via listCustomers."
- Changed
listCustomers2 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum number of customer records to return in a single page (between 1 and 100). Defaults to 20."New value: +"Maximum number of customer records to return in a single page (integer between 1 and 100). Defaults to 20 when omitted. Use smaller limits (e.g. 5-10) for faster LLM processing context." - changed
Input schema / properties / status / descriptionPrevious value: -"Filter customers by account lifecycle status (e.g., 'active', 'inactive', or 'suspended'). Leave empty to retrieve all statuses."New value: +"Filter customers by account lifecycle status. Valid values are 'active' (in good standing), 'inactive' (dormant), or 'suspended' (past due or locked). Leave empty to retrieve accounts across all lifecycle states."
- Changed
listSupportTickets2 fields changed- changed
Input schema / properties / customerId / descriptionPrevious value: -"Optional filter to retrieve support tickets for a specific customer ID (e.g., 'cust-001')."New value: +"Optional filter to retrieve support tickets specifically for a single customer ID (e.g., 'cust-001'). When omitted, tickets across all customer accounts are returned." - changed
Input schema / properties / priority / descriptionPrevious value: -"Filter tickets by urgency level ('low', 'normal', 'high', 'urgent')."New value: +"Filter tickets by urgency level ('low', 'normal', 'high', 'urgent'). When combined with customerId, returns only tickets matching both filters. Leave empty to retrieve tickets of all priority tiers."
5 tool updates
v1.0.1- Changed
createSupportTicket10 fields changed- added
Input schema / properties / customerId / descriptionAdded value: +"The customer ID associated with this support request (e.g., 'cust-001')." - added
Input schema / properties / customerId / exampleAdded value: +"cust-001" - added
Input schema / properties / description / descriptionAdded value: +"Detailed explanation of the customer issue, reproduction steps, or question." - added
Input schema / properties / description / exampleAdded value: +"Customer reported timeouts when generating PDF invoices for Q3." - added
Input schema / properties / priority / defaultAdded value: +"normal" - added
Input schema / properties / priority / descriptionAdded value: +"Urgency priority level for the ticket routing." - added
Input schema / properties / priority / enumAdded value: +[ + "low", + "normal", + "high", + "urgent" +] - added
Input schema / properties / priority / exampleAdded value: +"high" - added
Input schema / properties / subject / descriptionAdded value: +"Brief summary or title of the support issue (e.g., 'Database latency issue')." - added
Input schema / properties / subject / exampleAdded value: +"Database latency issue on invoice generation"
- Changed
getBillingHistory2 fields changed- changed
Input schema / properties / customerId / descriptionPrevious value: -"Unique customer identifier"New value: +"Unique customer identifier in format 'cust-XXX' (e.g., 'cust-001')." - added
Input schema / properties / customerId / exampleAdded value: +"cust-001"
- Changed
getCustomerDetails2 fields changed- changed
Input schema / properties / customerId / descriptionPrevious value: -"Unique customer identifier"New value: +"Unique customer identifier in format 'cust-XXX' (e.g., 'cust-001', 'cust-002')." - added
Input schema / properties / customerId / exampleAdded value: +"cust-001"
- Changed
listCustomers8 fields changed- added
Input schema / properties / limit / defaultAdded value: +20 - changed
Input schema / properties / limit / descriptionPrevious value: -"Max records to return"New value: +"Maximum number of customer records to return in a single page (between 1 and 100). Defaults to 20." - added
Input schema / properties / limit / exampleAdded value: +10 - added
Input schema / properties / limit / maximumAdded value: +100 - added
Input schema / properties / limit / minimumAdded value: +1 - changed
Input schema / properties / status / descriptionPrevious value: -"Filter customers by active/inactive status"New value: +"Filter customers by account lifecycle status (e.g., 'active', 'inactive', or 'suspended'). Leave empty to retrieve all statuses." - added
Input schema / properties / status / enumAdded value: +[ + "active", + "inactive", + "suspended" +] - added
Input schema / properties / status / exampleAdded value: +"active"
- Changed
listSupportTickets5 fields changed- changed
Input schema / properties / customerId / descriptionPrevious value: -""New value: +"Optional filter to retrieve support tickets for a specific customer ID (e.g., 'cust-001')." - added
Input schema / properties / customerId / exampleAdded value: +"cust-001" - changed
Input schema / properties / priority / descriptionPrevious value: -""New value: +"Filter tickets by urgency level ('low', 'normal', 'high', 'urgent')." - added
Input schema / properties / priority / enumAdded value: +[ + "low", + "normal", + "high", + "urgent" +] - added
Input schema / properties / priority / exampleAdded value: +"high"
5 tool updates
v1.0.0- First observed
createSupportTicket - First observed
getBillingHistory - First observed
getCustomerDetails - First observed
listCustomers - First observed
listSupportTickets
TDQS
Each tool targets a distinct resource and action: customer search, customer detail, billing history, ticket listing, and ticket creation. The usage guidelines explicitly reinforce these boundaries, making misselection unlikely.
All tool names follow a consistent camelCase verb_noun pattern: list/get/create plus the target resource. There is no mixing of conventions or vague, ambiguous verbs.
Five tools is a well-scoped set for a focused customer and support gateway. Each tool has a clear purpose and none are redundant or extraneous.
Read coverage for customers, billing, and tickets is solid, and ticket creation exists. However, there are notable lifecycle gaps: no way to update or resolve support tickets, and no customer create/update/delete operations, which creates dead ends in common workflows.
Maintenance
Related MCP Connectors
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
MCP gateway with runtime security policy, tool-call-level control, and audit of agent actions.
MCP Gateway: wrap any MCP server with cold-start retries, uptime SLA, and per-execution MPP billing.
Zero-setup MCP gateway securely connecting AI to your tools with authentication and workflows
Related MCP Servers
AlicenseNot gradedqualityAmaintenanceToolMesh is an Apache-2.0, self-hosted MCP gateway written in Go that sits between AI agents and backend systems. It enforces a fail-closed pipeline on every tool call, including per-tool and per-user authorization, server-side credential injection, structured audit logging, and output policies. APIs are declared in YAML with DADL, turning REST endpoints into MCP tools without writing a custom MCP6Apache 2.0- AlicenseNot gradedqualityCmaintenanceA secure MCP gateway for enterprise AI tool execution, enabling governed invocation of business tools with authentication, RBAC, audit logging, PII redaction, and async processing.Apache 2.0
- AlicenseNot gradedqualityBmaintenanceMCP gateway adding per-tool RBAC, tenant isolation, audit export, and PII redaction to any server.MIT
- AlicenseNot gradedqualityCmaintenanceUniversal MCP router and gateway that bridges LLM agents to OpenAPI, GraphQL, and AWS Lambda services with ISO/IEC 42001 AI governance, RBAC, PII redaction, semantic tool routing, and a web dashboard.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/BenjaminJ/enterprise-mcp-gateway'
If you have feedback or need assistance with the MCP directory API, please join our Discord server