Claude Certification
All case studies
Tool Design & MCP · 18% of exam

How DataLayer built its integrations platform on MCP

Replacing a tangle of bespoke connectors with reusable MCP servers.

Company
DataLayer (fictional, dev-tooling startup)
Duration
10 weeks
Outcome
Cut new-connector dev time from 4 weeks to 6 days. Tool-call error rate dropped from 18% to 2%. Same MCP servers now power their CLI, their desktop app, and three customer-built agents.

The pain

DataLayer ships data-source connectors for Postgres, Snowflake, Notion, Salesforce, and a dozen more. Originally each connector was a bespoke Python wrapper with hand-written tool schemas for the agent. Three problems compounded:

  1. 18% tool-call error rate. Agents kept passing malformed arguments.
  2. Three implementations per connector. Same connector code lived in their CLI, their hosted product, and their customer SDK.
  3. No standard error shape. Every connector raised its own exceptions.

Step 1 — Fix schemas before anything else

A representative *before* schema:

{
  "name": "query",
  "params": { "input": "string" }
}

After:

{
  "name": "run_sql",
  "description": "Execute a read-only SQL query against the warehouse.",
  "params": {
    "sql": { "type": "string", "description": "Read-only SQL. SELECT/CTE/EXPLAIN only." },
    "schema": { "type": "string", "default": "analytics", "description": "Postgres schema namespace" },
    "row_limit": { "type": "integer", "default": 1000, "maximum": 10000 }
  }
}

Flat, intent-revealing field names, explicit defaults, enumerated bounds where applicable. Within two weeks the malformed-argument rate dropped from 18% to 5%.

Step 2 — Make errors teach the agent

The team standardized on a three-field error contract for every tool:

{
  "error_code": "TABLE_NOT_FOUND",
  "message": "Table 'order_events' does not exist in schema 'public'.",
  "hint": "This workspace's tables live in schema 'analytics'. Try analytics.order_events."
}

The biggest gain wasn't speed — it was that retries actually *succeeded*. Agents stopped looping on opaque "operation failed" strings and instead corrected themselves on the next call. The remaining 5% malformed-argument rate fell to 2%.

Step 3 — Move from bespoke connectors to MCP servers

Each connector became an MCP server. The same Postgres MCP server now exposes:

  • Tools: run_sql, describe_table, list_schemas
  • Resources: postgres://table/{schema}/{name} for any table (cacheable client-side)
  • Prompts: /explain-this-query and /find-slow-queries — templates customers can surface in their own clients

The same server runs over stdio for local dev and over HTTPS for hosted. One implementation, three surfaces (CLI, desktop, customer SDK). New-connector dev time dropped from four weeks to six days because most of the work is now defining the schema and error map.

Step 4 — Resources, not tools, for big data

Their warehouse-metadata catalog has tens of thousands of tables. Exposing each as a tool call would burn schema tokens on every interaction. They expose them as resources:

postgres://table/analytics/order_events
postgres://table/analytics/users
…

Clients cache resources locally. When an agent says "read analytics.order_events schema", the client serves it from its cache without round-tripping. Token cost on metadata operations dropped roughly 70%.

Step 5 — Test schemas and tools separately

The team now ships two test suites for every connector:

# 1. Tool function tests — no LLM.
def test_run_sql_returns_rows():
    rows = run_sql({"sql": "SELECT 1", "schema": "analytics"})
    assert rows == [{"?column?": 1}]

# 2. Schema probe — tiny Claude call, checks tool arg validity.
async def test_schema_yields_valid_args():
    arg = await claude_probe("Read the first 5 rows of analytics.users")
    RunSqlArgs.model_validate(arg)  # raises if schema isn't communicating

When something breaks, you know whether it's the implementation or the schema description.

What stuck

  • Schema design is the single biggest lever on tool-call reliability.
  • A common error contract turns failures into recovery opportunities.
  • MCP is what unlocks reuse across CLI / desktop / SDK with one implementation.
  • Resources for read-only addressable data; tools for verbs.
  • Two test layers: function correctness and schema communicability.
Principles applied