Knowledge Graphs — Hybrid Pattern with External MCP
Knowledge Graphs are for slow-changing domain models. They are not the right choice for high-volume transactional data such as a large SKU catalog with real-time stock, an order history with millions of rows, or a customer database that updates every minute. Record allowances depend on your plan or Enterprise agreement; this guidance is about change rate and ownership, not a fixed graph size.
The right pattern for these domains is hybrid: put the domain structure in a Knowledge Graph and the live data behind an external MCP server. The agent uses both — the Knowledge Graph to understand “how my domain works” and the MCP server to answer “what is in stock right now”.
The boundary
Section titled “The boundary”| Layer | Knowledge Graph | External MCP server |
|---|---|---|
| Cardinality | Curated reference sets within the deployment quota | Operational systems sized for their workload |
| Change rate | Hours / days (slow-changing) | Seconds / minutes (real-time) |
| Source of truth | A reviewed bundle maintained by your team | Your existing operational system (Shopify, SAP, custom database) |
| Update pattern | brewctl kg apply (atomic) | Live API calls |
| Tools agent uses | list_X, get_X, list_X_ids | Custom tools per MCP server (search_products, get_inventory, …) |
| Question answered | ”How does my domain work?" | "What is in my system right now?” |
Example: E-commerce shoe store
Section titled “Example: E-commerce shoe store”A running-shoes e-commerce store with a large, frequently changing SKU catalog is best modeled in layers.
What lives in the Knowledge Graph
Section titled “What lives in the Knowledge Graph”The structure of the shoe domain:
- Category tree (~50 categories: running → road → trail → …)
- Attribute taxonomy (10-50 attributes: size, color, material, pronation_type)
- Attribute value enums (color: red/blue/black/…, size: EU 36..48)
- Brand registry (~50-500 brands with positioning metadata)
- Size conversion tables (US ↔ EU ↔ UK)
bundle_name: shoe-store-taxonomyversion: 2026-05-27.1entity_types: - name: category schema_file: schemas/category.schema.json entities_file: entities/categories.yaml - name: brand schema_file: schemas/brand.schema.json entities_file: entities/brands.yaml - name: attribute_definition schema_file: schemas/attribute_definition.schema.json entities_file: entities/attributes.yamlbrewctl kg apply ./my-storeAfter you add and apply the entity files, SyntheticBrew stores one entity for each record, subject to the deployment’s plan or Enterprise quota, and generates tools such as:
list_category(filters={parent_id?, surface?})get_category(ids)list_brand(filters={tier?, in_category?})get_brand(ids)list_attribute_definition(filters={for_category?})get_attribute_definition(ids)What lives in an external MCP server
Section titled “What lives in an external MCP server”The inventory — 20K SKUs with prices, stock, photos, reviews. This is the customer’s existing system (Shopify, custom API). They put an MCP server in front of it:
With brewctl, keep the MCP server and agent as separate resources:
apiVersion: syntheticbrew/v1kind: MCPServername: shoe-inventorytype: httpurl: https://shop.example.com/mcpauth_type: api_keyauth_key_env: SHOE_INVENTORY_TOKENenabled: trueapiVersion: syntheticbrew/v1kind: Agentname: shop-assistantmodel: glm-5mcp_servers: [shoe-inventory]capabilities: - type: knowledge_graphs enabled: true config: bundles: [shoe-store-taxonomy]The direct REST equivalent also uses separate MCP-server, agent, and capability endpoints. Do not put capabilities inside a config-import agent block; that nested field belongs to the brewctl resource format.
The shoe-inventory MCP server provides:
search_products(filters={category_id, brand_id, size, color, in_stock, price_range})get_product(sku)get_inventory(sku)list_recent_reviews(product_id, limit)How an agent uses both
Section titled “How an agent uses both”A multi-step user query like “I want red running shoes for the road, neutral pronation, under $150”:
Step 1: list_category(filters={parent: "running", surface: "road"}) → KG returns: [ {id: "road-running-neutral", label: "Neutral Road Running"}, {id: "road-running-stability", label: "Stability Road Running"}, ... ]
Step 2: get_attribute_definition(ids=["pronation_type"]) → KG returns: { entities: [{id: "pronation_type", data: { enum: ["neutral", "overpronation", "underpronation"] }}], not_found: [] }
Step 3: list_brand(filters={tier: "mid", category: "road-running-neutral"}) → KG returns: ~8 brands matching
Step 4: search_products( category_id: "road-running-neutral", pronation: "neutral", color: "red", brand_in: [...], price_lte: 150 ) → EXTERNAL MCP returns: 23 actual SKUs in stock, with prices and photos
Step 5: get_product(sku="ASICS-GEL-NIMBUS-25-RED-42") → EXTERNAL MCP returns: full product data, reviews, alternative sizesThe Knowledge Graph gives the agent a map of the domain — what categories exist, what “neutral pronation” means, which brands are relevant for road running. The external MCP server gives live availability.
The Knowledge Graph supplies the reviewed brand classifications and allowed pronation values. The external MCP server supplies current stock. The agent can use both sources in one workflow without copying changing inventory into the graph bundle.
Example: Healthcare formulary
Section titled “Example: Healthcare formulary”A medical reference application providing drug recommendations. Knowledge Graph holds the medical taxonomy, an external MCP server provides the patient-specific formulary.
Knowledge Graph (structure)
Section titled “Knowledge Graph (structure)”list_condition(filters={icd10_chapter, severity})list_symptom(filters={condition})list_treatment_class(filters={condition})list_active_ingredient(filters={treatment_class})Conditions, symptoms, treatment classes, and active ingredients with ATC codes. This is slow-changing reference data curated by domain experts.
External MCP server (patient context)
Section titled “External MCP server (patient context)”get_patient_allergies(patient_id)list_available_medications(active_ingredient, country)get_drug_interactions(drug_id_a, drug_id_b)Patient-specific, jurisdiction-specific, frequently updated. Lives in the hospital’s existing pharmacy system, exposed via MCP.
Agent workflow
Section titled “Agent workflow”User: “What can I prescribe for a patient with flu symptoms?”
Step 1: list_condition(filters={symptom_group: "flu_like"}) → KG: list of flu-like conditions with ICD-10 codes
Step 2: list_treatment_class(filters={condition: "J10"}) → KG: antiviral classes for influenza
Step 3: list_active_ingredient(filters={treatment_class: "antivirals"}) → KG: oseltamivir, zanamivir, ...
Step 4: get_patient_allergies(patient_id="PT-12345") → EXTERNAL MCP: patient allergy list
Step 5: list_available_medications(active_ingredient="oseltamivir", country="DE") → EXTERNAL MCP: products available in GermanyWhen to choose the boundary
Section titled “When to choose the boundary”A simple rule: if the data answers questions about your domain itself (taxonomy, categories, attributes, relationships, controlled vocabularies), it goes in a Knowledge Graph. If the data answers questions about a specific instance or current state (stock, prices, patient records, transactions), it goes in an external MCP server.
A second rule: if records change continuously or must reflect the latest transaction, keep them in the operational system. Knowledge Graph bundles are declarative and atomically reconciled, so they fit reviewed reference data better than transactional state.
Anti-patterns
Section titled “Anti-patterns”❌ All fast-changing SKUs in a Knowledge Graph
Section titled “❌ All fast-changing SKUs in a Knowledge Graph”Even when a plan permits the record count, frequently changing prices and stock defeat the purpose of a declarative reference bundle. Use an external MCP server for transactional inventory.
❌ One Knowledge Graph entity per user
Section titled “❌ One Knowledge Graph entity per user”User profiles change frequently. They are also tenant-specific data that should live in your application’s primary data store, not in a customer-declared bundle. Use a dedicated API or external MCP server.
❌ Hardcoding inventory in agent system prompts
Section titled “❌ Hardcoding inventory in agent system prompts”A common workaround is to list the product catalog in the system prompt. That becomes difficult to update, does not provide typed filters, and can lead to invented or stale IDs. Use a Knowledge Graph for the structure plus an external MCP server for live data.
See also
Section titled “See also”- Knowledge Graphs concept — when and why to use Knowledge Graphs
- Schema annotations reference —
x-*annotations - MCP servers — connecting external MCP servers to SyntheticBrew