Stacklane heet nu Vantion LabsLees meer

MCP-starterkit: geef AI-agents veilige toegang tot interne systemen

We gebruiken deze starterkit als een agent toegang nodig heeft tot interne systemen, zoals een CRM, een ERP of een documentopslag. Je krijgt vanaf de eerste commit een Model Context Protocol-server in TypeScript, gebouwd op Effect, met login, afgebakende rechten en een registratie van elke aanroep.

Wat erin zit

Hoe het in elkaar zit

  1. 01

    Verbinden

    Een MCP-client, zoals Claude, Cursor of een interne agent, verbindt via streamable HTTP. Zonder token wordt hij naar je identity provider verwezen en doorloopt daar de OAuth-flow.

  2. 02

    Autoriseren

    De server controleert het token met de gepubliceerde sleutels van de provider, of zoekt de API-sleutel op, en toetst de scope die de tool vereist.

  3. 03

    Uitvoeren

    De tool roept het interne systeem aan via een kleine client die doorgeeft wie de aanroeper is, met rate limits en time-outs.

  4. 04

    Vastleggen

    De aanroep komt in het auditlog en er gaat een getypeerd resultaat terug naar de agent.

Een blik op de code

Een read-only tool met een getypeerd resultaat, een scopecheck en een regel in het auditlog.

TypeScript
import { Effect, Schema } from "effect";
import { Tool, Toolkit } from "effect/unstable/ai";
import { CrmClient, Customer, CustomerNotFound } from "./CrmClient.ts";
import { GuardFailures, ToolGuard } from "../tools/ToolGuard.ts";

const GetCustomer = Tool.make("get_customer", {
  description: "Look up a customer by id.",
  parameters: Schema.Struct({ customerId: Schema.String }),
  success: Customer,
  failure: Schema.Union([CustomerNotFound, ...GuardFailures]),
}).annotate(Tool.Readonly, true);

export const CrmToolkit = Toolkit.make(GetCustomer);

export const CrmToolkitLive = CrmToolkit.toLayer(
  Effect.gen(function*() {
    const guard = yield* ToolGuard;
    const crm = yield* CrmClient;
    return CrmToolkit.of({
      // Checks crm:read, applies the rate and time limits, writes the audit entry.
      get_customer: (params) =>
        guard.run(
          { tool: "get_customer", scope: "crm:read", arguments: params },
          () => crm.getCustomer(params.customerId),
        ),
    });
  }),
);

Gebouwd met

Alle technologie

Bespreek één proces met de oprichter