Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx skills add skillmds/skillmd --skill servergit clone --depth 1 https://github.com/skillmds/skillmdWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/skillmds/skillmd/server)<a href="https://agentmods.dev/skills/skillmds/skillmd/server"><img src="https://agentmods.dev/badge/skills/skillmds/skillmd/server/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/skillmds/skillmd/server"><img src="https://agentmods.dev/badge/skills/skillmds/skillmd/server.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00008 | $0.04625 |
| Opus 5.5 | $0.00003 | $0.01850 |
| Sonnet 5 | $0.00002 | $0.00925 |
| Haiku 4.5 | $0.00001 | $0.00462 |
Grade A, and why
server scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 4d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 664 lines — stays where its author put it; the contents beside it link to each section on GitHub.
"""DeepAgents ACP server implementation."""
from future import annotations
import asyncio import uuid from typing import Any, Literal
from acp import ( Agent, AgentSideConnection, PROTOCOL_VERSION, stdio_streams, ) from acp.schema import ( AgentMessageChunk, InitializeRequest, InitializeResponse, NewSessionRequest, NewSessionResponse, PromptRequest, PromptResponse, SessionNotification, TextContentBlock, Implementation, AgentThoughtChunk, ToolCallProgress, ContentToolCallContent, LoadSessionResponse, SetSessionModeResponse, SetSessionModelResponse, CancelNotification, LoadSessionRequest, SetSessionModeRequest, SetSessionModelRequest, AgentPlanUpdate, PlanEntry, PermissionOption, RequestPermissionRequest, AllowedOutcome, DeniedOutcome, ToolCall as ACPToolCall, ) from deepagents import create_deep_agent from langchain_anthropic import ChatAnthropic from langchain_core.messages import AIMessage, AIMessageChunk, ToolMessage from langchain_core.messages.content import ToolCall from langchain_core.tools import tool from langgraph.checkpoint.memory import InMemorySaver from langgraph.graph.state import CompiledStateGraph from langgraph.types import Command, Interrupt
class DeepagentsACP(Agent): """ACP Agent implementation wrapping deepagents."""
def __init__(
self,
connection: AgentSideConnection,
agent_graph: CompiledStateGraph,
) -> None:
"""Initialize the DeepAgents agent.
Args:
connection: The ACP connection for communicating with the client
agent_graph: A compiled LangGraph StateGraph (output of create_deep_agent)
"""
self._connection = connection
self._agent_graph = agent_graph
self._sessions: dict[str, dict[str, Any]] = {}
# Track tool calls by ID for matching with ToolMessages
# Maps tool_call_id -> ToolCall TypedDict
self._tool_calls: dict[str, ToolCall] = {}
async def initialize(
self,
params: InitializeRequest,
) -> InitializeResponse:
"""Initialize the agent and return capabilities."""
return InitializeResponse(
protocolVersion=PROTOCOL_VERSION,
agentInfo=Implementation(
name="DeepAgents ACP Server",
version="0.1.0",
title="DeepAgents ACP Server",
),
)
async def newSession(
self,
params: NewSessionRequest,
) -> NewSessionResponse:
"""Create a new session with a deepagents instance."""
session_id = str(uuid.uuid4())
# Store session state with the shared agent graph
self._sessions[session_id] = {
"agent": self._agent_graph,
"thread_id": str(uuid.uuid4()),
}
return NewSessionResponse(sessionId=session_id)
async def _handle_ai_message_chunk(
self,
params: PromptRequest,
message: AIMessageChunk,
) -> None:
"""Handle an AIMessageChunk and send appropriate notifications.
Args:
params: The prompt request parameters
message: An AIMessageChunk from the streaming response
Note:
According to LangChain's content block types, message.content_blocks
returns a list of ContentBlock unions. Each block is a TypedDict with
a "type" field that discriminates the block type:
- TextContentBlock: type="text", has "text" field
- ReasoningContentBlock: type="reasoning", has "reasoning" field
- ToolCallChunk: type="tool_call_chunk"
- And many others (image, audio, video, etc.)
"""
for block in message.content_blocks:
# All content blocks have a "type" field for discrimination
block_type = block.get("type")
if block_type == "text":
# TextContentBlock has a required "text" field
text = block.get("text", "")
if not text: # Only yield non-empty text
continue
await self._connection.sessionUpdate(
SessionNotification(
update=AgentMessageChunk(
content=TextContentBlock(text=text, type="text"),
sessionUpdate="agent_message_chunk",
),
sessionId=params.sessionId,
)
)
elif block_type == "reasoning":
# ReasoningContentBlock has a "reasoning" field (NotRequired)
reasoning = block.get("reasoning", "")
if not reasoning:
continue
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 4d ago First seen · 664 lines · 8 tokens per session scan A 1d05c28d0726
server is a skill published in the GitHub repository skillmds/skillmd (1 stars, last pushed yesterday), licensed MIT. It adds 8 tokens to every session and 4,625 once invoked, about $0.0000 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-19.
Other skills, from other repositories
slopless
Use Slopless to review English Markdown for deterministic AI and human slop signals, including vague phrasing, formulaic prose, weak rhythm, filler, and cliches.
suiko
A Japanese writing and review workflow for checking whether text sounds uniform, translated, unnatural, or difficult to read. It supports writing and editing documents such as reports, guides, meeting notes, proposals, and emails.
poly-lint-and-format
Running poly lint / poly fmt — --fix, --format pretty|json|toon, --exclude, --config, exit codes, inline suppression, and the check → read-json → fix → re-check loop.
poly-orchestrator
Use poly as the single lint/format gate instead of invoking ruff/oxlint/rustfmt directly — one poly.toml, poly hooks install, poly migrate, CI via the Goldziher/poly setup Action.
poly-mcp
The poly MCP server — the eleven tools and which are read-only vs mutating, the paths/exclude/config/format params, async Tasks for the whole-project phase, and the isError contract.
poly-tiers-and-scope
Five mechanisms decide what actually inspects a file (crates/poly-core/src/registry.rs).