usemycontext
v1.0.4
Published
The official UseMyContext SDK - a typed client + React hook for the structurally-blind personal-context MCP. npm i usemycontext, then drop the user's compiled context straight into any AI app.
Downloads
766
Maintainers
Readme
usemycontext
The user's context, in any AI app you ship. One npm i, one hook, and the
user's compiled personal context drops straight into your prompts - while
UseMyContext stays structurally blind to the content.
npm i usemycontextimport { useMyContextReact } from "usemycontext/react";
// The user pasted their UseMyContext token (grab one at usemycontext.ai/#/connect).
// This component connects, then drops their compiled context into a prompt.
function Assistant({ token }) {
const { state, connected, connect, client } = useMyContextReact();
async function run() {
await connect({ token });
const { composite } = await client.profile(); // the user's compiled context
const { passages } = await client.ask("what should I keep in mind?");
const systemPrompt =
`You are helping a specific person. Their context:\n${composite}\n\n` +
`Relevant notes:\n${passages.map((p) => p.text).join("\n")}`;
console.log(systemPrompt); // -> hand this to your LLM
}
return (
<button onClick={run} disabled={state === "connecting"}>
{connected ? "Connected" : "Use my context"}
</button>
);
}That is the whole integration. The hook holds the user's own token and calls the membrane exactly like Claude does - same trust model, new client shape.
Without React
The core entry is framework-free:
import { useMyContext } from "usemycontext";
const ctx = useMyContext();
await ctx.connect({ token }); // v1 is TOKEN-IN
const { composite } = await ctx.profile();The drop-in button
import { ConnectMyContext } from "usemycontext/react";
<ConnectMyContext token={token} onConnect={(s) => console.log(s)} />;It renders one <button class="umc-connect-button" data-umc-state="..."> whose
label tracks the connect state. Style it however you like - the markup is yours.
The 7 tools
Once connected, the client exposes one ergonomic wrapper per MCP tool:
| Method | Returns | What it is |
|---|---|---|
| client.profile() | { composite, facts? } | the compiled personal context - drop into a system prompt |
| client.ask(query, { k? }) | { passages, text } | ask_docs - cited passages to ground the LLM |
| client.listFiles() | FileMeta[] | the user's files (metadata only) |
| client.searchFiles(query) | FileMeta[] | search files by name |
| client.getFile(fileId) | { text, downloadUrl? } | the file's full extracted text |
| client.suggestUpdate(text) | { id?, text } | the one write - a PENDING suggestion the user reviews |
| client.sharedContext(from?) | { mode, shares, composite } | read contexts others shared with the user |
The connect state machine
ctx.state is one of:
idle -> connecting -> connected
\-> declined (user/host refused)
\-> error (network / transport failure)
connected -> expired (token rejected mid-session - re-connect)
<any> -> disconnected (disconnect() was called)A 401 from the membrane (an expired or revoked token) moves the client to
expired and throws TokenExpiredError; re-run connect({ token }) with a
fresh token to recover.
Errors
Every failure is a typed subclass of UseMyContextError:
NotConnectedError- a wrapper was called beforeconnect().TokenExpiredError- the membrane rejected the token (carries theWWW-Authenticateheader).ScopeDeniedError- this connection is not authorized for that tool.ToolCallError- the tool returned an error result.TransportError- the network/transport failed.
Token model (v1)
v1 is token-in only: you supply the user's UseMyContext session token to
connect({ token }). The full browser-OAuth-in-the-SDK flow (a hosted popup on
connect.usemycontext.ai) is v2.
Persistence
Default: the token is kept in memory only and is never written to
localStorage unless you opt in. It does not survive a page reload by default.
This is deliberate, but be clear about what it does and does not do. The v1 token
is the user's long-lived session credential. Memory-only persistence reduces
its exposure - the token is never written to disk, is gone on reload, and cannot
be read at rest from localStorage - but it does not eliminate it: while the
client is connected the token still lives in the host page's memory, so a script
running on your page (an XSS) could still read it during a live session.
The long-lived-token-in-the-host-page problem is not solved by storage choice.
It is solved by v2's token lifecycle: short-lived access tokens plus an
httpOnly refresh cookie on connect.usemycontext.ai, so the host page never holds
a long-lived credential at all. Until then, treat the v1 token as sensitive and
keep your page free of untrusted scripts.
If you want the token to survive reloads, opt in knowingly (this trades the
above reduction away - the token is now also readable at rest from localStorage):
import { useMyContext, webStorage } from "usemycontext";
// You accept that the token now lives in localStorage, readable by any
// script on the page. The httpOnly-cookie model (no token in the host page)
// lands in v2.
useMyContext({ storage: webStorage(localStorage) });Pass storage: null to use a no-op store, or supply your own StorageAdapter:
useMyContext({ storage: null });License
MIT
