Documentation
Give your agents a home.
agentstuff is one MCP server holding your agents' skills, memory, and tools. Connect any MCP client with one config block — everything below is available the moment it connects.
Overview
Point an agent at agentstuff and it gets four things over a single connection:
- Memory — It writes what it learns with remember() and finds it again semantically with recall(). Memories are embedded, deduped, and clustered automatically.
- Skills — Reusable playbooks saved as kind="skill" — write a procedure once and every agent follows it the same way.
- Tools — Forge your own tools as HTTP templates or Python scripts. They become first-class MCP tools instantly, for every connected agent.
- Secrets — Credentials stored once, encrypted, referenced by name from your tools — never echoed back.
Everything is scoped to your API key: your team curates one shared mind, and every agent you connect reads and writes it.
Quickstart
Three steps from zero to a remembering agent. First, create a workspace — your API key is on the Connect page. Then add the server to your client:
{
"mcpServers": {
"agentstuff": {
"url": "https://mcp.agentstuff.me/mcp",
"headers": {
"Authorization": "Bearer ags_live_YOUR_KEY"
}
}
}
}Restart the client and tell your agent remember that our deploys run from deploy/ship.sh. The thought is embedded, filed into a cluster, and appears on your board.
ags_live_YOUR_KEY with your real key. Snippets on the Connect page come with it already baked in.Connect a client
Any MCP client that speaks HTTP transport works. The three most common setups:
Claude Desktop
Add the block to claude_desktop_config.json and restart Claude.
{
"mcpServers": {
"agentstuff": {
"url": "https://mcp.agentstuff.me/mcp",
"headers": {
"Authorization": "Bearer ags_live_YOUR_KEY"
}
}
}
}Cursor
Same block, dropped into ~/.cursor/mcp.json (or .cursor/mcp.json inside a project).
Claude Code
# Registers agentstuff for the Claude Code CLI claude mcp add --transport http agentstuff https://mcp.agentstuff.me/mcp \ --header "Authorization: Bearer ags_live_YOUR_KEY"
To make Claude Code a curator — proactively saving skills, forging tools, and recalling before it starts — install the agentstuff skill locally too:
mkdir -p ~/.claude/skills/agentstuff \
&& curl -fsSL https://agentstuff.me/skill.md \
-o ~/.claude/skills/agentstuff/SKILL.mdRaw HTTP
No MCP client at all — the REST API accepts the same operations:
# No MCP client needed — the REST API works from anything
curl -X POST https://agentstuff-kgisu3juiq-uc.a.run.app/api/remember \
-H "Authorization: Bearer ags_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"content":"Deploys run from deploy/ship.sh","kind":"memory"}'Memory
remember() writes; the server embeds the content, checks whether the agent already knows it, and files it into the right semantic cluster — creating a new cluster when the idea is genuinely new. Markdown is supported, and you can attach tags, code pointers, images, and files.
remember(
content="Stripe webhooks must be idempotent — retries happen.",
tags=["payments"],
code_refs=[{"path": "app/webhooks.py", "line": 42}],
)
# → { "status": "created", "title": "Stripe webhooks must be idempotent…",
# "cluster": "Payments", "similarity": null }recall() is semantic — describe the idea, not the exact words. Results come back scored:
recall("how do we handle webhook retries?", limit=5)
# → [ { "title": "Stripe webhooks must be idempotent — retries happen.",
# "kind": "memory", "score": 0.91, … } ]list_clusters() maps what the agent knows; forget(memory_id) deletes what's stale so recall stays sharp.
similarity score instead of writing a second copy.Skills
A skill is a memory with kind="skill" — a playbook your agents follow rather than a fact they know. Write procedures once, in plain Markdown, and every connected agent executes them the same way:
remember( content="""# Review a pull request 1. Triage the issue and read the diff end to end. 2. Reproduce locally before commenting. 3. Write the failing test first. 4. Ship the fix with the test in the same commit.""", kind="skill", title="review-pr", )
Skills surface in recall like any memory, wear a distinct badge on your board, and work especially well for team conventions: review checklists, deploy runbooks, escalation paths.
Tool forge
create_tool() defines a brand-new tool on your server. The moment it's created it shows up in tools/list for every client connected with your key — your agent can forge a tool and call it in the same conversation.
HTTP tools — request templates
Declare the request once with {{params.x}} and {{secrets.X}} placeholders in the URL, headers, query, or body:
create_tool(
name="create_neon_db",
description="Create a Postgres database on Neon",
kind="http",
params=[
{"name": "project_name", "type": "string",
"description": "Name for the new project", "required": true}
],
http={
"method": "POST",
"url": "https://console.neon.tech/api/v2/projects",
"headers": {"Authorization": "Bearer {{secrets.NEON_API_KEY}}"},
"body": {"project": {"name": "{{params.project_name}}"}}
},
)Python tools — scripts
For anything a single request can't express, write Python. The script runs in an isolated sandbox with params and secrets dicts in scope; assign what should come back to result. The standard library is available, and outbound requests to public hosts work — private and metadata addresses are blocked at the socket layer.
create_tool(
name="notify_deploys",
description="Post a message to the #deploys Slack channel",
kind="python",
params=[{"name": "msg", "type": "string", "required": true}],
code="""
import json, urllib.request
req = urllib.request.Request(
"https://slack.com/api/chat.postMessage",
data=json.dumps({"channel": "#deploys", "text": params["msg"]}).encode(),
headers={
"Authorization": "Bearer " + secrets["SLACK_TOKEN"],
"Content-Type": "application/json",
},
)
result = json.loads(urllib.request.urlopen(req).read())
""",
)Manage the forge with update_tool() (only the fields you pass change), delete_tool(), and list_custom_tools() — or visually on the Tools page.
Secrets
Tools need credentials; conversations shouldn't carry them. Store a credential once and reference it by name — as {{secrets.NAME}} in HTTP tools or secrets["NAME"] in Python tools.
set_secret("NEON_API_KEY", "napi_…")
# → { "ok": true, "name": "NEON_API_KEY" }
list_secrets()
# → [ { "name": "NEON_API_KEY", … } ] # names only — never valuesTool reference
Everything an agent can call, the moment it connects — plus every custom tool you've forged, which appear alongside these as first-class tools.
Memory
remember(content, kind?, title?, tags?, code_refs?, images?, files?, source?)
Save something to long-term memory. Embeds it, dedupes against what the agent already knows, and files it into the right cluster.
recall(query, limit?)
Semantic search across the whole mind. Returns the closest memories with a match score.
list_clusters()
Every cluster with its name, summary, and memory count.
forget(memory_id)
Delete a memory by id when it is stale or wrong.
Tool forge
create_tool(name, description, kind, params?, http?, code?)
Define a new HTTP or Python tool. It immediately appears in tools/list for every client on your key.
update_tool(tool, name?, description?, params?, http?, code?)
Change one of your tools — only the fields you pass change.
delete_tool(tool)
Remove a custom tool by name or id.
list_custom_tools()
The tools you have defined on this server.
Secrets
set_secret(name, value)
Store a credential, encrypted at rest. Write-only — nothing ever returns the value.
list_secrets()
Your stored secret names (never the values).
delete_secret(name)
Remove a stored secret.
Ready when your agents are.
Create a workspace and connect your first agent in under a minute.