dhaga.docs
Using Dhaga

Connect an AI assistant (MCP)

Dhaga speaks the Model Context Protocol, so Claude, ChatGPT, Cursor or any other MCP client can read your network and write back to it — ten tools, no AI credits for the reading half.

Ask Dhaga answers questions inside Dhaga. MCP is the other direction: point an assistant you already use at your graph and let it ask on its own, in the middle of whatever else you were doing.

  • "Who did I meet at the conference last month?"
  • "Save the recruiter who referred me, and remind me to follow up Friday."
  • "Which employers haven't got back to me?"

The endpoint is /api/mcp on your instance. Any client that speaks the Model Context Protocol can connect to it — Dhaga doesn't ship a per-client integration, because the client discovers the tools, their inputs and their descriptions at connect time.

Connecting a client

There are two ways in, and both reach the same tools. Which one you use depends on the client, not on what you're allowed to do.

As a connector (log in, no keys)

Dhaga is its own OAuth 2.1 authorization server, so a client like claude.ai or ChatGPT can add it the way it adds any other connector: you paste the URL, Dhaga shows you a normal login and a consent screen, and the client gets a token of its own. Nothing is copied around by hand, and you can only ever grant access to your own account.

Add a custom connector in the client and give it one thing — the endpoint, https://your-dhaga-host/api/mcp.

Everything else is negotiated. The client fetches Dhaga's discovery documents (/.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server), registers itself, and sends you to log in.

With a personal access token

For local clients — Claude Code, Cursor, anything running on your own machine — the simpler path is the API key you already have. It's the same personal access token the mobile app uses, created under Settings › Account › API keys (see Settings).

Claude Code, in one line:

claude mcp add --transport http dhaga https://your-dhaga-host/api/mcp \
  --header "x-api-key: YOUR_TOKEN"

Any client that takes a raw HTTP MCP server config wants the same two things — the URL and the header:

{
  "mcpServers": {
    "dhaga": {
      "type": "http",
      "url": "https://your-dhaga-host/api/mcp",
      "headers": { "x-api-key": "YOUR_TOKEN" }
    }
  }
}

A token is as good as your account, so treat it like a password: it goes in the client's config, not in a note, a repo, or a chat message. Revoke it in Settings and every client holding it stops working immediately.

Clients that only speak stdio

Some MCP clients still launch a local process and talk over stdin/stdout rather than HTTP. Bridge those with mcp-remote, which runs as the local process and forwards to the endpoint:

{
  "mcpServers": {
    "dhaga": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://your-dhaga-host/api/mcp",
        "--header", "x-api-key:YOUR_TOKEN"
      ]
    }
  }
}

That's a community bridge, not something Dhaga ships — prefer a direct HTTP connection wherever the client offers one.

What the assistant can read

Six read tools, and none of them spend AI credits:

  • dhaga_search — hybrid keyword + semantic search across contacts and note text. It returns the people plus the snippets that matched, so the assistant can tell you why someone came back rather than asserting it. Capped at 20 results.
  • dhaga_list_contacts — browse with filters (name, company, tag, starred) and pagination, up to 100 per page.
  • dhaga_get_contact — one person in full: details, job history, the facts extracted from their notes (each with the sourceNoteId receipt it came from), up to 25 recent notes, and their open follow-ups.
  • dhaga_list_follow_ups — everything you're on the hook for, across the whole network, soonest-due first.
  • dhaga_find_warm_path — up to three introduction paths to a person or company, through people you already know.
  • dhaga_list_upcoming_dates — birthdays and anniversaries in the next N days (30 by default, 365 at most), resolved in your own timezone.

Dhaga tells the connected model, at connect time, to treat your graph as the only source of truth about who you know — and to say so plainly when the answer isn't there rather than filling the gap from what it happens to know about a similarly-named public figure.

What it can write

Four write tools, all additive:

  • dhaga_add_note — attach a note to a contact.
  • dhaga_create_contact — save a person. Only a name is required; title, company, emails, phones, links, location and a first note are all optional.
  • dhaga_create_follow_up — open a reminder (what to do, plus an optional due date).
  • dhaga_close_follow_up — mark one done or dismissed.

A note written by an assistant goes through exactly the same path as one you type in the app: it queues background extraction, and every fact or follow-up derived from it keeps a source_note_id receipt. Delete the note later and its derived facts go with it, as always.

What it deliberately cannot do

There is no delete, no merge, no bulk action, no export, and no admin tool, and that is a decision rather than a gap.

Why the write half stops where it does

Deleting a contact in Dhaga cascades — the person, their notes, the facts extracted from them, their graph edges and their embeddings all go. That is right when you click it and unrecoverable when a confused or prompt-injected client does. So the irreversible operations stay in the app, where a human is looking at them.

dhaga_close_follow_up is the one thing that might read like a deletion and isn't: it changes a follow-up's status, and the follow-up stays on the contact.

What it costs

Reading your graph costs no AI credits at all. There is deliberately no "ask Dhaga" tool in the MCP surface — the client on the other end is already a model, so it gets raw retrieval with receipts and does its own reasoning. You are not paying Dhaga to think on top of something that already thinks.

The one exception is notes. dhaga_add_note, and dhaga_create_contact when you give it a note, queue the normal background extraction — 1 credit, exactly as if you had written the note in the app. If you're out of credits for the month the note is still saved; only the extraction is skipped, and the assistant is told so rather than left to assume it worked. See AI credits.

There's also a plain request limit — 60 tool calls a minute, per person. An assistant working through a question makes several calls a turn and won't notice it; a client stuck in a retry loop will, and that's the point.

For self-hosters

MCP is pure AGPL core. It imports nothing from packages/ee, needs no cloud tier, and your instance serves the identical /api/mcp endpoint — a self-hosted Dhaga is a first-class MCP server, not a degraded one.

Set BETTER_AUTH_URL correctly

The OAuth issuer is derived from BETTER_AUTH_URL. If it doesn't match the URL clients actually reach your instance on, the tokens Dhaga issues will be rejected by the client that asked for them. The personal-access-token path is unaffected by this — it's a plain header.

Dynamic Client Registration today, CIMD later

The 2026-07-28 MCP spec deprecates Dynamic Client Registration in favour of Client ID Metadata Documents (CIMD). Dhaga's authorization server is better-auth's mcp plugin, and better-auth 1.6 implements DCR but does not advertise CIMD yet — so DCR is what's live at /api/auth/mcp/register, and it works with the clients shipping today. CIMD support lands here when better-auth ships it.

On this page