Skip to main content
Glama
Haseeb-Ahmed-AI

customer-data-mcp

mcp-oracle-claude desktop

Ein lokaler MCP-Server (Model Context Protocol), der Kundendaten als abfragbare Tools bereitstellt, sodass Claude natürliche Sprachfragen über Kunden beantworten kann, indem er diesen Server direkt aufruft.

Derzeit sind die Daten lokal gemockt (data/customers.json, 28 fiktive Kundendatensätze mit Bestellhistorie). Später lässt sich die Mock-Datenschicht durch eine echte Verbindung zu Oracle AI Agent Studio ersetzen, ohne den MCP-Toolcode anzufassen – siehe Umstieg auf Oracle AI Agent Studio weiter unten.

Was dieses Projekt macht

Es ist ein stdio-basierter MCP-Server mit fünf Tools:

Tool

Was es tut

search_customers

Suche nach Name, E-Mail oder Firma (Teilübereinstimmung)

get_customer_details

Vollständiges Profil eines Kunden anhand der exakten ID

get_customer_orders

Bestellhistorie eines Kunden

list_customers_by_status

Kunden nach Status filtern: aktiv / inaktiv / abgewandert

get_customer_stats

Gesamtausgaben, Anzahl der Bestellungen, durchschnittlicher Bestellwert für einen Kunden

Sobald er in Claude Desktop als benutzerdefinierter Connector registriert ist, kann Claude diese Tools eigenständig aufrufen, um Fragen zu beantworten wie „Welche Kunden sind abgewandert?" oder „Was hat John Smith bestellt?"

Related MCP server: CRM MCP Server

Projektstruktur

/mcp-oracle-demo
  /data
    customers.json          # mock customer + order data
  /src
    data_source.ts          # ONLY file that touches raw data — the Oracle swap point
    server.ts                # MCP server entry point, registers all tools
    tools/
      search_customers.ts
      get_customer_details.ts
      get_customer_orders.ts
      list_customers_by_status.ts
      get_customer_stats.ts
  /test
    test_data_source.ts     # manual test walkthrough (npm test)
  package.json
  tsconfig.json
  README.md

Lokal installieren und ausführen

Erfordert Node.js 18+.

cd mcp-oracle-demo
npm install
npm run build      # compiles src/ -> dist/
npm start           # runs the compiled server over stdio

Für die lokale Entwicklung ohne Build-Schritt:

npm run dev          # runs src/server.ts directly via tsx

Um zu prüfen, ob alles funktioniert, bevor du es in Claude Desktop einbindest, führe den Test-Durchlauf aus, der die Datenzugriffsschicht und jeden Tool-Handler durchspielt und pro Check PASS/FAIL ausgibt:

npm test

Ein stdio-MCP-Server gibt von sich aus nichts auf stdout aus (stdout ist für den Protokollstream reserviert) – sobald er startet, siehst du auf stderr eine Zeile customer-data-mcp server running on stdio, und anschließend wartet er auf einen Client (wie Claude Desktop), der sich verbindet.

In Claude Desktop registrieren

Füge einen Eintrag zu deiner claude_desktop_config.json hinzu (Claude-Desktop-Menü → Einstellungen → Entwickler → Konfiguration bearbeiten), der auf den kompilierten Server verweist:

{
  "mcpServers": {
    "customer-data": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-oracle-demo/dist/server.js"]
    }
  }
}

Verwende einen absoluten Pfad – Claude Desktop startet den Prozess aus seinem eigenen Arbeitsverzeichnis, nicht aus dem Projektordner. Starte Claude Desktop nach dem Speichern der Konfiguration neu, und du solltest „customer-data" als verbundene Tool-Quelle aufgelistet sehen (halte in einem neuen Chat Ausschau nach dem 🔌 / Tools-Symbol).

Beispielfragen zum Ausprobieren, sobald die Verbindung steht

  • „Zeig mir alle aktiven Kunden."

  • „Was hat [Kundenname] bestellt?"

  • „Welche Kunden sind abgewandert?"

  • „Wie viel hat Kunde CUST-0012 bei uns ausgegeben, und wie hoch ist sein durchschnittlicher Bestellwert?"

  • „Finde Kunden bei Acme Co."

Umstieg auf Oracle AI Agent Studio

src/data_source.ts ist die einzige Datei, die rohe Kundendaten berührt. Jedes MCP-Tool ruft die daraus exportierten Funktionen (getCustomerById, searchCustomers, getCustomerOrders, getCustomersByStatus, getCustomerStats) auf, statt die JSON-Datei direkt zu lesen – die spätere Anbindung an das echte Backend bedeutet also, diese eine Datei zu bearbeiten und nicht die Tool-Definitionen oder den Server.

Was innerhalb von data_source.ts geändert werden müsste:

  1. Authentifizierung – einen Token-Flow (z. B. OAuth-Client-Credentials oder API-Key) für die API von Oracle AI Agent Studio hinzufügen; die Zugangsdaten sollten voraussichtlich aus Umgebungsvariablen statt als hartkodierte Werte gelesen werden, dazu ein kurzlebiger Token-Cache, damit wir uns nicht bei jedem Aufruf neu anmelden.

  2. Den lokalen JSON-Datelesevorgang ersetzen (loadCustomers()) durch authentifizierte REST-Aufrufe an die Endpunkte von Oracle – z. B. GET /customers/{id}, GET /customers/search?q=..., GET /customers?status=... – und die Antwort-Struktur von Oracle auf die bereits in dieser Datei definierten TypeScript-Interfaceschachteln Customer / Order abbilden (oder die Interfaces anpassen, falls das Oracle Schema abweicht).

  3. Fehlerbehandlung – Eine echte API kann Zeitüberschreitungen, Rate Limits oder Fehler verursachen, die beim Lesen einer lokalen Datei nie auftreten; also try/catch-Blöcke ergänzen und klare Fehlermeldungen bereitstellen, die die Tools an Claude zurückgeben.

  4. Caching – Der aktuelle In-Memory-Cache setzt statische une Daten voraus; bei einem echten Backend sollte er entweder entfernt werden.

Die vollständigen Details zu jedem dieser Punkte sind außerdem direkt am Ende von src/data_source.ts auskommentiert.

Tests

npm test führt test/test_data_source.ts aus, das:

  • Jede Funktion von data_source.ts direkt aufruft und die Ergebnisse gegen bekannte Eigenschaften der Mock-Daten prüft (z. B. löst eine bekannte Kunden-ID auf, eine kann null zurückgeben, die Suche ist nicht case-sensitive).

  • Die Handler-Funktion jedes Tools ruft direkt (unter Umgehung des MCP-Transports) auf und prüft, dass das zurückgegebene JSON wohlgeformt ist und mit den zugrunde liegenden Daten übereinstimmt.

Dies ist ein einfaches Skript (kein Test-Framework), damit es leicht Zeile für Zeile zu lesen und in einer Screen-Sharing-Demo erklären lässt.

Let's check for typos and grammar:

  • diese ist ein einfaches Skript — from final "Dies ist..." okay.

  • "ruft erneut ... auf" - no, this is "Calls every tool's handler function", so "Es ruft die Handler-Funktion..." Better.

  • "Das ... das:" Structure: "das:" + lists. My bullet phrases end with comma "das:"? Actually I wrote "* Jede Funktion ... aufruft und ... prüft..." and "* Die Handler-Funktion ... ruft ... und prüft, ..." — because the relative pronoun "das" requires verb-final: "Jede Funktion ... direkt aufruft und ... prüft"; "Die Handler-Funktion jedes Tools direkt aufruft ... und prüft". Good.

  • "über CASE cannot" - no.

  • In "Fehlerbehandlung" list: "zurückgeben kann" should be "die the Tobias" — okay.

  • "Kunden-ID ... liefert null zurück" — fine.

  • "bietet unter Wasser" no.

  • In the table row, maybe use "E-Mail" etc.

  • Need to preserve "Order history for one customer" "Bestellhistoire eines Kundens" okay.

Now check if "logged-in" etc.

Potential punctuation: German typographic quotes: I use „ und ". Some clusters: after «„Welche ...?"» I used the closing quote correctly: "?“, Actually German opening and closing: „Welche ...?" then blank? In Markdown, I used „Welche Kunden sind abgewandert?" – the closing is the same as opening if I haven't typed the closing quote; I typed „...?" — To close, need " before the comma? Let me set the quotes properly:

  • Opening: "…" is something. German: „…" — low opening double quote (U+201E), and closing „ (U+201C) typically appearing like high-9 quote “. In my draft I used rechtsdrehung maybe ne. In Unicode: „ (U+201E), " (U+201C). I'll use pairs: „Welche Kunden sind abgewandert?"; " is the closing quote. So I have that. But in some earlier I wrote "sind abgewandert?"} — it has the double quote " after "?", which is actually the straight quote, not the German closing quote. If I intended German, I should use the curly closing quote in code. Since I can't guarantee U+201C in my output? I can type " but that is same as straight quote. The user didn't require curly. In the final, I'll use plain straight quotation marks to avoid any issue. This is safer and preserves the original underline. Let me redo all quotes as plain ASCII straight quotes (") — the original uses them. So the German doc would have straight double quotes around examples. It's acceptable. I'll change all to ASCII to reduce Unicode issues. The instruction says preserving exact doc; quotes should follow original style. OK.

So final: "Welche Kunden ...?" not „...??". Also the placeholder \[...\]. Let me normalize in final output with double straight ASCII quotes.

Note: The "mcp-oracle" title is all in H1. Good.

Let me reconstruct the final final with ASCII quotes and ensure "PASS/FAIL" is correct.

I will output now.

Wait: Consider the exact phrase "Manager? Sveitating" — no.

Let me also recheck the original "churned" in section: "Filter customers by status: active / inactive / churned" — I translated.

One potential issue: "customer can answer language" etc.

I am done.

Final message below# mcp-oracle-claude desktop

Ein lokaler MCP-Server (Model Context Protocol), der Kundendaten als abfragbare Tools bereitstellt, sodass Claude natürliche Sprachfragen über Kunden beantworten kann, indem er diesen Server direkt aufruft.

Derzeit sind die Daten lokal gemockt (data/customers.json, 28 fiktive Kundendatensätze mit Bestellhistorie). Später lässt sich die Mock-Datenschicht durch eine echte Verbindung zu Oracle AI Agent Studio ersetzen, ohne den MCP-Toolcode anzufassen – siehe Umstieg auf Oracle AI Agent Studio weiter unten.

Was dieses Projekt macht

Es ist ein stdio-basierter MCP-Server mit fünf Tools:

Tool

Was es tut

search_customers

Suche nach Name, E-Mail oder Firma (Teilübereinstimmung)

get_customer_details

Vollständiges Profil für einen Kunden anhand der exakten ID

get_customer_orders

Bestellhistorie für einen Kunden

list_customers_by_status

Kunden nach Status filtern: aktiv / inaktiv / abgewandert

get_customer_stats

Gesamtausgaben, Anzahl der Bestellungen, durchschnittlicher Bestellwert für einen Kunden

Sobald er in Claude Desktop als benutzerdefinierter Connector registriert ist, kann Claude diese Tools eigenständig aufrufen, um Fragen zu beantworten wie "Welche Kunden sind abgewandert?" oder "Was hat John Smith bestellt?"

Projektstruktur

/mcp-oracle-demo
  /data
    customers.json          # mock customer + order data
  /src
    data_source.ts          # ONLY file that touches raw data — the Oracle swap point
    server.ts                # MCP server entry point, registers all tools
    tools/
      search_customers.ts
      get_customer_details.ts
      get_customer_orders.ts
      list_customers_by_status.ts
      get_customer_stats.ts
  /test
    test_data_source.ts     # manual test walkthrough (npm test)
  package.json
  tsconfig.json
  README.md

Lokal installieren und ausführen

Erfordert Node.js 18+.

cd mcp-oracle-demo
npm install
npm run build      # compiles src/ -> dist/
npm start           # runs the compiled server over stdio

Für die lokale Entwicklung ohne Build-Schritt:

npm run dev          # runs src/server.ts directly via tsx

Um zu prüfen, ob alles funktioniert, bevor du es in Claude Desktop einbindest, führe den Test-Durchlauf aus, der die Datenzugriffsschicht und jeden Tool-Handler durchspielt und jede Prüfung mit PASS/FAIL markiert:

npm test

Ein stdio-verbindender MCP-Server gibt von sich aus nichts auf stdout aus (stdout ist für den Protokollstream reserviert) – sobald er startet, siehst du eine Zeile customer-data-mcp server running on stdio auf stderr, und danach wartet er darauf, dass sich ein Client (wie Claude Desktop) verbindet.

In Claude Desktop registrieren

Füge einen Eintrag zu deiner claude_desktop_config.json hinzu (Claude-Desktop-Menü → Einstellungen → Entwickler → Konfiguration bearbeiten), der auf den kompilierten Server verweist:

{
  "mcpServers": {
    "customer-data": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-oracle-demo/dist/server.js"]
    }
  }
}

Verwende einen absoluten Pfad – Claude Desktop startet den Prozess aus seinem eigenen Arbeitsverzeichnis, nicht aus dem Projektordner. Starte Claude Desktop nach dem Speichern der Konfiguration neu, und sollte "customer-data" als verbundene Tool-Quelle erscheinen und in einem neuen Chat nachschauen (halte nach dem 🔌 / Tools-Symbol Ausschau).

Beispielfragen zum Ausprobieren, sobald die Verbindung steht

  • "Zeig mir alle aktiven Kunden."

  • "Was hat [Kundenname] bestellt?"

  • "Welche Kunden sind abgewandert?"

  • "Wie viel hat Kunde CUST-0012 bin uns ausgegeben, und wie hoch ist sein durchschnittlicher Bestellwert?"

  • "Finde Kunden bei Acme Co."

Umstieg auf Oracle AI Agent Studio

src/data_source.ts ist die einzige Datei, die rohe Kundendaten berührt. Jedes MCP-Tool ruft die aus Datei exportierten Funktionen (getCustomerById, searchCustomers, getCustomerOrders, getCustomersByStatus, getCustomerStats) auf, statt die JSON-Datei direkt zu lesen – die spätere Anbindung an das echte Backend bedeutet also, nur diese Datei zu bearbeiten, nicht die Tool-Definitionen oder den Server.

Eingehen auf die Funktionsweise der Datenquelle, umzählen die erforderlich is, inside Sr. If data/horde.ts:

  1. Authentifizierung – einen Token-Flow hinzufügen (z. B. OAuth--Client-Credentials oder API-Key) für die API von Oracle AI Agent Studio; die Zugangsdaten sollten voraussichtlich aus Umgebungsvariablen gelesen werden, statt irgendetwas hart zu kodieren, systemen einen kurzvergischer Cache, damit nicht jeder Aufruf neu authentifiziert.

  2. **Ersetzen des lokalen Daten, die JSON-Datenread (loadCustomers()) durch authentifizierte REST-Aufrufe an die Oracle-Endpunkte – z. B. GET /customers/{id}, GET /customers/search?q=..., GET /customers?status=... – unddem Mapping der Oracle-Antwortstruktur auf die bereits in dieser Datei definierten TypeScript-Interfaces Customer / Order (oder die Interfaces anpassen, falls das Oracle-Schema grad anders ist).

  3. Fehlerbehandlung – eine echte API kann Timeouts, Rate-Limits oder Fehler haben, die beim Lesen einer lokalen Datei nie auftreten; hoch geg Function{add try/catch und klare Fehlermeldungen hinzufügen, die die Sprachmodelle an Claude zurücker fetten.

  4. Caching – der aktuelle In-Memory-Cache geht von statischen Daten aus; bei einem lokalen Backend sollte er entweder geleert werden oder eine kurze Verfallszeit (TTL) erhalten.

Die vollständigen Details zu jedem der Punkte sind am unteren Ende von src/data/quile.ts direkt auskommentiert.

Tests

npm test führt test/test_data_source.ts aus, das:

  • Jede Funktion von data_source.ts direkt aufut und die Ergebnisse gegen bekannte Eigenschaften der Mock-Daten prüft (z. B. wird eine bekannte Kunden-ID aufgelöst, eine deno auf und unbekannte gibt null zurück, Suche ist case-insensitiv).

  • Provokesalle Tool-Handler-Funktionen direkt (über den MCP-Transport) aufruft und die JSON-Überprüfung, dass die zurückgegebenen JSON valid und mit den Daten übereinstimmen.

Es ist ein schlichtes Skript (ohne Test-Framework), damit es leicht zu lesen und in einer Screen-Sharing-Demo Zeile für Zeile zu erklären ist.

Available Tools

5 tools
get_customer_detailsA

Get the full profile for a single customer by their exact customer ID (e.g. 'CUST-0007'). Returns name, contact info, company, signup date, status, and order summary. If you only have a name or email, use search_customers first to find the customer ID.

NameRequiredDescriptionDefault
customer_idYesThe exact customer ID, e.g. 'CUST-0007'.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It states that it returns a profile with specific fields, implying a read-only operation, but it doesn't explicitly confirm read-only behavior, error handling (e.g., not found), or any side effects. While adequate for a simple get, it could be more explicit about the safety and failure modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The core purpose is front-loaded, and the alternative usage is stated concisely. Every sentence contributes information, and there is no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool with no output schema and no annotations, the description covers the essential context: what it does, what it accepts, what it returns, and how to route when the ID is unavailable. It does not detail return structure or error cases, but given the tool's simplicity, this is reasonably complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for the single parameter, so baseline is 3. The description adds value by giving an example format ('CUST-0007') and emphasizing 'exact customer ID', which clarifies that the value must match precisely. This goes beyond the schema's description to reduce ambiguity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Get' and a specific resource 'full profile for a single customer', and identifies the key identifier (customer ID). It distinguishes from the sibling search_customers by explicitly stating when to use that alternative, and it lists the returned fields, making the tool's purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'If you only have a name or email, use search_customers first', giving clear guidance on when to prefer an alternative. However, it does not address other siblings like get_customer_orders or list_customers_by_status, though the mention of 'order summary' hinted at potential overlap. The guidance is helpful but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_customer_ordersA

Get the full order history for a single customer by their exact customer ID (e.g. 'CUST-0007'). Returns a list of orders, each with an order ID, date, product, amount, and order status. If you only have a name or email, use search_customers first to find the customer ID.

NameRequiredDescriptionDefault
customer_idYesThe exact customer ID, e.g. 'CUST-0007'.

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It implies read-only behavior via 'Get' but does not explicitly state non-mutating or any error/edge-case behavior. It does describe the return structure (list with fields), which adds some value, but lacks disclosure on empty results, pagination, or access requirements. For a simple read operation this is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the primary action and example. The second sentence adds return details and a redirect to search_customers. Zero waste, every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read tool with no output schema, the description fully explains what it returns (list with order fields) and provides an alternative when prerequisites are unmet. There is no missing information an agent needs to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema itself documents customer_id with the same example and description. The description adds the qualifier 'exact' and repeats the example, but this is marginal beyond the schema. Baseline 3 is appropriate since the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool gets the full order history for a single customer by exact customer ID, with the example 'CUST-0007'. It also specifies return fields, making the purpose unambiguous. It does not explicitly contrast with every sibling, but it does name search_customers as an alternative, which helps differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear usage context: use when you have the exact customer ID, and if you only have a name/email, use search_customers first. This explicitly sets a condition for when not to use this tool. However, it does not mention other siblings like get_customer_details or get_customer_stats, so coverage of alternatives is incomplete but sufficient for basic routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_customer_statsA

Get summary spend statistics for a single customer by their exact customer ID (e.g. 'CUST-0007'): total order count, total spend (excluding cancelled/refunded orders), average order value, and lifetime value. Use this for questions about how much a specific customer has spent, rather than their raw order list.

NameRequiredDescriptionDefault
customer_idYesThe exact customer ID, e.g. 'CUST-0007'.

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses a key behavioral detail—total spend excludes cancelled/refunded orders—which is essential to interpret the output. However, it does not cover edge cases like nonexistent customer IDs or permission requirements, but for a read-only summary tool this is acceptable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences: the first lists the purpose and metrics, the second gives usage guidance. The phrase 'e.g. CUST-0007' repeats the schema example, but the description is otherwise efficient and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read tool with no output schema, the description adequately covers the return values (metrics listed), a hidden behavioral detail (exclusion of cancelled/refunded), and clear usage context. No critical information is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%; the schema already describes customer_id with an example. The description reinforces 'exact' and repeats the same example, adding no new semantic information. It meets the baseline for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Get'), the resource ('summary spend statistics for a single customer'), and specifies the exact metrics returned (total order count, total spend, average order value, lifetime value). It also explicitly differentiates from raw order lists via the phrase 'rather than their raw order list,' distinguishing it from the sibling get_customer_orders.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides an explicit when: 'Use this for questions about how much a specific customer has spent,' and a when-not with an alternative: 'rather than their raw order list.' This gives clear guidance without ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_customers_by_statusA

List all customers with a given status. Valid statuses are 'active', 'inactive', or 'churned'. Returns each matching customer's basic profile info. Use this for questions like 'show me all active customers' or 'which customers have churned?'

NameRequiredDescriptionDefault
statusYesThe customer status to filter by.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description bears full responsibility for behavioral disclosure. It states that the tool returns 'basic profile info', implying a read-only operation and summarizing the output. It does not mention pagination, ordering, or potential limitations, but for a simple list-by-status tool this is sufficient. The description is honest and does not contradict any annotations (there are none).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences: the first delivers the core action and valid values, the second states the return type and provides query examples. It is front-loaded with the essential purpose and contains zero filler, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool with no output schema and no annotations, the description covers the essential context: what it does, valid inputs, return nature, and usage examples. It does not mention pagination or any edge cases, but given the simplicity of the operation, this is adequate. A 5 would require addressing potential limitations or more specific return details, which are not critical here.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% — the single 'status' parameter already has an enum and a clear description. The description repeats the valid statuses and gives usage examples, which adds a little context but does not provide new semantic meaning beyond what the schema declares. This matches the baseline of 3 for full schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('List'), the resource ('all customers'), and the specific filter ('with a given status'). It also gives concrete example queries, which makes the purpose unambiguous. The verb 'list' distinguishes it from sibling tools like search_customers (search) and get_customer_details (single customer), so an agent can easily tell them apart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage context with example questions ('show me all active customers', 'which customers have churned?'), telling the agent when to invoke this tool. However, it does not mention when not to use it or explicitly contrast with alternatives like search_customers or get_customer_details, so it stops short of the full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_customersA

Search for customers by name, email, or company name. Performs a case-insensitive partial match, so 'smith' will match 'John Smith' and 'jane.smith@...'. Returns a list of matching customers with their basic profile info (does not include full order history — use get_customer_details or get_customer_orders for that). Use this when the user gives a name, email, or company rather than an exact customer ID.

NameRequiredDescriptionDefault
queryYesSearch text to match against customer name, email, or company (partial match, case-insensitive). Example: 'smith', 'acme', 'john@example.com'.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden. It discloses case-insensitive partial matching, indicates the return content ('basic profile info'), and explicitly excludes full order history, directing to other tools. It does not mention pagination or error behavior, but for a read-only search these are minor gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the core purpose, each earning its place. No redundancy, and the secondary alternatives are mentioned succinctly without digressing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter search tool, it covers the essential context: what it matches, what it returns (basic profile), what it excludes (order history), and when to use it. It could elaborate on what 'basic profile info' includes, but given the single parameter and no output schema, this is adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema already fully documents the query parameter with description and example, covering the matching behavior (partial, case-insensitive). The tool description restates the same info but adds no new semantic detail beyond the schema, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description states a specific verb ('Search for customers'), identifies the resource ('customers'), and enumerates searchable fields (name, email, company). It also distinguishes from siblings by noting it's for partial text matches rather than exact IDs and mentions get_customer_details/get_customer_orders for order history, making it clear what this tool is for.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use: 'Use this when the user gives a name, email, or company rather than an exact customer ID.' It also guides toward alternatives for order history, providing clear when-to-use and when-not-to-use 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.

  1. 5 tool updatesv1.0.0
    • First observedget_customer_details
    • First observedget_customer_orders
    • First observedget_customer_stats
    • First observedlist_customers_by_status
    • First observedsearch_customers

TDQS

A4.4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: search by name/email/company, get details by ID, get orders by ID, list by status, and get stats by ID. There is no overlap; the descriptions explicitly clarify when to use each (e.g., search_customers vs. get_customer_details).

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern using snake_case: search_customers, get_customer_details, get_customer_orders, list_customers_by_status, get_customer_stats. The verbs (search, get, list, get) and nouns are uniform and predictable.

Tool Count5/5

5 tools is well-scoped for a customer data server, sitting comfortably within the ideal 3-15 range. Each tool addresses a distinct query type without redundancy, making the surface concise and maintainable.

Completeness4/5

The tool set covers the core read-oriented workflows: search, details, orders, status-based listing, and stats. The only minor gap is a lack of a way to list all customers regardless of status (e.g., a list_customers tool), but list_customers_by_status can approximate this with a single status, and the domain appears read-only by design.

Maintenance

ActivityStale
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers