Connectors
Connectors are the Extend stage of the harness pipeline — how an agent perceives data and reaches the tools it acts through. They are MCP-native, so every MCP server is already a Kraken connector.
#Overview
An agent is only as capable as what it can perceive and reach. Connectors are the bridge: they feed agents data from databases, APIs, and internal systems, and they expose tools the agent can call to do work. A connector is a plain module in your project — the file name is the identity.
Connectors are MCP-native. Kraken did not invent a proprietary connector protocol; it builds on the Model Context Protocol, the open standard for connecting AI systems to external tools. Every MCP server in the ecosystem is automatically a Kraken connector. The platform’s value is the governance, authentication, and health monitoring layer it adds on top — not the protocol itself.
Note
Because connectors are MCP-native, the protocol is portable: you are never locked in by the way your agents reach their tools. See Open by Default.
#Defining a connector
Author a connector with defineConnector and defineTool from @kraken-ai/platform. The definition declares a displayName, a description, the environment variables it needs at runtime, and a record of tools. The file’s path is its identity — a connector at src/connectors/filesystem.ts is the filesystem connector.
import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
import { normalize, resolve } from "node:path";
import { defineConnector, defineTool } from "@kraken-ai/platform";
import * as z from "zod";
const DATA_DIR = resolve(process.env.KRAKEN_DATA_DIR ?? "./data");
await mkdir(DATA_DIR, { recursive: true });
const safePath = (relativePath: string): string => {
const resolved = resolve(DATA_DIR, normalize(relativePath));
if (resolved !== DATA_DIR && !resolved.startsWith(`${DATA_DIR}/`)) {
throw new Error("Path traversal denied");
}
return resolved;
};
// File at src/connectors/filesystem.ts → identity = "filesystem"
export default defineConnector({
displayName: "Filesystem",
description: "Read and write files in the data directory",
requiredEnvVars: ["KRAKEN_DATA_DIR"],
tools: {
fs_read: defineTool({
description: "Read a file from the data directory",
input: z.object({ path: z.string().describe("Relative path within data directory") }),
handler: async ({ path }: { path: string }) => readFile(safePath(path), "utf-8"),
}),
fs_write: defineTool({
description: "Write content to a file",
input: z.object({
path: z.string().describe("Relative path within data directory"),
content: z.string().describe("File content to write"),
}),
annotations: { destructiveHint: true },
handler: async ({ path, content }: { path: string; content: string }) => {
const safe = safePath(path);
await mkdir(resolve(safe, ".."), { recursive: true });
await writeFile(safe, content, "utf-8");
return { success: true };
},
}),
fs_list: defineTool({
description: "List files and directories",
input: z.object({
path: z.string().optional().describe("Relative path (defaults to root)"),
}),
annotations: { readOnlyHint: true },
handler: async ({ path }: { path?: string }) => {
const entries = await readdir(safePath(path ?? "."), { withFileTypes: true });
return entries.map((e: { name: string; isDirectory: () => boolean }) => ({
name: e.name,
type: e.isDirectory() ? "dir" : "file",
}));
},
}),
},
});requiredEnvVars declares the environment variables a connector reads at runtime, such as a third-party API key. At provisioning time the platform supplies only the declared keys to the connector, sourced from the agent’s configured environment — undeclared keys are not visible to connector code.
#Tools
A tool is a single callable an agent can invoke. defineTool takes a Zod schema as its input and infers the handler’s argument types from it, giving you end-to-end type safety from schema to handler.
descriptionstringRequiredHuman-readable description of what the tool does. Surfaced to the agent so it can decide when to call the tool.
inputZodTypeRequiredA Zod schema describing the tool’s arguments. The handler’s parameter type is inferred from this schema.
annotationsToolAnnotationsOptionalOptional MCP tool hints — readOnlyHint, destructiveHint, idempotentHint, and openWorldHint — that describe the tool’s behavior to the model.
handler(args) => resultRequiredThe function that runs when the tool is called. Receives the parsed, typed arguments and returns a string, number, boolean, object, array, MCP content, or null/undefined.
#Resources & prompts
Because connectors are MCP-native, a connector can expose more than tools. Alongside the tools record, defineConnector accepts optional resources and prompts records — the resource and prompt primitives from the Model Context Protocol. Resources expose readable content an agent can pull in as context; prompts expose reusable, parameterized message templates.
Resources and prompts pass through the same governance and health layer as tools — every interaction with a connector is mediated by the platform, regardless of which MCP primitive it uses.
#Using a connector in an agent
Attach a connector to an agent through the connectors array on definePlatformAgent. Import the connector module and pass it in — the agent gains every tool the connector exposes.
import { definePlatformAgent } from "@kraken-ai/platform";
import filesystem from "../connectors/filesystem";
import researchGuidelines from "../skills/research-guidelines";
export default definePlatformAgent({
model: "google/gemini-3-flash-preview",
instructions:
"You are a research agent. Use the filesystem tools to read and analyze files. Follow the research-guidelines skill for methodology.",
skills: [researchGuidelines],
connectors: [filesystem],
});For the full agent definition surface — models, teams, skills, and actions — see Agents.
#Governed access
Connectors are where an agent touches real systems, so every tool call a connector serves passes through the governance gateway before it runs. Policies are evaluated at call time and resolve to one of three outcomes:
- Allow — the call proceeds and the result is returned to the agent.
- Deny — the call is blocked. Access is deny-by-default: a tool call only runs when policy explicitly permits it.
- Escalate — the call is paused for human approval before it can proceed.
Every one of these decisions is recorded in the immutable audit trail. See Governance & Policies for how policies are written and evaluated.
#Next steps
- Actions — The other side of the harness: structured, typed outputs an agent emits to drive downstream work.
- Governance & Policies — How allow, deny, and escalate decisions are evaluated for every tool call a connector serves.
- Connector SDK — Full reference for defineConnector, defineTool, resources, prompts, and required environment variables.