Skip to main content
Glama
AutomateIP

skills-mcp-server

by AutomateIP

skills-mcp-server

An MCP server, built with FastMCP, that serves a directory of SKILL.md-based "skills" over the network — as both MCP resources and MCP tools.

How it works

  • Resources come from FastMCP's built-in fastmcp.server.providers.skills.SkillsDirectoryProvider. It scans a root directory, and treats every subdirectory containing a SKILL.md file as one skill, exposing:

    • skill://{name}/SKILL.md — the skill's main file

    • skill://{name}/_manifest — a synthetic JSON file listing (path/size/hash) for the skill

    • skill://{name}/{relative/path} — every other file in the skill folder (e.g. references/*.md)

    This server configures the provider with supporting_files="resources", so every supporting file is individually listed by list_resources() up front (not hidden behind a lazy URI template) — good for upfront discoverability by clients that just call list_resources() once.

  • Tools (list_skills, get_skill) are hand-written on top of the same skills directory, since the provider only exposes resources, not tools. They parse full YAML frontmatter (interface: blocks, nested lists, etc.) rather than relying on the provider's internal simplified line-based frontmatter parser, so nested metadata (e.g. risk_level, confirmation_points) comes through correctly.

    • list_skills() → name, description, argument hint, risk level, and path for every skill.

    • get_skill(name) → full parsed frontmatter, the markdown body, and a list of that skill's supporting reference files.

  • Transport: streamable-HTTP (mcp.run(transport="http", ...)), since this is meant to run in a container and be reached by remote MCP clients rather than over stdio.

  • Skills directory is never baked into the image. The Dockerfile only ships the server code; the actual skills live on the host and are mounted as a read-only volume at container runtime (docker-compose.yml mounts them to /skills). Swap in a different skills directory by changing the compose volume mount or the SKILLS_DIR env var — no rebuild needed.

Related MCP server: Skillz

Configuration

All configuration is via environment variables (see .env.example):

Variable

Default

Meaning

SKILLS_DIR

/skills

Root directory to scan for skill folders

MCP_HOST

0.0.0.0

Host/interface the HTTP transport binds to

MCP_PORT

8010

Port the HTTP transport binds to

SKILLS_RELOAD

true

If true, re-scan the skills directory on every request. Default on since an external process (e.g. a cron job re-cloning a skills repo into the mounted volume) may mutate content behind the server's back. Set false for a static skills directory to skip re-scan overhead.

SKILLS_SUPPORTING_FILES

resources

resources (list every file upfront) or template (lazy URI template)

LOG_LEVEL

INFO

Standard Python logging level

A GET /health route is also registered for container/orchestrator liveness checks.

Local development quickstart

Requires Python 3.11+ and uv.

uv venv .venv
source .venv/bin/activate
uv pip install -e .

# Point at any skills directory you like — this repo bundles a minimal
# example under ./example-skills:
export SKILLS_DIR=./example-skills
skills-mcp-server
# -> Starting MCP server 'Skills MCP Server' with transport 'http' on http://0.0.0.0:8010/mcp

(pip install -e . in a plain venv works too, if you'd rather not use uv.)

Quick smoke test with the FastMCP client

import asyncio
from fastmcp import Client

async def main():
    async with Client("http://127.0.0.1:8010/mcp") as client:
        tools = await client.list_tools()
        print([t.name for t in tools])

        resources = await client.list_resources()
        print([str(r.uri) for r in resources])

        result = await client.call_tool("list_skills", {})
        print(result.data)

asyncio.run(main())

Or with curl against the health route:

curl http://127.0.0.1:8010/health
# {"status": "ok", "skills_dir": "./example-skills"}

Docker quickstart

docker compose up --build

This builds the image (server code only — no skills baked in), mounts the bundled ./example-skills directory from the repo to /skills inside the container read-only, and serves on http://localhost:8010/mcp. No configuration is required for this to work on a fresh clone.

Pointing at a different skills directory

Copy docker-compose.override.yml.example to docker-compose.override.yml (untracked — see .gitignore) and edit the path:

services:
  skills-mcp-server:
    volumes:
      - /path/to/your/skills:/skills:ro

Compose automatically merges docker-compose.override.yml over docker-compose.yml, so your own skills directory is used without editing the tracked file.

Or, if running the container directly instead of via compose:

docker run --rm -p 8010:8010 \
  -v /path/to/your/skills:/skills:ro \
  -e SKILLS_DIR=/skills \
  skills-mcp-server:local

Connecting an MCP client

Any MCP client that supports streamable-HTTP transport can connect directly to http://<host>:8010/mcp. Example generic client config:

{
  "mcpServers": {
    "skills": {
      "url": "http://localhost:8010/mcp",
      "transport": "http"
    }
  }
}

Project layout

skills-mcp-server/
├── pyproject.toml
├── Dockerfile
├── docker-compose.yml
├── docker-compose.override.yml.example  # template for pointing at your own skills dir
├── .env.example
├── .gitignore
├── LICENSE
├── README.md
├── example-skills/            # bundled fixture so the server works out of the box
│   └── hello-world/
│       ├── SKILL.md
│       └── references/
│           └── greeting-styles.md
└── src/skills_mcp_server/
    ├── __init__.py
    ├── config.py      # env-driven Settings
    ├── discovery.py    # full YAML frontmatter parsing for list_skills/get_skill
    ├── tools.py        # list_skills / get_skill MCP tool definitions
    └── server.py       # FastMCP app wiring, provider, health route, entrypoint

License

Apache License 2.0 — see LICENSE.

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Converts AI Skills (following Claude Skills format) into MCP server resources, enabling LLM applications to discover, access, and utilize self-contained skill directories through the Model Context Protocol. Provides tools to list available skills, retrieve skill details and content, and read supporting files with security protections.
    Last updated
    3
    27
    Apache 2.0
  • A
    license
    -
    quality
    B
    maintenance
    A minimal MCP server that resolves skill names to filesystem paths + metadata, enabling on-demand skill retrieval without loading full content into context.
    Last updated
    MIT

View all related MCP servers

Related MCP Connectors

  • MCP server for skill documentation, generated by doc2mcp.

  • Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.

  • Markdown-first MCP server for Notion API with 8 composite tools and 39 actions.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AutomateIP/skills-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server