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.

01

Overview

Point an agent at agentstuff and it gets four things over a single connection:

  • MemoryIt writes what it learns with remember() and finds it again semantically with recall(). Memories are embedded, deduped, and clustered automatically.
  • SkillsReusable playbooks saved as kind="skill" — write a procedure once and every agent follows it the same way.
  • ToolsForge your own tools as HTTP templates or Python scripts. They become first-class MCP tools instantly, for every connected agent.
  • SecretsCredentials 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.

02

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:

mcp config (any 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.

Replace ags_live_YOUR_KEY with your real key. Snippets on the Connect page come with it already baked in.
03

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.

claude_desktop_config.json
{
  "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

terminal
# 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:

terminal
mkdir -p ~/.claude/skills/agentstuff \
  && curl -fsSL https://agentstuff.me/skill.md \
       -o ~/.claude/skills/agentstuff/SKILL.md
The skill (served at /skill.md) carries the trigger rules: gotcha → remember it, repeatable procedure → save a skill, second call to the same API → forge a tool.

Raw HTTP

No MCP client at all — the REST API accepts the same operations:

terminal
# 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"}'
04

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
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
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.

If a remember is near-duplicate of an existing memory, the response says so with a similarity score instead of writing a second copy.
05

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:

a skill is a playbook
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.

06

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:

an http tool
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.

a python tool
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.

07

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.

secrets
set_secret("NEON_API_KEY", "napi_…")
# → { "ok": true, "name": "NEON_API_KEY" }

list_secrets()
# → [ { "name": "NEON_API_KEY", … } ]   # names only — never values
Secrets are encrypted at rest and write-only: no tool response, listing, or error message ever includes the value.
08

Tool 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.

Get started