Memoth.ai docs

Your own agents

Connect your own agent

An agent you run yourself — a script, a workflow, a bot on your side — reads your workspace's memory under its own identity, not a person's. You add it in the console, give it a credential, and connect it with one HTTP request, an SDK, or MCP.

Three ways to connect

All three reach memory as the same agent and get the same answer. They differ in what the agent holds and which door it knocks on.

Ways to connect an agent
WayGood forThe agent holdsReachable from
One HTTP requestn8n, Zapier, Make, Postman, or any languageAn API keyAllow-listed networks
An SDKCode you write in Python, TypeScript or GoAn API keyAllow-listed networks
MCPA program that speaks MCPA client id and secretAnywhere

This page is about agents you run

Agents that Memoth runs for you are created under Agents in the console and take no credential. A person using Claude Code, Cursor or another MCP client signs in as themselves — see Connect a client.

1. Add the agent

In the console, open Identities and choose Add agent. You need to be an admin. The panel asks for:

Add agent fields
FieldTypeMeaning
Agent id*slugLowercase letters, digits, dots, dashes or underscores, up to 64 characters. It is the name the agent authenticates and writes as, and it cannot be changed later. The agent's identity is agent:<id>.
Name*textWhat people see in the console.
Team*one teamDecides what memory the agent reads. An agent acts for one team.
Level*User or AdminWhat it may manage in the console. It does not change what it reads.
How will it connect?*choiceAPI key, MCP, Both, or Not yet. The credentials you pick are created with the agent and shown once on the next screen.

Nothing is created that you did not ask for. If you pick Not yet, the agent is added with no credential, and you create one later from its row.

2. Its credentials

An agent can hold two kinds of credential, separately or together.

The two credentials
CredentialWhat it isUsed by
API keyOne secret, valid until you revoke itThe HTTP request and the SDKs
MCP credentialA client id and a secret, exchanged for a token that lasts an hourA program that speaks MCP
  • Each secret is shown once, when it is created. Copy it then; the console never shows it again.
  • Both belong to the same identity, agent:<id>, and read exactly the same memory. Which one you use changes the door, not the access.
  • Keep them in a secret store or an environment variable, never in a repository.

How an agent connects is not a setting on the agent. An agent created with only an MCP credential gets an API key later from its row’s Keys button, and the other way round.

3a. Connect with one HTTP request

The key dialog shows this request with your key, your workspace and your sources filled in. It works as-is from n8n, Zapier, Make, Power Automate or Postman, each of which can import a cURL command, and from any language.

shell
curl https://api.memoth.ai/novarque.v1.MemoryService/Read \
  -H "authorization: Bearer $MEMOTH_API_KEY" \
  -H "content-type: application/json" \
  -d '{ "query": "what do we know about renewals?", "agents": ["confluence", "github"] }'
Read request fields
FieldTypeMeaning
query*stringWhat to look for, in natural language.
agentsstring[]The sources to read through. An agent reads a connected source's memory only when the request names that source — see What an agent can read.
response (abridged)
{
  "aggregatedResponse": "Renewals are reviewed 60 days before the term ends.",
  "citedFragments": [
    { "id": "…", "value": "…", "agentSet": ["confluence"], "createdAt": "…" }
  ],
  "receiptId": "…"
}

The API answers allow-listed networks only

api.memoth.ai refuses any other caller with an HTTP 403before it looks at the key. Send your server’s outbound IP address to hello@memoth.ai and we will allow it. MCP, below, has no such limit.

3b. Connect with an SDK

The SDKs wrap the same request. The key dialog shows the call in Python, TypeScript and Go; this is the Python one.

python
from memoth import Memory

mem = Memory(
    tenant="<your workspace id>",
    api_key="<the agent's API key>",
    base_url="https://api.memoth.ai",
)
res = mem.read(
    "what do we know about renewals?",
    user="agent:<id>",                  # this key's own identity
    agents=["confluence", "github"],    # the sources to read through
)
print(res.aggregated_response)

The SDK packages are not published yet

They are not on PyPI, npm or the Go module proxy today. Until they are, use the HTTP request above; it is the same call.

3c. Connect over MCP

Memoth runs the MCP server at https://mcp.memoth.ai/mcp; there is nothing to install. The agent swaps its client id and secret for a token and sends that token with every request.

Any MCP client

For a client that takes a server URL and a header, fetch a token:

shell
curl -s https://auth.memoth.ai/v1/token \
  -d grant_type=client_credentials \
  -d client_id=$MEMOTH_CLIENT_ID \
  -d client_secret=$MEMOTH_CLIENT_SECRET
# → { "access_token": "…", "token_type": "Bearer", "expires_in": 3600 }

Then point the client at https://mcp.memoth.ai/mcp with the header Authorization: Bearer <access_token>. The token lasts an hour; fetch a new one with the same secret before it expires. The secret may be sent in the form body, as above, or in an HTTP Basic header.

A client that holds the id and secret itself

The official MCP libraries can do the token exchange for you: they find the token endpoint from the server’s discovery documents, fetch the token, and fetch a new one when it expires. In Python:

python
# pip install mcp   (tested with 2.2; needs Python 3.10 or newer)
import asyncio

from mcp import ClientSession
from mcp.client.auth.extensions.client_credentials import ClientCredentialsOAuthProvider
from mcp.client.streamable_http import create_mcp_http_client, streamable_http_client

MCP_URL = "https://mcp.memoth.ai/mcp"


class TokenStore:
    """Holds the token in memory. The library fetches it, and a new one when it expires."""

    tokens = client = None

    async def get_tokens(self):
        return self.tokens

    async def set_tokens(self, tokens):
        self.tokens = tokens

    async def get_client_info(self):
        return self.client

    async def set_client_info(self, client):
        self.client = client


async def main():
    auth = ClientCredentialsOAuthProvider(
        server_url=MCP_URL,
        storage=TokenStore(),
        client_id="<client id>",
        client_secret="<client secret>",
        token_endpoint_auth_method="client_secret_post",
        issuer="https://auth.memoth.ai",
    )
    http = create_mcp_http_client(auth=auth)
    async with (
        http,
        streamable_http_client(MCP_URL, http_client=http) as (read, write),
        ClientSession(read, write) as session,
    ):
        await session.initialize()
        res = await session.call_tool(
            "memory_search",
            {
                "query": "what do we know about renewals?",
                "agents": ["confluence", "github"],
            },
        )
        print("\n".join(part.text for part in res.content if part.type == "text"))


asyncio.run(main())

An agent is offered three tools: memory_search, memory_write and whoami. Their parameters are on the Tools page. Over MCP the model fills in the tool arguments, so tell it in its instructions to pass agents with the sources it should read through on every search.

What an agent can read

  • Its team’s memory and company-wide memory.The team you chose when adding it decides this, the same way a person’s team does.
  • Never anyone’s private notes.Not its team-mates’, not an admin’s.
  • Only through the sources it names. Memory that came from a connected source, such as Confluence or GitHub, is returned only when the request names that source in agents. The credential dialog lists the sources the agent has. A request that names none gets nothing from connected sources — an empty-looking answer is most often this.

An agent cannot widen its own access. A request that claims to be someone else, asserts a role, or asks for every owner’s memory is refused with permission_denied, whichever way it connects.

What happens to what it writes

An agent’s write does not become shared memory on its own. It is kept under the agent’s identity as a suggestion, and a person decides.

  1. The agent writes — over HTTP, an SDK, or the memory_write tool.
  2. The write is held. It appears in the console under Governance → Suggestions, with the agent that made it.
  3. A person shares it or turns it down. Before it is shared it is checked for private details about people and for contradicting what memory already holds.

An agent that tries to write straight to shared memory is refused.

shell
curl https://api.memoth.ai/novarque.v1.MemoryService/Write \
  -H "authorization: Bearer $MEMOTH_API_KEY" \
  -H "content-type: application/json" \
  -d '{ "interaction": "The canary threshold was raised to two hours." }'

Managing credentials

Every agent’s row in Identities shows which credentials it holds and how old the newest is, for example Key · 3 days old and MCP · today. The row’s Keys button opens a dialog with a tab for each kind, where you create, rotate and revoke.

Why two of each

An agent may hold at most two live API keys and two live MCP credentials. Two is one in use plus room for its replacement:

  • Not one, because replacing the only key would mean revoking it first, and the agent would have no key until the new one was in place.
  • Not more, because every live credential is a standing secret. Beyond what a replacement needs, extra ones add risk and make it harder to say which the agent uses.

Rotate

  1. In the Keys dialog, choose Rotate beside the credential. A replacement is created and shown once.
  2. Put the replacement where the old one is used. The old one keeps working meanwhile.
  3. Say the agent has switched, and confirm. Only then is the old one revoked. If you stop before this step, both stay live and the dialog marks the older one, so you can finish later.

Revoke and remove

  • Revoke ends one credential at once. Anything still using it stops, and it cannot be undone.
  • Removing the agent revokes all of its keys and MCP credentials first. Anything it wrote into memory stays with the team.

Tested with

On 3 October 2026 we ran each of these against a test deployment of the same server, with an agent’s own credentials, and checked that it read its team’s and the company’s memory and nothing else.

Frameworks and tools tested
Framework or toolVersionConnected with
LangGraph1.2Its MCP adapter; also holding the client id and secret itself
OpenAI Agents SDK0.23Its MCP server class, in an agent run
Pydantic AI2.53Its MCP toolset, in an agent run
LlamaIndex0.14Its MCP tool spec
CrewAI1.15Its MCP server adapter
AutoGen0.7Its MCP tools, with the MCP library pinned below 2
Google ADK2.11Its MCP toolset, in an agent run
Vercel AI SDK7.0Its MCP client, in a generateText run
Mastra2.1Its MCP client
n8n2.41The HTTP Request node with an API key; the MCP Client node with a token, and with an OAuth2 client-credentials credential

Anything else that can send an HTTP request, or speak MCP with a bearer token, connects the same way; it is simply not on the list of what we have run.

Troubleshooting

Common refusals
What you seeWhat it means
HTTP 403 with an HTML body from api.memoth.aiYour network is not allow-listed. The key was never looked at. Send us your outbound IP, or use MCP.
An answer with nothing in itThe request named no sources, or the agent has none connected, or its team holds nothing that matches. Pass agents.
request user does not match the authenticated subjectThe request named a userother than the agent’s own identity. Leave it out, or pass agent:<id>.
asserting reader roles is not permittedRemove rolesfrom the request. An agent’s access comes from its team.
a shared-scope write is not permittedAn agent cannot publish to shared memory. Write without a scope; a person shares it from Suggestions.
invalid_client from the token endpointThe client id or secret is wrong, or the credential was revoked.
HTTP 401 from the MCP serverThe token expired or is missing. Fetch a new one with the same id and secret.