# Skills

A **skill** is a packaged capability a Met can use: talking to an external
system, running a procedure, reading a data source. Instead of wiring every
integration by hand, you activate the skill and the Met already knows how to use it.

Use the `skills:read` and `skills:manage` scopes.

## The model in three pieces

| piece | what it is |
|---|---|
| **Catalog** | the skills available to your workspace — the system ones and the marketplace ones |
| **Activation** | the skill installed in your workspace, with its credentials and its state |
| **Link** | which Mets can use it. Activating it does not give it to all of them: it is linked per Met |

That third piece is the one most often missed. **Activating a skill does not make
your Mets use it** — it has to be linked. That is deliberate: it keeps a support
Met from inheriting the billing Met's capabilities.

## See what's there

```ts
const marketplace = await met.skills.marketplace();  // the marketplace ones
const system      = await met.skills.system();       // the ones Meteor ships
const active      = await met.skills.active();       // the ones you already have active
const everything  = await met.skills.all();
```

To find out which state each one is in:

```ts
const states = await met.skills.status();
// → [{ skill_id, active, configured, missing_credentials: [...] }, …]

const one = await met.skills.skillStatus('crm-hubspot');
```

`configured` is the one that matters before linking: a skill can be **active and
without credentials**, and in that case the Met sees it and fails when it uses it.

## Activate and configure

```ts
await met.skills.activate('crm-hubspot');

await met.skills.setCredentials('crm-hubspot', {
  api_key: process.env.HUBSPOT_KEY,
});
```

Credentials are **write-only**: they are stored encrypted and no API response
returns them, whole or masked. To know whether they are set you use `configured`
from the state; to change them, you send them again in full.

Before handing the skill to a Met, test it:

```ts
const check = await met.skills.test('crm-hubspot', { /* example payload */ });
```

`test` really does run the skill against the external system, so it spends
whatever that call spends. With a `met_test_` key you cannot run skills that have
external side effects — see [Authentication](authentication.html).

## Link it to a Met

```ts
await met.skills.linkToAgent(agentId, 'crm-hubspot');

const forThisMet = await met.skills.forAgent(agentId);   // what that Met sees

await met.skills.unlinkFromAgent(agentId, 'crm-hubspot');
```

Unlinking does **not** deactivate the skill or delete its credentials: it only
takes it away from that Met. To remove it from the workspace:

```ts
await met.skills.deactivate('crm-hubspot');   // keeps credentials
await met.skills.remove('crm-hubspot');       // takes it out of the workspace
```

Executions already in flight that were using the skill finish; the next ones stop
seeing it.

## Skills with MCP servers of their own

A skill can bring its own MCP servers, and you can control which ones stay
exposed:

```ts
const servers = await met.skills.mcps('crm-hubspot');

await met.skills.setMcps('crm-hubspot', { /* configuration */ });
await met.skills.updateMcp('crm-hubspot', mcpId, { /* changes */ });
await met.skills.removeMcp('crm-hubspot', mcpId);
```

Not to be confused with [MCP integrations](mcp-integrations.html), which are
connectors you register at the workspace level: the ones here come inside the
skill and live and die with it.

## When a skill, and when a standalone tool

- **Skill** — if the capability has credentials and several operations, and you
  want to switch it on or off as one unit.
- **[MCP integration](mcp-integrations.html)** — if you already have an MCP
  server and just want Meteor to use it.
- **[Function](functions-and-flows.html)** — if it is your own code and you want
  the Met to call it like an endpoint.

> The order you almost always want: `status` → `activate` → `setCredentials` →
> `test` → `linkToAgent`. Skipping `test` is the most common cause of a Met that
> "has the skill" and fails on first use.
