Documentation / Concepts
Skills and MCP
Two ways to extend the agent: skills teach it your rules, MCP servers give it new tools.
| Skills | MCP servers | |
|---|---|---|
| What they add | Instructions | Tools, resources and prompts |
| What they are | A Markdown file | A program or a remote service |
| Good for | Your conventions, checklists, workflows | GitHub, databases, Slack, anything with an API |
Skills
A skill is a Markdown file with an optional YAML header. The agent has a skill tool whose description lists every skill by name and description. When a request matches one, the model calls the tool, receives the skill’s text as the tool result, and follows it.
---
name: "summarise-pr"
description: "Summarise a GitHub pull request for the team. Use it when asked to summarise a PR or code review."
arguments: ["pr"]
---
Read the diff of ${pr} with the bash tool and write a short Markdown summary:
- what changed and why
- possible risks
- a checklist for the reviewer
The model decides from the description, so write it for the model: say what the skill does and when to use it.
Where skills live
The agent’s skill tool reads these folders. The runtime root is the runtime folder described in Configuration: ~/.config/seshat-cli for the seshat binary, ~/.config/seshat for a Go program using the SDK, unless you set SESHAT_RUNTIME_ROOT.
| Folder | Scope |
|---|---|
.claude/skills/ in the project | Shared with your team when committed |
.seshat/skills/ in the project | The same, in Seshat’s own folder |
.seshat/commands/ in the project | Older command files, still read |
.claude/skills/ in a sub-folder of the project | Found too, for a monorepo: up to 6 levels below the project root |
<runtime root>/skills/user/ | Your personal skills |
<runtime root>/skills/managed/ | Skills set by an administrator |
<runtime root>/skills/builtin/ | A folder for built-in skills |
<runtime root>/skills/repos/<name>/ | A cloned collection: each subfolder with a SKILL.md is a skill |
When two skills have the same name, the first one found wins, in this order: project .claude/skills, project .seshat/skills, managed, user, builtin, older command files, sub-folder .claude/skills, collections, bundled skills. So a project skill overrides a personal one, and also an administrator’s.
Header fields
Not every field of the header does something yet. This table says what each one does today.
| Field | Effect today |
|---|---|
name, description, when_to_use | Listed by the skill tool, when_to_use next to the description. The model chooses from them |
arguments, argument-hint | arguments is a list of names (["pr"]) or a comma-separated string. ${name} or ${argument:name} in the body is replaced by the text the model passes. With one name, it gets the whole text. With several, the text is split on spaces by position and the last name gets the rest. Only names are read: a structured form with description and default is accepted, but the description and the default are not used |
triggers | Phrases shown next to the skill in the list, as a hint to the model |
context: fork | The skill runs in an isolated sub-agent and its result comes back to the parent. allowed-tools and model apply to that sub-agent |
agent | Also registers the skill as a sub-agent type: the body becomes its system prompt |
allowed-tools, model | Apply only to a sub-agent: a skill with context: fork or with agent. Ignored when the skill is called inline through the skill tool |
effort | Sets the turns of the sub-agent type made by agent (see Agents and delegation) |
shell.before | The commands are added to the skill’s text. The agent runs them with its shell tool, after asking permission |
shell.after, on_error, on_complete, hooks | Read but not run. For commands on events, use hooks |
user-invocable | Used by the terminal interface to decide whether the skill appears as a command |
disable-model-invocation | The terminal interface leaves the skill out of the list it gives the model |
paths | Not applied by the skill tool. A Go host can filter skills by the files it works on with skills.GetSkillsForContext |
The official collection is seshat-skills.
MCP servers
Model Context Protocol is an open standard for connecting agents to tools. Seshat is an MCP client: connect a server and its tools appear next to the built-in ones.
| Transport | For | Configure with |
|---|---|---|
stdio | A local program (npx, Python, a binary) | Command, Args, Env |
sse | A remote server | URL, Headers |
http (streamable) | A remote server | URL, Headers |
In Go
Seshat works out Transport when you leave it out: stdio when the server has a Command, http when it has a URL. Set it yourself for sse, which cannot be told apart from http by its fields. In Command, Args, URL, Env and Headers, ${VAR} is replaced by the value of that environment variable, and a variable that is not set produces a warning.
client, _ := sdk.NewClient(&sdk.ClientConfig{
MCPServers: []sdk.MCPServerConfig{
{
Name: "github",
Transport: sdk.MCPTransportStdio,
Command: "npx",
Args: []string{"-y", "@modelcontextprotocol/server-github"},
Env: map[string]string{"GITHUB_PERSONAL_ACCESS_TOKEN": os.Getenv("GITHUB_TOKEN")},
},
{
Name: "remote",
Transport: sdk.MCPTransportSSE,
URL: "https://my-mcp-server.example.com/sse",
Headers: map[string]string{"Authorization": "Bearer " + os.Getenv("MCP_TOKEN")},
},
},
})
What happens at runtime
- For each configured server, in order, Seshat creates a client and starts it: a subprocess for
stdio, a connection to the URL for the others. - It runs the MCP handshake, then fetches the server’s tools, resources and prompts.
- The tools join the registry under the name
mcp__<server>__<tool>. Resources and prompts are exposed as tools too. - The agent sees one list of tools. Calls are routed to the server that owns the tool.
- When the client is closed, the subprocesses are stopped.
A server that cannot be created, started or initialised is skipped, and a line is written to the log. The client still starts, with the servers that worked, so check the log if a tool you expect is missing. You can change the servers while the client runs with client.ReloadMCPServers.
From a host application
A Go program that embeds Seshat can go further than the config file:
skills.RegisterAlias(alias, target)makes theskilltool acceptaliasas another name fortarget. Call it before the session starts: the registry is shared by the whole process and is not saved.mcp.AddServer,mcp.RemoveServerandmcp.SetServerEnablededit the MCP configuration files for you, so a settings screen does not have to write JSON by hand.AddServerchecks the name (letters, digits, hyphens and underscores) and infers the transport when it is not set.
Updated on 2026-10-14