# Mets and their tools

A **Met** is an agent in your workspace: it has a mission, instructions, AI Functions, skills and access to the workspace's data (collections and contacts). With `met.agents` you create and adjust them from code; with tool introspection you know exactly what each one sees.

## Create and adjust Mets

```ts
import Met from '@meteor.ia/sdk';

const met = new Met(process.env.MET_API_KEY!, { workspaceId: 40 });

const agent = await met.agents.create({
  name: 'Valeria',
  title: 'Sales advisor',
  mission: 'Qualify and answer inbound leads',
  instructions: 'Be concise. Confirm the budget before booking.',
});

await met.agents.list();          // every Met in the workspace
await met.agents.retrieve(agent.id);
await met.agents.update(agent.id, { instructions: 'New script.', active: true });
```

The editable fields are `name`, `title`, `mission`, `instructions` and `active`. To give it a workspace skill: `met.agents.linkSkill(agentId, skillId)` (and `unlinkSkill` to take it away).

## See which tools a Met has

This is diagnosis #1 when a Function doesn't surface, or when you don't know what to switch off:

```ts
const tools = await met.agents.tools(agent.id);
// [{ name, source: 'collection'|'skill'|'function'|'internal', description, disabled }]
```

Each tool carries its `source` (where it comes from) and `disabled` (whether it is already off for this Met). If your Function doesn't show up with `source: 'function'`, the problem is in the Function itself — no handler, `active: false` — not in the Met. The names this method returns are the **only valid ones** for `disabled_tools`.

## Switch tools off per Met

```ts
await met.agents.update(agent.id, {
  disabled_tools: ['mcp_meteor_list_items', 'mcp_meteor_get_item'],
});
```

Disabling a tool does not unlink it: it leaves it out of the set the LLM can call (hidden from the catalog and rejected at runtime). Take the names from `agents.tools()`.

> The `mcp_meteor_*` tools (source `internal`) are **generic**: they operate over every collection in the workspace, not over a single one. If you switch off `mcp_meteor_list_items`, you take it away from the Met for **all** collections at once. To close off one specific collection, use `expose_to_agent` (below).

## Hide a collection from the Met

So that no path — API, chat or channel — exposes a collection to the LLM, mark it as not visible, without deleting any data:

```ts
await met.collections.update(collectionId, { expose_to_agent: false });
```

`expose_to_agent` defaults to `true`. Set it to `false` for internal data the Met should not consult, and back to `true` to re-expose it. More in [Collections and items](collections-and-items.html).

> Which Met answers a run is decided by deterministic routing (the `met` bind), not by these tools. See [Run Mets](run-mets.html).

## Example: leave a Met with only its Function

```ts
const bot = await met.agents.create({ name: 'Quoter', mission: 'Quote over the API' });

// 1. Look at what it has available
const tools = await met.agents.tools(bot.id);

// 2. Switch off everything internal (generic collections) and let only its Function through
const internal = tools.filter((t) => t.source === 'internal').map((t) => t.name);
await met.agents.update(bot.id, { disabled_tools: internal });

// 3. Also close off a sensitive collection on every path
await met.collections.update(internalPricesId, { expose_to_agent: false });
```

The Met is now scoped to its AI Function, with no indiscriminate access to the workspace's collections.
