Skilder is a versioned, governed library for your team's agent capabilities: skills composed with the MCP tools they need, published deliberately, distributed to every connected agent from one endpoint.
It picks up where prototypes end: skill copies drifting across repos, live edits changing agent behavior mid-task, tool lists overflowing the context window, no answer to "what did the agent actually do?"
With this connector, Claude can:
• Learn skills on demand: instructions, files, and tools unlock together, exactly when a task needs them
• Execute each skill's tools through server-partitioned read and write channels, under each user's own identity
• Run skill scripts (Python, TypeScript, shell) sandboxed on your runtimes
• Report friction on skills as it works, so you catch decay before users do
• Build new capabilities in conversation (workspace admins): discover available tools, then create, compose, and update skills and roles
Lifecycle is engineered in: drafts, publishing, version history, rollback. Agents only see the published state, so you can iterate on a skill while it runs in production.
Usage is measured per skill: what runs, what fails, what sits unused. Admins curate which tools are exposed, and every session leaves an auditable timeline.
Skills use the open Agent Skills format: import existing folders as-is from GitHub or ZIP. Everything stays portable.
Setup takes five minutes: connect, sign in or sign up in the consent flow, and a demo workspace is provisioned. Then bring your own skills.
Protocol
MCP 2026-07-28
Server version
1.0.0
Supports
Tools
Resources
Prompts
Completions
Overall score
B
Overall quality score: 80 out of 10080/100
Server metadata
4 of 8 fields50/1004 / 8 pts
Identity, discovery, and usage metadata advertised during the MCP handshake.
init_skilder lists the roles, skills, and tools this Skilder workspace provides. It returns a session id that every other Skilder tool requires in its `sessionId` argument; until `init_skilder` has been called, those tools return an error.
Protocol
Pass100/10016 / 16 pts
Connection, authentication, and protocol compatibility.
Tool definitions, annotations, and client compatibility.
Skills over MCP resources are readable
Server does not advertise the Skills over MCP extension
All tools have descriptions
All tools have non-empty descriptions
All tools have OpenAI behavior hints
5 behavior annotation issue(s) found
How to fix: On each tool, declare annotations.readOnlyHint, annotations.destructiveHint, and annotations.openWorldHint as booleans. The policy review separately assesses whether their values match the tool's actual behavior.
How to fix: For tools that render a UI resource, add openai/toolInvocation with string fields invoking and invoked (present-tense labels shown while the tool runs and after it finishes, e.g. "Searching…" / "Searched").
All view resources are readable and use ui:// with a supported MCP Apps HTML MIME type
Declared domains respond
All declared domains are reachable
View resource metadata complete
4 resource(s) have incomplete metadata
How to fix: Use a ui:// URI and text/html;profile=mcp-app. For mcp-use v1, use widgetMetadata.metadata.widgetDescription; for v2, use the bound tool's view.description. The current description check reads _meta.ui.widgetDescription or _meta["openai/widgetDescription"] on resource contents or linked tools, not resource.description. Consequently, v2 view.description alone may leave this warning: report the checker compatibility gap instead of adding unsupported v1 fields or claiming the warning is fixed.
How to fix: For ChatGPT submission, set one exact HTTPS origin such as "https://app.example.com" on every view via _meta.ui.domain (or openai/widgetDomain). Paths are not valid and all views in one app must share the origin.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Initializes a Skilder session and lists the available roles, skills, and the tools they unlock. Required before any other Skilder tool — they return an error while no session is initialized. The response includes a session id: subsequent Skilder tool calls require it in their `sessionId` argument and return an error without it. Accepts an optional agent-authored task summary — one sentence, never the user's verbatim message — that labels the session and steers which role Skilder suggests.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
task_summary
One sentence, written by you, naming the kind of work the user is asking for. Summarise their request rather than repeating it, and keep the vocabulary that places it — the tools, artefacts and terms of the field involved — since Skilder matches the wording against role and skill names.
Clear enough to supply this argument.
sessionId
Optional: a previously-issued Skilder session id (sks-…) to resume that session — session ids do not expire. Omit to start a new one.
Clear enough to supply this argument.
Annotations75/100
Declare destructiveHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "init_skilder",
"title": "Initialize Skilder",
"description": "Initializes a Skilder session and lists the available roles, skills, and the tools they unlock. Required before any other Skilder tool — they return an error while no session is initialized. The response includes a session id: subsequent Skilder tool calls require it in their `sessionId` argument and return an error without it. Accepts an optional agent-authored task summary — one sentence, never the user's verbatim message — that labels the session and steers which role Skilder suggests.",
"inputSchema": {
"type": "object",
"required": [],
"properties": {
"sessionId": {
"type": "string",
"description": "Optional: a previously-issued Skilder session id (sks-…) to resume that session — session ids do not expire. Omit to start a new one."
},
"task_summary": {
"type": "string",
"description": "One sentence, written by you, naming the kind of work the user is asking for. Summarise their request rather than repeating it, and keep the vocabulary that places it — the tools, artefacts and terms of the field involved — since Skilder matches the wording against role and skill names."
}
}
},
"annotations": {
"title": "Initialize Skilder",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description83/100
Access roles, skills, and resources using path-based navigation. Roles are the entry point: init_skilder lists the available roles — learn one to unlock its skills and their tools. Always provide a full path with a role or skill name — "/" alone is not a valid path.
Path formats (the leading "/" is optional):
- `roles/Role Name` - Learn a role and all its skills at once (start here — init_skilder lists the roles)
- `Skill Name` or `/Skill Name` - Revisit a single skill from a learned role to get its instructions and tools again
- `Skill Name/document.md` - Get a specific resource from a skill
Examples:
- `learn(path="roles/Developer")` - Learn all skills in the Developer role
- `learn(path="Data Processing")` - Revisit the Data Processing skill
- `learn(path="Data Processing/readme.md")` - Get the readme resource
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Input documentation gives an agent enough context to populate the arguments.
path
Path to the resource (role, skill, or resource). Use /roles/Role Name for roles, /Skill Name for skills, or /Skill Name/name.md for resources.
Clear enough to supply this argument.
sessionId
Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call.
Clear enough to supply this argument.
Annotations75/100
Declare destructiveHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "learn",
"title": "Learn Skills & Access References",
"description": "Access roles, skills, and resources using path-based navigation. Roles are the entry point: init_skilder lists the available roles — learn one to unlock its skills and their tools. Always provide a full path with a role or skill name — \"/\" alone is not a valid path.\n\nPath formats (the leading \"/\" is optional):\n- `roles/Role Name` - Learn a role and all its skills at once (start here — init_skilder lists the roles)\n- `Skill Name` or `/Skill Name` - Revisit a single skill from a learned role to get its instructions and tools again\n- `Skill Name/document.md` - Get a specific resource from a skill\n\nExamples:\n- `learn(path=\"roles/Developer\")` - Learn all skills in the Developer role\n- `learn(path=\"Data Processing\")` - Revisit the Data Processing skill\n- `learn(path=\"Data Processing/readme.md\")` - Get the readme resource",
"inputSchema": {
"type": "object",
"required": [
"path",
"sessionId"
],
"properties": {
"path": {
"type": "string",
"description": "Path to the resource (role, skill, or resource). Use /roles/Role Name for roles, /Skill Name for skills, or /Skill Name/name.md for resources."
},
"sessionId": {
"type": "string",
"description": "Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call."
}
}
},
"annotations": {
"title": "Learn Skills & Access References",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description88/100
Execute a script from a skill with optional CLI-style arguments.
Path format: `/Skill Name/script.py [args]`
Examples:
- `execute_script(path="/Data Processing/transform.py")`
- `execute_script(path="/Data Processing/transform.py --input data.csv --output result.json")`
- `execute_script(path="/Automation/deploy.sh --env staging")`
Scripts run on their linked runtime.
Files: pass an `@skilder-file:/<fileId>/<name>` path from `upload_skilder_file`, `learn` or another tool, or an `@skilder-asset:` path, as a whole argument or as `--name=<path>`, unchanged and in double quotes if it contains a space or an apostrophe — the script receives a local path to a fresh copy of the file. A `@skilder-file:/<fileId>/<name>` path does not expire, while an `@skilder-asset:` path changes when its skill is published; any other `@skilder-file:` path is refused. Files the script returns come back as `@skilder-file:/<fileId>/<name>` paths kept in the workspace, which any later call can take; fetch one with `read_skilder_file`.
Describe the returned information so the agent knows whether it will answer the request.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
path
Path to the script including optional arguments. Format: /Skill Name/script.py [--arg value ...]
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
sessionId
Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "execute_script",
"title": "Execute Script",
"description": "Execute a script from a skill with optional CLI-style arguments.\n\nPath format: `/Skill Name/script.py [args]`\n\nExamples:\n- `execute_script(path=\"/Data Processing/transform.py\")`\n- `execute_script(path=\"/Data Processing/transform.py --input data.csv --output result.json\")`\n- `execute_script(path=\"/Automation/deploy.sh --env staging\")`\n\nScripts run on their linked runtime.\n\nFiles: pass an `@skilder-file:/<fileId>/<name>` path from `upload_skilder_file`, `learn` or another tool, or an `@skilder-asset:` path, as a whole argument or as `--name=<path>`, unchanged and in double quotes if it contains a space or an apostrophe — the script receives a local path to a fresh copy of the file. A `@skilder-file:/<fileId>/<name>` path does not expire, while an `@skilder-asset:` path changes when its skill is published; any other `@skilder-file:` path is refused. Files the script returns come back as `@skilder-file:/<fileId>/<name>` paths kept in the workspace, which any later call can take; fetch one with `read_skilder_file`.",
"inputSchema": {
"type": "object",
"required": [
"path",
"sessionId"
],
"properties": {
"path": {
"type": "string",
"description": "Path to the script including optional arguments. Format: /Skill Name/script.py [--arg value ...]"
},
"sessionId": {
"type": "string",
"description": "Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call."
}
}
},
"annotations": {
"title": "Execute Script",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description92/100
Report feedback about a skill or tool; it is recorded in the workspace activity trace for the skill's author. Useful when: (1) a skill/tool call fails or blocks the task, (2) the user re-asks for the same outcome shortly after a skill attempt, (3) the user explicitly corrects you about a skill/tool's behavior, or (4) you notice a concrete, specific defect yourself (e.g. instructions that were ambiguous and caused a wrong first attempt, a schema mismatch, information you had to guess at). Not intended for successful completions or vague quality opinions. Keep the feedback concise (1-3 sentences) and concrete: what was attempted, what actually happened vs. expected, and — if evident — the likely cause.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Explain the meaning of this value, not just its name.
skill_name
Name of the skill (optional)
Explain the meaning of this value, not just its name.
tool_name
Name of a specific tool (optional)
Clear enough to supply this argument.
feedback
Constructive feedback about the skill or tool
Explain the meaning of this value, not just its name.
sessionId
Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "feedback_skill",
"title": "Report Skill Feedback",
"description": "Report feedback about a skill or tool; it is recorded in the workspace activity trace for the skill's author. Useful when: (1) a skill/tool call fails or blocks the task, (2) the user re-asks for the same outcome shortly after a skill attempt, (3) the user explicitly corrects you about a skill/tool's behavior, or (4) you notice a concrete, specific defect yourself (e.g. instructions that were ambiguous and caused a wrong first attempt, a schema mismatch, information you had to guess at). Not intended for successful completions or vague quality opinions. Keep the feedback concise (1-3 sentences) and concrete: what was attempted, what actually happened vs. expected, and — if evident — the likely cause.",
"inputSchema": {
"type": "object",
"required": [
"feedback",
"sessionId"
],
"properties": {
"feedback": {
"type": "string",
"description": "Constructive feedback about the skill or tool"
},
"sessionId": {
"type": "string",
"description": "Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call."
},
"tool_name": {
"type": "string",
"description": "Name of a specific tool (optional)"
},
"skill_name": {
"type": "string",
"description": "Name of the skill (optional)"
}
}
},
"annotations": {
"title": "Report Skill Feedback",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description82/100
Execute a read-only tool unlocked by learning a skill. Only tools whose upstream server declares them read-only are served here; write-capable tools return an error naming run_write_tool. Use the tool_name exactly as provided when you learned the skill, and pass the arguments as a JSON object matching the tool's input schema.
The description explains the capability, when to use it, and what to expect.
Inputs83/100
Explain the meaning of this value, not just its name.
tool_name
The exact name of the tool to call
Clear enough to supply this argument.
tool_input
The input arguments for the tool
Explain the meaning of this value, not just its name.
sessionId
Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call.
Clear enough to supply this argument.
Annotations75/100
Declare destructiveHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "run_read_tool",
"title": "Run Read-Only Tool",
"description": "Execute a read-only tool unlocked by learning a skill. Only tools whose upstream server declares them read-only are served here; write-capable tools return an error naming run_write_tool. Use the tool_name exactly as provided when you learned the skill, and pass the arguments as a JSON object matching the tool's input schema.",
"inputSchema": {
"type": "object",
"required": [
"tool_name",
"tool_input",
"sessionId"
],
"properties": {
"sessionId": {
"type": "string",
"description": "Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call."
},
"tool_name": {
"type": "string",
"description": "The exact name of the tool to call"
},
"tool_input": {
"type": "object",
"description": "The input arguments for the tool",
"additionalProperties": true
}
}
},
"annotations": {
"title": "Run Read-Only Tool",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description71/100
Execute a write-capable tool unlocked by learning a skill (any tool not declared read-only by its upstream server; read-only tools return an error naming run_read_tool). Use the tool_name exactly as provided when you learned the skill, and pass the arguments as a JSON object matching the tool's input schema.
Explain mutations, irreversible effects, or prerequisites that matter before calling this tool.
Inputs84/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
tool_name
The exact name of the tool to call
Clear enough to supply this argument.
tool_input
The input arguments for the tool
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
sessionId
Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "run_write_tool",
"title": "Run Write Tool",
"description": "Execute a write-capable tool unlocked by learning a skill (any tool not declared read-only by its upstream server; read-only tools return an error naming run_read_tool). Use the tool_name exactly as provided when you learned the skill, and pass the arguments as a JSON object matching the tool's input schema.",
"inputSchema": {
"type": "object",
"required": [
"tool_name",
"tool_input",
"sessionId"
],
"properties": {
"sessionId": {
"type": "string",
"description": "Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call."
},
"tool_name": {
"type": "string",
"description": "The exact name of the tool to call"
},
"tool_input": {
"type": "object",
"description": "The input arguments for the tool",
"additionalProperties": true
}
}
},
"annotations": {
"title": "Run Write Tool",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Get a short-lived signed download URL for a Skilder-managed file. Use this to pull the file's actual bytes somewhere — e.g. onto your own local disk/repo checkout, or into another tool that needs a real file rather than a path — for a file another tool (e.g. a screenshot tool) already produced at a `@skilder-file:` or `@skilder-asset:` path.
Always returns two content blocks, regardless of file type (image, text, or other binary):
- A `resource_link` block with the signed HTTPS URL.
- A text block with the file's name/size/mime type, the URL's expiry, and a ready-to-run `curl` command to download it (e.g. `curl -sSL '<url>' -o '<name>'`).
Accepted path forms:
- `@skilder-file:/<fileId>/<name>` — a file kept in the workspace: one a tool or script produced (e.g. a screenshot), one uploaded with `upload_skilder_file`, or a skill's asset as `learn` prints it. Pass the path exactly as it was returned.
- `@skilder-asset:/<resourceId>/<filename>` — any skill file: an asset, a reference or a script. `learn` prints this form for a reference, a script, or an asset not yet moved to the store.
Any other `@skilder-file:` path is refused. A fresh signed URL is minted on every call.
Examples:
- `read_skilder_file(path="@skilder-file:/3f2c9a7e-1b4d-4c8e-9a6f-2d5e7b8c0f13/step-01.png")`
- `read_skilder_file(path="@skilder-asset:/0xabc/report.csv")`
Requires `curl` on your host: the bytes move only through the signed URL. Without curl, stop and report the missing prerequisite — do not try another way to transfer the file, and never pass its contents (e.g. base64) through the conversation.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
path
Skilder URI: @skilder-file:/<fileId>/<name> or @skilder-asset:/<resourceId>/<filename>
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
sessionId
Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call.
Clear enough to supply this argument.
Annotations75/100
Declare destructiveHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "read_skilder_file",
"title": "Read Skilder File",
"description": "Get a short-lived signed download URL for a Skilder-managed file. Use this to pull the file's actual bytes somewhere — e.g. onto your own local disk/repo checkout, or into another tool that needs a real file rather than a path — for a file another tool (e.g. a screenshot tool) already produced at a `@skilder-file:` or `@skilder-asset:` path.\n\nAlways returns two content blocks, regardless of file type (image, text, or other binary):\n- A `resource_link` block with the signed HTTPS URL.\n- A text block with the file's name/size/mime type, the URL's expiry, and a ready-to-run `curl` command to download it (e.g. `curl -sSL '<url>' -o '<name>'`).\n\nAccepted path forms:\n- `@skilder-file:/<fileId>/<name>` — a file kept in the workspace: one a tool or script produced (e.g. a screenshot), one uploaded with `upload_skilder_file`, or a skill's asset as `learn` prints it. Pass the path exactly as it was returned.\n- `@skilder-asset:/<resourceId>/<filename>` — any skill file: an asset, a reference or a script. `learn` prints this form for a reference, a script, or an asset not yet moved to the store.\n\nAny other `@skilder-file:` path is refused. A fresh signed URL is minted on every call.\n\nExamples:\n- `read_skilder_file(path=\"@skilder-file:/3f2c9a7e-1b4d-4c8e-9a6f-2d5e7b8c0f13/step-01.png\")`\n- `read_skilder_file(path=\"@skilder-asset:/0xabc/report.csv\")`\n\nRequires `curl` on your host: the bytes move only through the signed URL. Without curl, stop and report the missing prerequisite — do not try another way to transfer the file, and never pass its contents (e.g. base64) through the conversation.",
"inputSchema": {
"type": "object",
"required": [
"path",
"sessionId"
],
"properties": {
"path": {
"type": "string",
"description": "Skilder URI: @skilder-file:/<fileId>/<name> or @skilder-asset:/<resourceId>/<filename>"
},
"sessionId": {
"type": "string",
"description": "Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call."
}
}
},
"annotations": {
"title": "Read Skilder File",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Push a file INTO Skilder so a tool can read it. Use this whenever a tool needs a real file you hold locally (a PDF to fill, a spreadsheet to process, an image to attach) and you only have it on your own disk.
Returns a text block containing:
- A ready-to-run `curl` command that PUTs your file to a short-lived, single-use signed HTTPS URL.
- The `@skilder-file:/<fileId>/<name>` path the file will be stored at in the workspace. The path does not expire. Pass it, whole and unchanged, as the file argument of any tool or script, also inside a list or object; the tool receives a copy of the file under its name. A tool on a remote MCP server cannot open it and refuses it.
Two steps, in order:
1. `upload_skilder_file(filename="contract.pdf")` → gives you the curl command and the path.
2. Run the curl command, then call the tool with the path, e.g. `{ "filePath": "@skilder-file:/<fileId>/contract.pdf" }`.
The curl PUT returns once the file is stored in the workspace, and its JSON response repeats the same path. If the PUT answers 409 (the URL was already used), 401 (it expired), 404 or a 5xx, call `upload_skilder_file` again for a fresh URL; a second 404 means the workspace is no longer available. 413 means the file is above the maximum size. To go the other way — pull a file out of Skilder — use `read_skilder_file`.
Requires `curl` on your host: the bytes move only through the signed URL. Without curl, stop and report the missing prerequisite — do not try another way to transfer the file, and never pass its contents (e.g. base64) through the conversation.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
filename
Name of the file you are uploading, e.g. "contract.pdf". The receiving tool gets the file under this name, and Skilder types the file from its extension; an unknown extension is "application/octet-stream". The storage location is chosen by Skilder.
Clear enough to supply this argument.
sessionId
Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "upload_skilder_file",
"title": "Upload Skilder File",
"description": "Push a file INTO Skilder so a tool can read it. Use this whenever a tool needs a real file you hold locally (a PDF to fill, a spreadsheet to process, an image to attach) and you only have it on your own disk.\n\nReturns a text block containing:\n- A ready-to-run `curl` command that PUTs your file to a short-lived, single-use signed HTTPS URL.\n- The `@skilder-file:/<fileId>/<name>` path the file will be stored at in the workspace. The path does not expire. Pass it, whole and unchanged, as the file argument of any tool or script, also inside a list or object; the tool receives a copy of the file under its name. A tool on a remote MCP server cannot open it and refuses it.\n\nTwo steps, in order:\n1. `upload_skilder_file(filename=\"contract.pdf\")` → gives you the curl command and the path.\n2. Run the curl command, then call the tool with the path, e.g. `{ \"filePath\": \"@skilder-file:/<fileId>/contract.pdf\" }`.\n\nThe curl PUT returns once the file is stored in the workspace, and its JSON response repeats the same path. If the PUT answers 409 (the URL was already used), 401 (it expired), 404 or a 5xx, call `upload_skilder_file` again for a fresh URL; a second 404 means the workspace is no longer available. 413 means the file is above the maximum size. To go the other way — pull a file out of Skilder — use `read_skilder_file`.\n\nRequires `curl` on your host: the bytes move only through the signed URL. Without curl, stop and report the missing prerequisite — do not try another way to transfer the file, and never pass its contents (e.g. base64) through the conversation.",
"inputSchema": {
"type": "object",
"required": [
"filename",
"sessionId"
],
"properties": {
"filename": {
"type": "string",
"description": "Name of the file you are uploading, e.g. \"contract.pdf\". The receiving tool gets the file under this name, and Skilder types the file from its extension; an unknown extension is \"application/octet-stream\". The storage location is chosen by Skilder."
},
"sessionId": {
"type": "string",
"description": "Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call."
}
}
},
"annotations": {
"title": "Upload Skilder File",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Read-only analytics over what Skilder agents did: activity and value summaries, breakdowns, and the session and call records behind them. Pass tool_name plus a tool_input object for that sub-tool. Records of what happened only — skills, roles and other definitions are not here. Your workspace permissions decide whose numbers come back, never an argument: every result echoes its scope and names in "withheld" what a narrower scope did not get. window is "24h", "7d", "30d", "90d", "all" or ISO dates {from, to}; default 30d for figures, 7d for lists. Sizes start small and the same call raises them: lists 20 (up to 50), breakdown rows 10 (up to 50), a session trace 100 calls (up to 500), get-call payloads 4000 characters (up to 20000). A short result says so: hasMore means pass nextOffset back as offset; an "other" row holds every group ranked after the page; truncated and resultsTruncated mean a scan hit its bound, so narrow the window before relying on affected groups or rows. A sub-tool's full input schema is available via analytics(tool_name="describe-tool", tool_input={"tool_name": "<name>"}). Available tools, with their REQUIRED tool_input arguments — optional arguments are counted, not listed: activity-overview() [+1 optional]; value-overview() [+2 optional]; activity-breakdown(metric: "calls"|"failures"|"value"|"unpriced"|"sessions"|"guardrail-decisions", by: "skill"|"tool"|"user"|"role"|"status"|"client"|"day"|"outcome"|"guardrail") [+4 optional]; list-sessions() [+8 optional]; get-session(sessionId: string) [+2 optional]; list-calls() [+13 optional]; get-call(callId: string) [+1 optional].
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
tool_name
The exact name of the analytics tool to call, or "describe-tool" to fetch another tool's input schema
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
tool_input
The input arguments for the analytics tool, matching that tool's own schema. The signature list above names every argument a sub-tool requires; one with none listed accepts {}. The full schema (including enums, bounds and defaults) is returned by tool_name="describe-tool" with {"tool_name": "<name>"}.
Clear enough to supply this argument.
sessionId
Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "analytics",
"title": "Skilder Analytics",
"description": "Read-only analytics over what Skilder agents did: activity and value summaries, breakdowns, and the session and call records behind them. Pass tool_name plus a tool_input object for that sub-tool. Records of what happened only — skills, roles and other definitions are not here. Your workspace permissions decide whose numbers come back, never an argument: every result echoes its scope and names in \"withheld\" what a narrower scope did not get. window is \"24h\", \"7d\", \"30d\", \"90d\", \"all\" or ISO dates {from, to}; default 30d for figures, 7d for lists. Sizes start small and the same call raises them: lists 20 (up to 50), breakdown rows 10 (up to 50), a session trace 100 calls (up to 500), get-call payloads 4000 characters (up to 20000). A short result says so: hasMore means pass nextOffset back as offset; an \"other\" row holds every group ranked after the page; truncated and resultsTruncated mean a scan hit its bound, so narrow the window before relying on affected groups or rows. A sub-tool's full input schema is available via analytics(tool_name=\"describe-tool\", tool_input={\"tool_name\": \"<name>\"}). Available tools, with their REQUIRED tool_input arguments — optional arguments are counted, not listed: activity-overview() [+1 optional]; value-overview() [+2 optional]; activity-breakdown(metric: \"calls\"|\"failures\"|\"value\"|\"unpriced\"|\"sessions\"|\"guardrail-decisions\", by: \"skill\"|\"tool\"|\"user\"|\"role\"|\"status\"|\"client\"|\"day\"|\"outcome\"|\"guardrail\") [+4 optional]; list-sessions() [+8 optional]; get-session(sessionId: string) [+2 optional]; list-calls() [+13 optional]; get-call(callId: string) [+1 optional].",
"inputSchema": {
"type": "object",
"required": [
"tool_name",
"tool_input",
"sessionId"
],
"properties": {
"sessionId": {
"type": "string",
"description": "Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call."
},
"tool_name": {
"enum": [
"describe-tool",
"activity-overview",
"value-overview",
"activity-breakdown",
"list-sessions",
"get-session",
"list-calls",
"get-call"
],
"type": "string",
"description": "The exact name of the analytics tool to call, or \"describe-tool\" to fetch another tool's input schema"
},
"tool_input": {
"type": "object",
"description": "The input arguments for the analytics tool, matching that tool's own schema. The signature list above names every argument a sub-tool requires; one with none listed accepts {}. The full schema (including enums, bounds and defaults) is returned by tool_name=\"describe-tool\" with {\"tool_name\": \"<name>\"}.",
"additionalProperties": true
}
}
},
"annotations": {
"title": "Skilder Analytics",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Admin-only dispatcher for managing Skilder content: roles, skills, skill-content (references/scripts/assets), guardrail rules, org-units, and MCP servers. Pass tool_name plus a tool_input object matching that tool's arguments — for management/CRUD operations rather than learned-skill tools (no prior "learn" step is needed). Note: the list_* operations here return the full ADMIN view (including drafts, disabled items and raw ids) — this is distinct from the consumption-oriented view that "learn"/"init_skilder" surface, so it is not suitable for deciding what to learn/use. All operations run under your workspace permissions. Consent: the write operations (create/update/delete/publish/add/remove/attach/detach/reparent/install/enable) act on shared workspace content, so they need the user's explicit request or explicit approval — never modify Skilder content on your own initiative. If you judge a change is warranted, describe the change you intend and ask the user to confirm it, then call. The read operations (list-*/get-*/suggest-*/describe-tool) and test-guardrail, which runs only the rule's own script and calls no tool, need no such confirmation. Best practices and architecture context for these tools are available (admin-only) via learn(path="roles/Skilder Platform Assistant"). A sub-tool's full input schema is available via manage(tool_name="describe-tool", tool_input={"tool_name": "<name>"}). Available tools, with their REQUIRED tool_input arguments — optional arguments are counted, not listed: list-skills(); get-skill(skillId: string); create-skill(name: string) [+2 optional]; update-skill(skillId: string) [+3 optional]; delete-skill(skillId: string); add-tool-to-skill(skillId: string, toolIds: string[]); remove-tool-from-skill(skillId: string, toolIds: string[]); suggest-skills-for-role(roleId: string); list-skill-content(skillId: string) [+1 optional]; get-skill-content(id: string) [+1 optional]; create-skill-content(contentType: "reference"|"script"|"asset", skillId: string, name: string) [+6 optional]; update-skill-content(contentType: "reference"|"script"|"asset", id: string) [+7 optional]; delete-skill-content(id: string) [+1 optional]; attach-skill-asset(skillId: string) [+5 optional]; list-available-tools() [+1 optional]; list-roles(); get-role(roleId: string); create-role() [+8 optional]; update-role(roleId: string) [+7 optional]; delete-role(roleId: string); add-skill-to-role(roleId: string, skillId: string); remove-skill-from-role(roleId: string, skillId: string); list-guardrails(); get-guardrail(guardrailId: string); create-guardrail(name: string, language: "PYTHON"|"BASH"|"JAVASCRIPT"|"TYPESCRIPT") [+5 optional]; update-guardrail(guardrailId: string) [+7 optional]; set-guardrail-enabled(guardrailId: string, enabled: boolean); delete-guardrail(guardrailId: string); test-guardrail(guardrailId: string, version: "PUBLISHED"|"DRAFT", phase: "PRE"|"POST", sample: object); list-org-units(); get-org-unit(orgUnitId: string); create-org-unit(name: string, color: "RED"|"ORANGE"|"YELLOW"|"GREEN"|"BLUE"|"PURPLE"|"PINK"|"GRAY", order: integer) [+1 optional]; update-org-unit(orgUnitId: string, name: string, color: "RED"|"ORANGE"|"YELLOW"|"GREEN"|"BLUE"|"PURPLE"|"PINK"|"GRAY", order: integer); delete-org-unit(orgUnitId: string) [+1 optional]; reparent-org-unit(orgUnitId: string, newParentId: string,null); prepare_mcp_config(input: string); install_mcp_server(name: string, description: string, config: object) [+3 optional]; list_mcp_servers(); update_mcp_server(serverId: string) [+6 optional].
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
tool_name
The exact name of the management tool to call, or "describe-tool" to fetch another tool's input schema
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
tool_input
The input arguments for the management tool, matching that tool's own schema. The required arguments of every tool are listed in this tool's description; the full schema (including optional arguments, enums and defaults) is returned by tool_name="describe-tool" with {"tool_name": "<name>"}.
Clear enough to supply this argument.
sessionId
Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "manage",
"title": "Manage Skilder Content",
"description": "Admin-only dispatcher for managing Skilder content: roles, skills, skill-content (references/scripts/assets), guardrail rules, org-units, and MCP servers. Pass tool_name plus a tool_input object matching that tool's arguments — for management/CRUD operations rather than learned-skill tools (no prior \"learn\" step is needed). Note: the list_* operations here return the full ADMIN view (including drafts, disabled items and raw ids) — this is distinct from the consumption-oriented view that \"learn\"/\"init_skilder\" surface, so it is not suitable for deciding what to learn/use. All operations run under your workspace permissions. Consent: the write operations (create/update/delete/publish/add/remove/attach/detach/reparent/install/enable) act on shared workspace content, so they need the user's explicit request or explicit approval — never modify Skilder content on your own initiative. If you judge a change is warranted, describe the change you intend and ask the user to confirm it, then call. The read operations (list-*/get-*/suggest-*/describe-tool) and test-guardrail, which runs only the rule's own script and calls no tool, need no such confirmation. Best practices and architecture context for these tools are available (admin-only) via learn(path=\"roles/Skilder Platform Assistant\"). A sub-tool's full input schema is available via manage(tool_name=\"describe-tool\", tool_input={\"tool_name\": \"<name>\"}). Available tools, with their REQUIRED tool_input arguments — optional arguments are counted, not listed: list-skills(); get-skill(skillId: string); create-skill(name: string) [+2 optional]; update-skill(skillId: string) [+3 optional]; delete-skill(skillId: string); add-tool-to-skill(skillId: string, toolIds: string[]); remove-tool-from-skill(skillId: string, toolIds: string[]); suggest-skills-for-role(roleId: string); list-skill-content(skillId: string) [+1 optional]; get-skill-content(id: string) [+1 optional]; create-skill-content(contentType: \"reference\"|\"script\"|\"asset\", skillId: string, name: string) [+6 optional]; update-skill-content(contentType: \"reference\"|\"script\"|\"asset\", id: string) [+7 optional]; delete-skill-content(id: string) [+1 optional]; attach-skill-asset(skillId: string) [+5 optional]; list-available-tools() [+1 optional]; list-roles(); get-role(roleId: string); create-role() [+8 optional]; update-role(roleId: string) [+7 optional]; delete-role(roleId: string); add-skill-to-role(roleId: string, skillId: string); remove-skill-from-role(roleId: string, skillId: string); list-guardrails(); get-guardrail(guardrailId: string); create-guardrail(name: string, language: \"PYTHON\"|\"BASH\"|\"JAVASCRIPT\"|\"TYPESCRIPT\") [+5 optional]; update-guardrail(guardrailId: string) [+7 optional]; set-guardrail-enabled(guardrailId: string, enabled: boolean); delete-guardrail(guardrailId: string); test-guardrail(guardrailId: string, version: \"PUBLISHED\"|\"DRAFT\", phase: \"PRE\"|\"POST\", sample: object); list-org-units(); get-org-unit(orgUnitId: string); create-org-unit(name: string, color: \"RED\"|\"ORANGE\"|\"YELLOW\"|\"GREEN\"|\"BLUE\"|\"PURPLE\"|\"PINK\"|\"GRAY\", order: integer) [+1 optional]; update-org-unit(orgUnitId: string, name: string, color: \"RED\"|\"ORANGE\"|\"YELLOW\"|\"GREEN\"|\"BLUE\"|\"PURPLE\"|\"PINK\"|\"GRAY\", order: integer); delete-org-unit(orgUnitId: string) [+1 optional]; reparent-org-unit(orgUnitId: string, newParentId: string,null); prepare_mcp_config(input: string); install_mcp_server(name: string, description: string, config: object) [+3 optional]; list_mcp_servers(); update_mcp_server(serverId: string) [+6 optional].",
"inputSchema": {
"type": "object",
"required": [
"tool_name",
"tool_input",
"sessionId"
],
"properties": {
"sessionId": {
"type": "string",
"description": "Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call."
},
"tool_name": {
"enum": [
"describe-tool",
"list-skills",
"get-skill",
"create-skill",
"update-skill",
"delete-skill",
"add-tool-to-skill",
"remove-tool-from-skill",
"suggest-skills-for-role",
"list-skill-content",
"get-skill-content",
"create-skill-content",
"update-skill-content",
"delete-skill-content",
"attach-skill-asset",
"list-available-tools",
"list-roles",
"get-role",
"create-role",
"update-role",
"delete-role",
"add-skill-to-role",
"remove-skill-from-role",
"list-guardrails",
"get-guardrail",
"create-guardrail",
"update-guardrail",
"set-guardrail-enabled",
"delete-guardrail",
"test-guardrail",
"list-org-units",
"get-org-unit",
"create-org-unit",
"update-org-unit",
"delete-org-unit",
"reparent-org-unit",
"prepare_mcp_config",
"install_mcp_server",
"list_mcp_servers",
"update_mcp_server"
],
"type": "string",
"description": "The exact name of the management tool to call, or \"describe-tool\" to fetch another tool's input schema"
},
"tool_input": {
"type": "object",
"description": "The input arguments for the management tool, matching that tool's own schema. The required arguments of every tool are listed in this tool's description; the full schema (including optional arguments, enums and defaults) is returned by tool_name=\"describe-tool\" with {\"tool_name\": \"<name>\"}.",
"additionalProperties": true
}
}
},
"annotations": {
"title": "Manage Skilder Content",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Show the user an interactive Skilder card in the conversation. Call it at the two moments a human should see something for themselves: (1) view="summary" — after finishing Skilder content work (skills / roles / MCP servers created or updated, typically at the end of a chain of manage calls), to present what was achieved; (2) view="version-card" — when the user should review an entity's draft/publish state or decide about publishing: the card shows the live status and gives the user a real Publish button, so never publish on the user's behalf — show this card and let them click. The card supplements your text: the same information is returned as text for hosts without cards.
The description explains the capability, when to use it, and what to expect.
Inputs69/100
6 of 8 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
view
Which card to show: "version-card" (one skill/role/guardrail's draft & publish status, with a Publish button for the user) or "summary" (a recap of entities you created/updated/published).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
entity_type
version-card only: the entity kind.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
entity_id
version-card only: the entity id (e.g. from a manage result).
Clear enough to supply this argument.
headline
summary only (optional): one-line headline for the recap.
Clear enough to supply this argument.
items › items › entity_type
Not provided
Missing description. Explain what this value means and how to supply it.
items › items › entity_id
Not provided
Missing description. Explain what this value means and how to supply it.
items › items › action
What you did to this entity.
Clear enough to supply this argument.
sessionId
Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call.
Clear enough to supply this argument.
Annotations75/100
Declare destructiveHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "display",
"title": "Display to User",
"description": "Show the user an interactive Skilder card in the conversation. Call it at the two moments a human should see something for themselves: (1) view=\"summary\" — after finishing Skilder content work (skills / roles / MCP servers created or updated, typically at the end of a chain of manage calls), to present what was achieved; (2) view=\"version-card\" — when the user should review an entity's draft/publish state or decide about publishing: the card shows the live status and gives the user a real Publish button, so never publish on the user's behalf — show this card and let them click. The card supplements your text: the same information is returned as text for hosts without cards.",
"inputSchema": {
"type": "object",
"required": [
"view",
"sessionId"
],
"properties": {
"view": {
"enum": [
"version-card",
"summary"
],
"type": "string",
"description": "Which card to show: \"version-card\" (one skill/role/guardrail's draft & publish status, with a Publish button for the user) or \"summary\" (a recap of entities you created/updated/published)."
},
"items": {
"type": "array",
"items": {
"type": "object",
"required": [
"entity_type",
"entity_id",
"action"
],
"properties": {
"action": {
"enum": [
"created",
"updated",
"published"
],
"type": "string",
"description": "What you did to this entity."
},
"entity_id": {
"type": "string"
},
"entity_type": {
"enum": [
"skill",
"role",
"mcp-server"
],
"type": "string"
}
}
},
"description": "summary only: the entities to recap. Names and statuses are fetched live — never guessed."
},
"headline": {
"type": "string",
"description": "summary only (optional): one-line headline for the recap."
},
"entity_id": {
"type": "string",
"description": "version-card only: the entity id (e.g. from a manage result)."
},
"sessionId": {
"type": "string",
"description": "Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call."
},
"entity_type": {
"enum": [
"skill",
"role",
"guardrail"
],
"type": "string",
"description": "version-card only: the entity kind."
}
}
},
"annotations": {
"title": "Display to User",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true
}
}
Align the title with the capability actually described by this tool.
Description75/100
Internal callback for actions the user clicks inside a Skilder display card (app-only). Do not call this directly: publishing requires an explicit user click on the card — use display(view="version-card") to show the user the card instead.
The description explains the capability, when to use it, and what to expect.
Inputs44/100
2 of 4 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
action
The clicked card action.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
entity_type
Not provided
Missing description. Explain what this value means and how to supply it.
entity_id
Not provided
Missing description. Explain what this value means and how to supply it.
sessionId
Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "display_action",
"title": "Display Card Action",
"description": "Internal callback for actions the user clicks inside a Skilder display card (app-only). Do not call this directly: publishing requires an explicit user click on the card — use display(view=\"version-card\") to show the user the card instead.",
"inputSchema": {
"type": "object",
"required": [
"action",
"entity_type",
"entity_id",
"sessionId"
],
"properties": {
"action": {
"enum": [
"publish"
],
"type": "string",
"description": "The clicked card action."
},
"entity_id": {
"type": "string"
},
"sessionId": {
"type": "string",
"description": "Skilder session id (sks-…) returned by init_skilder. Required on every Skilder tool call."
},
"entity_type": {
"enum": [
"skill",
"role",
"guardrail"
],
"type": "string"
}
}
},
"annotations": {
"title": "Display Card Action",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
Loading score analytics…
Put your MCP to the test
A few tasks worth trying with this server, chosen from its reviewed tools. These have not been run.
01Skilder AnalyticsRead-only analytics over what Skilder agents did: activity and value summaries, breakdowns, and the session and call records behind them.
02Display to UserShow the user an interactive Skilder card in the conversation.
03Learn Skills & Access ReferencesAccess roles, skills, and resources using path-based navigation.
Want to run these tasks against your MCP server with us?
pietro.zullo setup, tools, quality score, publishing readiness, and alternatives.
How do I add pietro.zullo to Claude, ChatGPT, or Cursor?
Add pietro.zullo to Claude, ChatGPT, or Cursor by connecting its remote MCP URL in each client's MCP settings. In Claude, add a custom connector. In ChatGPT, add an MCP app. In Cursor, add an MCP server under Settings. The MCP URL is https://app.skilder.ai/mcp. This server requires OAuth, so complete the login prompt after you connect.
Is pietro.zullo MCP ready for ChatGPT and Claude?
As of October 15, 2026, pietro.zullo scores 83/100 on Manufact's MCP publishing checklist. The scan does not yet meet ChatGPT publishing checks and meets Claude publishing checks. Passing these checks does not guarantee marketplace approval.
How clear is pietro.zullo's MCP tool documentation?
As of October 15, 2026, pietro.zullo scores 80/100 in Manufact's review of tool titles, descriptions, input and output schemas, and behavior annotations. The review covers 12 of 12 discovered tools. The quality score measures documentation clarity; runtime behavior and marketplace readiness require separate checks.
What tools does the pietro.zullo MCP server provide?
pietro.zullo provides these MCP tools: execute_script, feedback_skill, init_skilder, learn, manage, read_skilder_file, run_read_tool, and run_write_tool.
What are the best alternatives to pietro.zullo?
As of October 20, 2026, alternatives to pietro.zullo in productivity on the Manufact MCP leaderboard include Autodesk Product Help, BoardWise, FlagStat, Keenable Web Search, and PomoDial.
Does pietro.zullo MCP require authentication?
pietro.zullo requires authentication. Connect it in Claude, ChatGPT, or Cursor and complete the OAuth login prompt.
How can pietro.zullo improve its MCP documentation?
display_action is the lowest-scoring reviewed tool at 60/100. No output schema is declared. Add one for structured results so clients can interpret returned fields. Open its review for feedback and a copyable fix prompt, then rerun the documentation review after updating your tool metadata.
Who develops pietro.zullo?
pietro.zullo is developed by skilder.ai. It is listed as community on the Claude connector directory.
Not your MCP?
Review any public or OAuth MCP server for protocol compatibility, tool documentation, and ChatGPT and Claude publishing readiness. No account required.