# MCP Tools Reference

> Markdown variant of <https://www.skillzdrive.com/docs/reference/tools>.

The MCP server exposes a single namespace of tools, all prefixed
`skills_`. Tools are gated by auth and by whether the caller's
filtered skill set contains any executable scripts —
script-execution tools are omitted from `tools/list` when no allowed
skill has a script.

Auth tiers (the bearer presented to the MCP endpoint):

- **anonymous** — no key; only available when the server is started with `REQUIRE_API_KEY=false` (development).
- **authenticated** — any valid `sk_live_*` API key. Most tools.
- **scoped** — same as authenticated but the key has a non-null `allowed_skill_ids` (a "collection"). Some management tools reject scoped keys.
- **upload-only keys** — rejected by the MCP transport entirely.

There is no admin-tier MCP tool. Admin endpoints
(`/admin/reload-skills`, `/admin/apply-skill-deltas`,
`/admin/invalidate-auth-cache`, `/admin/debug-skills`) live on the
HTTP transport and require the `MCP_ADMIN_SECRET` header.

## Error response shape

Every error response includes structured fields:

```json
{
  "error": "skill_not_found",
  "message": "No skill with slug 'pdff'",
  "suggestions": ["Did you mean 'pdf'?", "Use skills_searchSkills to find skills"],
  "_workflow": {
    "nextSteps": [
      { "tool": "skills_searchSkills", "example": { "query": "pdf" } }
    ]
  }
}
```

- `error` — machine-readable code (e.g. `skill_not_found`, `script_not_found`, `access_denied`, `session_not_found`, `missing_credentials`, `quota_exceeded`).
- `message` — human-readable text. Show this to users.
- `suggestions` — array of recovery steps. Show the first one as an action.
- `_workflow.nextSteps` — what tool to call next for automatic recovery.

## Discovery

### `skills_getStarted`

Render the SkillzDrive welcome overview for the session. Returns
credits, current collection, trending skills, and quick actions.
Recommended as the first tool call.

- Auth: authenticated. Inputs: none.

### `skills_searchSkills`

Search skills by name, description, or tags within the caller's
allowed set.

- Auth: authenticated.
- Required: `query: string`.
- Optional: `limit: number` (default 10, max 50), `collectionName: string`.

### `skills_listSkills`

List all skills available to the caller with metadata (slug, name,
description, tags, `hasScripts`).

- Auth: authenticated.
- Optional: `tags: string[]`, `query: string`, `collectionName: string`.

### `skills_getSkill`

Single-skill lookup by slug. Honors `allowed_skill_ids` scope;
returns `not_found` when the slug isn't accessible to the caller.

- Auth: authenticated. Required: `slug: string`.

### `skills_getLeaderboard`

Top 10 public/premium skills over the last 30 days.

- Auth: authenticated.
- Optional: `sort_by: 'executions' | 'installs' | 'rating'` (default `executions`).

### `skills_discoverSkills`

Search the marketplace **and** the GitHub skill catalog. Each
result carries a `source: "marketplace" | "github"` field.
Paginated 10 per page.

- Auth: authenticated. Required: `keywords: string`.
- Optional: `offset: number` (default 0).

## Drive management

### `skills_importToDrive`

Import a skill (marketplace or GitHub) into the caller's drive.
Triggers download → security scan → doc enrichment. Charges import
credits. Long-running (1–2 min).

- Auth: authenticated. Required: `skillSlug: string`.

### `skills_removeFromDrive`

Remove a skill from the drive; rejects active shares and deletes
private copies.

- Auth: authenticated. Required: `skillSlug: string`.

### `skills_toggleDriveSkill`

Toggle a skill's `enabled` flag in `user_skill_lockers`.

- Auth: authenticated. Required: `skillSlug: string`.

### `skills_checkUpdates`

List pending skill updates with security-scan summaries.

- Auth: authenticated. Inputs: none.

### `skills_acceptUpdate`

Accept a pending update; pins the drive entry to the latest
version. Charges a small credit fee.

- Auth: authenticated. Required: `skillSlug: string`.

### `skills_dismissUpdate`

Dismiss a pending update; the drive entry stays on its current
pinned version. Free.

- Auth: authenticated. Required: `skillSlug: string`.

### `skills_downloadSkills`

Package skills as a zip and return a 24-hour signed Supabase URL.

- Auth: authenticated.
- Required: `scope: 'drive' | 'collection' | 'skill'`.
- Conditional: `collectionName` (when `scope='collection'`), `skillSlug` (when `scope='skill'`).

## Collections

A "collection" is a named, scoped API key. Both unscoped and scoped
callers can read collections; mutating tools generally require an
unscoped (all-skills) key.

### `skills_createCollection`

Mint a new scoped API key. Returns the `sk_live_*` once.

- Auth: authenticated, **unscoped only**.
- Required: `name: string`.
- Optional: `skillSlugs: string[]` (omit for all-skills), `includeTeamSkills: boolean` (default true), `includeSharedSkills: boolean` (default true).

### `skills_listCollections`

List collections owned by the account.

- Auth: authenticated, **unscoped only** (scoped keys get a permission error). Inputs: none.

### `skills_updateCollection`

Rename or toggle team/shared inclusion flags.

- Auth: authenticated, **unscoped only**.
- Required: `collectionName: string` (name or `sk_live_*`).
- Optional: `newName: string`, `includeTeamSkills: boolean`, `includeSharedSkills: boolean`.

### `skills_deleteCollection`

Delete a collection and revoke its API key. Irreversible.

- Auth: authenticated, **unscoped only** (scoped keys cannot delete, including their own).
- Required: `collectionName: string`.

### `skills_addToCollection`

Add a skill to a scoped collection. Single slug, not array.

- Auth: authenticated. Scoped keys operate on their own collection (the `collectionName` arg is ignored); unscoped callers must specify it.
- Required: `skillSlug: string`.
- Optional: `collectionName: string` (required for unscoped).

### `skills_removeFromCollection`

Remove a skill from a scoped collection. Same scoped/unscoped rules
as `addToCollection`.

- Auth: authenticated. Required: `skillSlug: string`.
- Optional: `collectionName: string`.

## Documentation

### `skills_docTOC`

Get the full table of contents for a skill's documentation.

- Auth: authenticated. Required: `skillSlug: string`.

### `skills_docSection`

Get the body of a specific documentation section.

- Auth: authenticated. Required: `skillSlug: string`, `sectionSlug: string`.

### `skills_getResourceInfo`

Metadata for a skill resource file (sections, token counts, type).

- Auth: authenticated. Required: `skillSlug: string`, `filePath: string`.

### `skills_readResourceContent`

Read a resource file's content (full or by section name). Blocked
for premium skills.

- Auth: authenticated. Required: `skillSlug: string`, `filePath: string`.
- Optional: `sectionName: string`.

## Scripts

These tools are only listed by `tools/list` if the caller has at
least one allowed skill with scripts.

### `skills_listScripts`

List executable scripts for one skill. **MUST call before `runScript`.**

- Auth: authenticated. Required: `skillSlug: string`.

### `skills_runScript`

Execute a script in an isolated E2B sandbox. Output is **not**
returned inline — read it via `skills_readFile`.

- Auth: authenticated.
- Required: `skillSlug: string`, `scriptName: string`.
- Optional: `args: string[]`, `stdin: string`, `sessionId: string`, `reuseSession: boolean` (default false; **always pass true** to enable readFile).

### `skills_readFile`

Read a file from an active session sandbox. Pass `closeAfter: true`
on the final read to release the session in the same call.

- Auth: authenticated. Required: `sessionId: string`, `filePath: string`.
- Optional: `startLine: number` (default 1), `limit: number` (default 200, max 500), `closeAfter: boolean` (default false).

### `skills_listOutputFiles`

List files in a sandbox directory.

- Auth: authenticated. Required: `sessionId: string`.
- Optional: `directory: string` (default `/tmp`), `closeAfter: boolean`.

### `skills_closeSession`

Close a session and free its sandbox. Sessions auto-expire after 5
minutes of inactivity.

- Auth: authenticated. Required: `sessionId: string`.

### `skills_getScript`

Return script metadata + a direct-storage signed download URL for
local execution.

- Auth: authenticated. Required: `skillSlug: string`, `scriptName: string`.

### `skills_getScriptStream`

Return script metadata + the script content **inline** in the tool
response (chunked). Used as a fallback when `skills_getScript`'s
download URL can't be fetched (sandboxed agents, large scripts).

- Auth: authenticated. Required: `skillSlug: string`, `scriptName: string`.

## Upload

### `skills_getUploadUrl`

Return the SkillzDrive website upload URL preconfigured for **this**
caller (embeds `key_id`/`key_name` so scoped keys land in the
caller's collection).

- Auth: authenticated. Inputs: none.

### `skills_createUploadTicket`

Mint a 10-minute single-use bearer token for the
`upload-to-skillzdrive` skill's `send-file.sh`. Response includes a
`websiteFallbackUrl` for environments that can't run a local script.

- Auth: authenticated. Scoped callers are locked to their own collection.
- Optional: `filename: string`, `collectionName: string` (unscoped callers only).

## Billing

### `skills_getCredits`

Current credit balance, monthly skill-call counter + tier limit,
and recent credit transactions.

- Auth: authenticated. Inputs: none.

### `skills_listWebhooks`

List the account's credit-alert webhook subscriptions.

- Auth: authenticated. Inputs: none.

### `skills_createWebhook`

Subscribe a URL to credit-alert webhooks. Returns the subscription
`id` + `secret` once (HMAC-SHA256 signing key for delivery
verification).

- Auth: authenticated.
- Required: `event_type: 'credits.threshold_hit' | 'credits.exhausted'`, `target_url: string` (HTTPS).
- Conditional: `threshold_value: number` (required for `credits.threshold_hit`).

### `skills_deleteWebhook`

Delete a webhook subscription.

- Auth: authenticated. Required: `id: string`.

## Quick reference: the Golden Path

```
listScripts → runScript(reuseSession: true) → readFile → closeSession
```

Output is in `/tmp/last_run.out` (stdout) and `/tmp/last_run.err`
(stderr). On `session_not_found`, re-run with `reuseSession: true`
to get a fresh sandbox.
