AgenticSecond Brain
Agentic · MCP Servers

MCP SERVERS

// 2 custom-built · 10+ integrated · TypeScript + Zod · typed bridges from Claude to any tool

0
Built from Scratch
0+
Integrated as Clients
Project & Task4
Design4
Research2
Automation2
Browser1
Scroll
Primer

What MCP actually is

MCP — Model Context Protocol is Anthropic's open standard for how AI clients talk to tools. Think of it as USB for AI: one plug, any tool. An MCP server exposes named tools with typed inputs and outputs; any MCP-capable client — Claude Code, Claude Desktop, Cursor, anything — calls them like typed functions.

Before MCP, every integration was a hand-crafted wrapper: per-tool REST glue, per-client adapter, duplicated schema definitions, silent failures when upstream API shapes drifted. With MCP, the contract is the protocol. A tool defines its Zod schema once, and every MCP client gets runtime-validated inputs, structured errors, capability negotiation, streaming responses — for free.

The payoff is architectural: the protocol is decoupled from the runtime. If Anthropic ships a new model, or I swap Claude for a different MCP-aware agent tomorrow, nothing in the tool stack breaks. Every server stays intact. Every tool contract stays typed.

Every surface

The MCP landscape

Two servers I built from scratch; the rest are Anthropic-official, vendor, or community servers I wire into the stack. Each one turns a specific system — a REST API, a local filesystem, a browser extension, a design canvas — into a typed surface Claude can query and drive. The agent treats them all the same.

Custom-built
from scratch

Make.com MCP

19 tools · 5 groups

A TypeScript bridge into Make.com's REST API — scenarios, blueprints, executions, connections, data stores, webhooks, folders, orgs & teams. n8n has since become my primary automation runtime, but the MCP server stays maintained so Claude keeps a typed handle on the Make workspace.

github.com/luccafaust/make-mcp-server

Second Brain MCP

9 tools · Obsidian vault

A custom server over my Obsidian vault. vault_search, vault_recall, vault_read, vault_write, vault_update, vault_query, vault_context, vault_link, vault_skill — Claude reads and writes across 140+ atomic notes, keeping the knowledge base alive between sessions.

~/Documents/second-brain/.mcp-server/

Project & Task Management
4 servers
Asana
Tasks, projects, sections, tags
Linear
Issues, cycles, roadmap
Atlassian / Jira
Tickets, sprints, boards
Notion
Pages, databases · ×3 workspaces
Design & Creative
4 servers
Figma
Files, frames, component inspection
Excalidraw
Diagrams, whiteboards, export
Stitch
Screen generation, design systems
Magic (21st.dev)
UI component generation
Research & Documents
2 servers
NotebookLM
Notebooks, sources, research queries
Google Drive
Files, folders, shared docs
Browser & Context
1 server
Arc
Open tabs, bookmarks, browsing context
Automation & Workflows
2 servers
n8n
Self-hosted workflow runner · webhook-triggered from MCP tool calls on other servers
Claude.ai native
First-party MCP bridges for Asana, Linear, Notion, Drive · zero-config

Non-exhaustive — the set grows as new servers ship. Because every integration speaks MCP, adding a new one is a mcpServers config entry, not a code change.

Case study · Make.com

Request Lifecycle

Zooming into one of the two I built — Make.com is actually the least spectacular of the custom surfaces (it's a REST wrapper with good types), but it's the cleanest example to show the MCP request lifecycle end-to-end.

request →
← response
Claude CodeLLM Client
MCP Protocolstdio / SSE
Server + ZodTypeScript
Make.com APIeu2.make.com
Agent Runtime
JSON-RPC 2.0
Zod Validation
REST API
Tool explorer · switch the server

Pick an MCP, inspect its surface

Every server below exposes its tools with the same contract — Zod-validated params in, structured content out, typed errors on failure. Only the verbs differ. The Make tab gets the full interactive schema inspector; the others list their verbs so you can see how the same pattern covers vastly different domains.

The full interactive inspector — 19 tools across 5 API domains (Scenarios, Blueprints, Executions, Data, Orgs & Teams). Click a tool to see its real Zod schema, request shape, and response. n8n has since taken over as the primary orchestrator on the VPS, but this MCP server stays maintained as Claude's read/write surface into the Make workspace.

19 tools total

make_list_scenarios

List all scenarios in the team. Optionally filter by folder.

Schema
z.object({
folder_id: z.number().optional(),
})
Request
{
"folder_id": 12345
}
Response
{
"scenarios": [
{ "id": 1, "name": "Lead Notification", "isActive": true },
{ "id": 2, "name": "Weekly Report", "isActive": false }
]
}
Case study · Make.com

Live Request

A complete MCP tool call end-to-end — from Claude prompt through Zod validation to the Make.com API response. The Second Brain server does the same shape against an Obsidian vault instead of a REST API.

make_list_scenariosLive
TypeScript
MCP SDK
Zod
Node.js
Make.com API
0

Tools Shipped

0

Custom Servers

0%

Type-Safe

0+

Client-Integrated

Architecture

Both custom servers follow the same shape — a long-lived TypeScript process using the official @modelcontextprotocol/sdk, Zod for runtime validation, and a thin adapter per target system. The Make.com server (v2.0.0) wraps Make's REST API with 19 tools across 5 groups: Scenarios (7), Blueprints (2), Executions (2), Data (6 — connections, data stores, webhooks, folders), and Orgs & Teams (2). The Second Brain server wraps an Obsidian vault on disk with 9 tools — vault_search, vault_recall, vault_read, vault_write, vault_update, vault_query, vault_context, vault_link, vault_skill. Different targets, same discipline: every tool input is Zod-validated before it touches the underlying system, every output is serialized through the MCP content format, every failure maps to a structured MCP error.

The SDK handles the hard parts — JSON-RPC transport (stdio or HTTP), capability negotiation, tool registration, streaming responses, schema export — so the server code stays focused on business logic. Claude Code discovers the servers via the mcpServers config block; on startup the client fetches each server's tool list, including Zod schemas converted to JSON Schema, and exposes them to the model as callable functions. No wrappers, no RPC glue, no hand-maintained tool registries.

Same shape, different targets

Both custom servers register tools with server.registerTool() — a Zod schema, capability annotations, an async handler, a structured response. The target system changes (REST API vs. on-disk Markdown files) but the contract is identical. Every MCP client sees them the same way.

make-mcp-server/src/tools/scenarios.ts
server.registerTool(
  "make_list_scenarios",
  {
    title: "List Make Scenarios",
    description: "List all scenarios in the Make.com team.",
    inputSchema: {
      folder_id: z.number().optional().describe("Filter by folder ID"),
    },
    annotations: {
      readOnlyHint: true,
      idempotentHint: true,
      openWorldHint: true,
    },
  },
  async ({ folder_id }) => {
    let path = `/scenarios?teamId=${TEAM_ID}`;
    if (folder_id !== undefined) path += `&folderId=${folder_id}`;
    const result = await makeApiRequest(path);
    return {
      content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
    };
  }
);
second-brain/.mcp-server/src/index.ts
server.tool(
  "vault_query",
  "Strukturierte Abfrage per Frontmatter-Felder.",
  {
    type: z.string().optional().describe("decision | learning | skill | ..."),
    project: z.string().optional().describe("Projektname"),
    status: z.string().optional().describe("active | archived | draft"),
    tags: z.array(z.string()).optional().describe("mind. einer muss matchen"),
    since: z.string().optional().describe("Nur Notes seit Datum (YYYY-MM-DD)"),
  },
  async ({ type, project, status, tags, since }) => {
    const results = queryNotes(VAULT_PATH, { type, project, status, tags, since });
    const summary = results.map(n => ({
      path: n.path,
      title: n.title,
      frontmatter: n.frontmatter,
    }));
    return {
      content: [{ type: "text", text: JSON.stringify({ results: summary }, null, 2) }],
    };
  }
);

Key Decisions

  • MCP SDK over custom protocol

    Standard protocol means any agent can use it — not just Claude Code. The MCP SDK handles transport, serialization, and capability negotiation, so the server stays focused on business logic.

  • Zod for runtime validation

    Catch invalid inputs before they hit Make.com. TypeScript types handle DX at development time; Zod schemas enforce correctness at runtime. Both are derived from the same source of truth — no drift between types and validation.

  • Tool groups over flat list

    Once a server exposes more than a handful of tools, a flat list becomes unusable. On Make the groups map to API domains (Scenarios, Blueprints, Executions, Data, Orgs & Teams); on the Second Brain vault they map to verbs (search, recall, read, write, update, query, context, link, skill). The payoff is predictable, discoverable surfaces for agents and humans alike.

  • Build only what no server exists for

    Make.com and my Obsidian vault had no usable MCP option — so I built them. For Asana, Linear, Notion, Figma, and the rest, there are official or community servers that already cover the surface I need. No point reinventing a typed bridge that already works.

  • Tool descriptions are part of the contract

    The .describe() on every Zod field isn't documentation for humans — it's the context the LLM uses to decide when to call the tool and what to pass. A vague description means the agent guesses; a precise one means it gets the call right first time. I treat descriptions as seriously as the schemas themselves.

  • Structured errors over thrown exceptions

    When the underlying API rate-limits, 404s, or times out, the server returns a structured MCP error — code, message, retry hint — instead of leaking raw HTTP stack traces. The agent can reason about failure (back off, retry, escalate) instead of choking on an opaque exception string.

  • Resources vs. tools — use both

    MCP distinguishes read-only resources from action-taking tools. The Second Brain server exposes the vault index as a resource (Claude can read it without a tool call), and mutations (writes, links, deletes) as tools. Keeps the surface cheap to browse and explicit about side effects.

  • One server per domain, not per integration

    The Make server speaks Make only; the vault server speaks the vault only. A single monolithic “all my tools” server would couple failure modes (one bug takes everything down), blow up the tool surface Claude has to reason over, and make versioning painful. Split surfaces stay composable.