Skip to content

MCP Server

Connect AI agents to localskills.sh via the Model Context Protocol. Setup for Claude Code, claude.ai, Cursor, Codex CLI, Windsurf, VS Code, and other MCP clients.

Updated View as Markdown

localskills.sh provides a Model Context Protocol (MCP) server that lets AI agents discover, read, and author your teams’ skills without leaving their workflow. Any MCP client that supports Streamable HTTP with OAuth (Claude Code, claude.ai, Claude Desktop, Cursor, Codex CLI, Windsurf, VS Code, and others) can connect directly.

Server endpoint

The MCP server is available at:

https://localskills.sh/mcp/mcp

It uses the Streamable HTTP transport (stateless mode). Each request is independent; no session management is required.

Authentication

The MCP server requires OAuth 2.1. Unauthenticated requests receive a 401 with the standard WWW-Authenticate discovery hint, so well-behaved MCP clients handle the whole flow automatically: they register dynamically, open a browser authorization page, and receive a Bearer access token scoped to the MCP resource.

During authorization you pick which of your organizations the connection is for. The token is bound to that organization: the agent sees and writes only that org’s skills. To work with a different organization, re-authenticate and pick it (most clients have a “reconnect” or “log out” action per server).

The server supports these OAuth scopes:

Flag Description
skills:read Search skills and fetch their content (always granted)
skills:write Create skills and publish versions (optional; uncheck it on the consent screen for a read-only connection)
offline_access Refresh tokens, so the client stays connected without re-authorizing
openid / profile / email Basic identity for the consent screen

Discovery metadata lives at the standard well-known URLs:

https://localskills.sh/.well-known/oauth-authorization-server
https://localskills.sh/.well-known/oauth-protected-resource/mcp/mcp

Client setup

Point any MCP client’s Streamable HTTP transport at https://localskills.sh/mcp/mcp. The first connection triggers the browser OAuth flow. Verified setups for common environments:

Claude Code

Add the server via the CLI (global):

claude mcp add localskills --transport http https://localskills.sh/mcp/mcp

Or share it with your whole project by committing a .mcp.json at the repo root:

{
  "mcpServers": {
    "localskills": {
      "type": "http",
      "url": "https://localskills.sh/mcp/mcp"
    }
  }
}

Run /mcp inside a session to authenticate and inspect the connection.

claude.ai & Claude Desktop

Go to Settings → Connectors → Add custom connector and enter https://localskills.sh/mcp/mcp. Approve the OAuth prompt and the tools become available in chats (enable them from the search-and-tools menu). On Team/Enterprise plans an admin may need to add the connector first.

Cursor

Add to .cursor/mcp.json in your project (or ~/.cursor/mcp.json globally):

{
  "mcpServers": {
    "localskills": {
      "url": "https://localskills.sh/mcp/mcp"
    }
  }
}

Codex CLI

Add to ~/.codex/config.toml:

[mcp_servers.localskills]
url = "https://localskills.sh/mcp/mcp"

Then run codex mcp login localskills to complete the OAuth flow.

Windsurf

Add to ~/.codeium/windsurf/mcp_config.json (note the serverUrl key):

{
  "mcpServers": {
    "localskills": {
      "serverUrl": "https://localskills.sh/mcp/mcp"
    }
  }
}

VS Code (Copilot agent mode)

Add to .vscode/mcp.json in your workspace:

{
  "servers": {
    "localskills": {
      "type": "http",
      "url": "https://localskills.sh/mcp/mcp"
    }
  }
}

Cline

Add to ~/.cline/data/settings/cline_mcp_settings.json:

{
  "mcpServers": {
    "localskills": {
      "type": "streamableHttp",
      "url": "https://localskills.sh/mcp/mcp"
    }
  }
}

opencode

Add to opencode.json in your project (or ~/.config/opencode/opencode.json globally):

{
  "mcp": {
    "localskills": {
      "type": "remote",
      "url": "https://localskills.sh/mcp/mcp",
      "enabled": true
    }
  }
}

Available tools

The server exposes up to nine tools (create_upload_ticket registers only when UPLOAD_SIGN_SECRET is configured on the worker). Skill and folder read tools require the skills:read scope; whoami requires only an authenticated token, not a skills scope. Write tools require skills:write and are not registered at all on read-only connections.

whoami

Returns the identity behind the token: user id, email, granted scopes, and your teams (each with an id, slug, name, and role). When the token is bound to one organization, boundTeamId identifies it. Takes no arguments. Agents call it first to learn which team values to pass to the tools below.

search_skills

Search skills and rules visible to you. Returns matching skills with their slug, publicId, description, and current version; pass one to get_skill_content to load it. Use scope: "personal" to search only managed personal workspaces across your teams. The public catalog is not searchable over MCP.

Flag Description
query Search text to match against name, description, and tags
type Filter by “skill” or “rule”
tag Filter by a specific tag
team Limit to one of your teams (tenant slug or id, from whoami)
folder Limit to a folder subtree, e.g. “backend/database”; requires team
scope all (default readable union), team (requires team and excludes managed personal workspaces), mine (skills you created), or personal (your managed personal workspace subtrees)
limit Max results, 1–50 (default 20)

get_skill_content

Load a skill’s full content. Returns the SKILL.md body plus any additional package files: text files inlined up to a size budget, binaries listed as metadata with a signed downloadUrl (see bundled files). Multi-file packages also include a signed packageDownloadUrl for the whole zip.

Flag Description
slug The skill slug, or its publicId when the slug is ambiguous (required)
version Version: exact semver (1.2.3), range (^1.0.0), or integer

get_skill_file

Fetch one file from a skill’s package by path (for binary files that get_skill_content lists as metadata only). Returns the bytes as base64 (chunked, 32 KiB by default, up to 1 MiB per call) plus a signed downloadUrl that streams the whole file in one HTTP GET. Includes a SHA-256 checksum when the file is returned whole.

Flag Description
slug The skill slug, or its publicId (required)
path File path inside the package, as listed by get_skill_content (required)
version Version: exact semver, range, or integer
offset Byte offset for chunked reads (default 0)
length Max bytes to return (default 32 KiB, hard cap 1 MiB)

list_folders

Browse a team’s folder tree (only paths you can read). Pass a returned path as the folder argument to search_skills to scope a search.

Flag Description
team Tenant slug or id, from whoami or search results (required)

get_folder_access

Who can read a folder: every team member with access, resolved live from the folder ACLs (direct grants, team grants, and admin-bypass roles), plus the underlying grant list. Open folders report all members as access: "open". Readable by anyone who can read the folder; editing ACLs stays on the website.

Flag Description
team Tenant slug or id, from whoami or search results (required)
folder Folder path (e.g. “individual/jane-doe”) or folder ID (required)

create_skill

Create a new skill. Requires the skills:write scope and skill-creation permission in the target organization. Idempotent on content: retrying an identical create after a lost response returns the existing skill with idempotent: true instead of creating a duplicate.

Flag Description
name Skill name, 1–100 characters (required)
content The root SKILL.md body in markdown (required unless uploadId is passed)
files Supporting package files [{ path, content, encoding? }]; utf8 by default, base64 for binaries; max 100 files / 10 MB per call
uploadId Commit a package staged via create_upload_ticket (up to 100 MB); mutually exclusive with content/files
tenantId Team ID to create the skill under (required)
type “skill” or “rule” (default: skill)
visibility “public”, “private”, or “unlisted” (default: private)
tags Up to 10 tags
description Short description
folder Existing folder path (e.g. “backend/database”) or folder ID (default: tenant root)
onConflict “suffix” (default) auto-renames the slug when the name is taken; “error” fails with E_CONFLICT naming the existing skill instead of creating a renamed sibling

create_upload_ticket

Stage a full-size package (up to 100 MB / 500 files) when the inline files cap is too small. Returns a fileUrlTemplate (PUT each raw file, substituting {path} URL-encoded per segment), a finalizeUrl (POST once all files are uploaded; the server assembles the canonical deterministic zip), and the uploadId to pass to create_skill / publish_version. Requires HTTP egress and the skills:write scope; no parameters. Clients never build zip archives; packaging is server-side.

publish_version

Publish a new version of an existing skill. Requires the skills:write scope. Auto-bumps the patch version by default, or you can specify an explicit semver or bump type. Idempotent on content: publishing bytes identical to the current version (without a higher explicit semver) returns the current version with idempotent: true.

Flag Description
slug Skill slug (required)
content The new root SKILL.md body for this version (required unless uploadId is passed)
files Supporting package files [{ path, content, encoding? }]; utf8 by default, base64 for binaries; max 100 files / 10 MB per call
uploadId Commit a package staged via create_upload_ticket (up to 100 MB); mutually exclusive with content/files
semver Explicit semver (must be greater than current)
bump Auto-bump: “major”, “minor”, or “patch” (default: patch)
message Version message / changelog

Resources

The server also provides MCP resources for browsing skills:

localskills://skills: Lists all skills your token can read, with metadata (slug, name, description, type, semver).

localskills://skills/{slug}: Returns the SKILL.md content of one skill. Agents can browse the list, then read individual skills to inject content into their context.

localskills://skills/{slug}/files/{path}: Reads one file from a skill’s package (current version). Binary files come back as base64 blob contents; files over 1 MiB must be fetched with get_skill_file instead.

Bundled files & signed downloads

Skills are packages: a root SKILL.md plus optional supporting files (scripts, templates, binary assets). Agents have two ways to materialize those files:

Signed download URLs: get_skill_content and get_skill_file include a downloadUrl on every non-inlined file (and a packageDownloadUrl for the whole zip). These are HMAC-signed URLs, valid for 1 hour, minted only after the caller’s access checks pass. One curl -o file '<url>' streams the file at any size without passing bytes through model context. It’s the best path whenever the agent’s sandbox has HTTP egress.

Inline base64: the guaranteed fallback for sandboxes without network access (MCP calls ride the client’s connection, so they always work). Call get_skill_file repeatedly, advancing offset by bytesReturned until eof, then concatenate and decode the chunks.

Error handling

Tool failures set isError and carry a machine-readable code in structuredContent.error.code:

Flag Description
E_NOT_FOUND No such skill, team, folder, or file (or no access to it)
E_AMBIGUOUS Slug matches several skills; retry with the publicId
E_ACCESS_DENIED Authenticated but not allowed (missing membership or folder grant)
E_INVALID_INPUT Bad arguments, e.g. folder without team

Dynamic skill loading

Agents can discover and load skills on the fly during a conversation. When an agent encounters a task it doesn’t have instructions for, it can search your team’s library, pull in the relevant skill, and continue without interruption.

Example workflow: an agent is asked to write a Next.js API route. It searches for relevant skills, finds one with best practices, and injects it into context:

// 1. Agent calls search_skills
search_skills({ query: "next.js api routes", type: "skill", limit: 5 })

// 2. Agent picks the best match and fetches its content
get_skill_content({ slug: "nextjs-api-patterns" })

// 3. The skill content is now in the agent's context
//    and it follows the instructions while writing code

Because MCP tools are native to the agent’s runtime, this happens seamlessly. The agent decides when to search, what to load, and how to apply the instructions, with no manual intervention.

Loading skills on boot

To load skills from localskills.sh automatically when a session starts, add instructions to your project’s agent configuration file: AGENTS.md, CLAUDE.md, .cursorrules, or equivalent.

CLAUDE.md example: add this to your project’s CLAUDE.md so Claude Code loads skills at the start of every session:

# Skills

At the start of each session, use the localskills MCP server to load
the following skills into context:

- `nextjs-api-patterns`: Follow these patterns for all API routes
- `drizzle-d1-guide`: Reference for database queries
- `testing-conventions`: Standards for writing tests

To load a skill, call get_skill_content with the slug above.
If you need additional skills for a task, search localskills.sh first.

AGENTS.md example: for multi-agent setups, scope skills to specific agent roles:

# Agent Skills

## All agents
Load these skills from localskills.sh via MCP at session start:
- `code-review-checklist`: Apply during all code reviews
- `security-rules`: Enforce on every change

## Frontend agent
Additionally load:
- `react-component-patterns`: Component architecture guidelines
- `tailwind-conventions`: Styling standards

## Backend agent
Additionally load:
- `api-design-guide`: REST API conventions
- `error-handling-patterns`: Error handling standards

.cursorrules example: add MCP skill loading to your Cursor project rules:

You have access to the localskills MCP server.
At the start of each conversation, load these skills:

1. Call get_skill_content({ slug: "react-component-patterns" })
2. Call get_skill_content({ slug: "typescript-strict-mode" })

Follow the loaded skill instructions for all code you write.
When asked about an unfamiliar topic, search localskills.sh
for relevant skills before answering.

This pattern gives teams shared coding standards and guidelines that every agent session picks up automatically. Update a skill on localskills.sh and every agent gets the latest version on its next session (no reinstall needed).

Permissions & access

MCP requests act as the user who authorized the connection, within the organization chosen during authorization. The server surfaces only your teams’ skills; the public catalog is browsable on the website and REST API, not over MCP. Folder restrictions apply exactly as they do in the dashboard: skills in folders you have no grant for don’t appear in search, resources, or reads. Writes (create_skill, publish_version) additionally require the corresponding skill permissions in the target organization.

Revoking access works as you’d expect: leave (or be removed from) an organization and existing tokens bound to it stop returning its skills immediately.

Health check

Verify the server is running:

curl https://localskills.sh/mcp/health

Returns {"status":"ok"} when healthy.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close