npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

intempt-mcp-server

v1.0.0

Published

MCP server for Intempt — CRM, meetings, analytics, AI chat, and marketing automation

Readme

intempt-mcp-server

MCP server for Intempt — AI content generation, brand management, knowledge base, and user/account lookup through natural language.

Works with Claude Desktop, Claude Code, Cursor, Windsurf, VS Code (Copilot), Zed, Cline, and any MCP-compatible client.

Documentation

| Document | What it answers | |---|---| | docs/TEST_AND_EXECUTION_PROTOCOL.md | How to build, test, restart and prove the server works against production — including the checks that pass without proving anything | | docs/PROTOCOL_CONFORMANCE.md | Row-by-row MCP + OAuth conformance with file-level evidence, and the two gaps that remain open | | Limitations | The capability ceiling: what it will not do, and what is broken upstream |

Status

| Area | Status | |------|--------| | MCP server (stdio + HTTP transport) | Working — Node.js, MCP SDK, 124 tools registered (measured 2026-08-10) | | Auth — browser login (stdio) | Workingauthorization_code + PKCE over a loopback redirect (RFC 8252) as the registered intempt-desktop client. /oauth/authorize hands the browser to the social provider's own login, so no Intempt-hosted page is involved. Token refresh, shared ~/.intempt/auth.json | | Auth — device code flow (HTTP transport only) | Working, pending a console deploy — the flow itself is fine; it sends the user to intempt.oauth.device.verification-uri = https://intempt.com/device. That page is built and working on console-v2 branch ved-device-route, but is not yet pushed or deployed, so production does not serve it. Kept for the HTTP transport, where the browser is on a different machine and loopback cannot work. Not used on a normal desktop — stdio uses the loopback flow above, which is why desktop login needs no device page | | Content generation (7 tools) | Working — routes through BluChatClient's WebSocket (wss://api.intempt.com/v1/{org}/projects/{project}/chat) | | Registry-backed (111 tools) | Working — real REST endpoints via @intempt/commands, extracted from console-v2's own working API client code (204 registry entries, 202 real / 2 confirmed stub; 48 excluded from the MCP surface by design) | | Docker + CI/CD | Working — Dockerfile, compose, GitHub Actions for test + publish | | Test suite | Working382 tests, 11 files; 381 pass, 1 fails on Windows only (symlinkSync needs Administrator; see the test protocol) | | MCP Resources | Working — 8 brand kit/knowledge-base resources registered, dual-exposed alongside the equivalent tools. A client sees 7 in resources/list + 1 in resources/templates/list (intempt://brand/attributes/{name} is parameterised, and the spec lists templates separately) — so "7" from a client is correct, not a missing resource | | Skill self-registration via npm install -g | Working, and verified from a tarball install — the postinstall hook copies the 9 intempt/claude-plugin skills into ~/.claude/skills/, same mechanism as @chatcut/skill. This row previously said "inert until published", which was wrong: it does not need a registry, only an install | | Payments/billing integration | Not started — no per-tool metering yet (works after auth since all API-driven) | | npm publish | Pipeline ready, not yet published.github/workflows/mcp-publish.yml builds, typechecks, tests and publishes on a mcp@* tag. @intempt/commands is a devDependency that esbuild inlines into the bundle, so this package publishes on its own with no unpublished dependencies. Blocked only on an NPM_TOKEN in repo/org secrets and on the branch being pushed (CI builds from the remote) |

Quick Start

Requires Node.js >= 18.

npm install -g intempt-mcp-server
claude mcp add intempt -- intempt-mcp-server

Or run it without installing:

claude mcp add intempt -- npx -y intempt-mcp-server

Then, in the chat, run the login tool. A browser opens on your normal Intempt sign-in page; when it says you're logged in, every tool works. If your account belongs to more than one org or project, run list_orgs and then use_project — no restart is needed.

Check whether the package is published yet — this answers for itself, so it cannot go stale the way a hardcoded "not published" notice does:

npm view intempt-mcp-server version

If that returns a version, ignore this section and use the registry commands above. If it errors with E404, the first release has not landed; build and hand over a tarball instead. It is the identical artifact the registry will serve.

cd packages/mcp
npm run build
npm pack            # -> intempt-mcp-server-1.0.0.tgz

On the installing machine:

npm install -g ./intempt-mcp-server-1.0.0.tgz
claude mcp add intempt -- intempt-mcp-server

⚠️ A tarball install and a registry install both provide the same intempt-mcp-server binary, so they collide. Run npm uninstall -g intempt-mcp-server before switching from one to the other.

Setup by Platform

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "intempt": {
      "command": "npx",
      "args": ["-y", "intempt-mcp-server"],
      "env": {
        "INTEMPT_ORG": "your-org",
        "INTEMPT_PROJECT": "your-project"
      }
    }
  }
}

Claude Code

Recommended: the Intempt plugin. It registers the MCP server automatically and bundles a setup skill that handles CLI install, login, and org/project selection in one step (intempt/claude-plugin):

/plugin marketplace add intempt/claude-plugin
/plugin install intempt@intempt-plugins

Restart Claude Code (exit and relaunch), then say:

run intempt setup

Manual alternative, if you don't want the plugin:

claude mcp add intempt -- npx -y intempt-mcp-server

Skills without the plugin marketplace: npm install -g intempt-mcp-server also self-registers the same 9 skills directly into ~/.claude/skills/, via a postinstall hook -- the same mechanism ChatCut's Claude Code integration uses. No /plugin marketplace add step needed. Set INTEMPT_SKIP_SKILL_INSTALL=1 to opt out. This works from a tarball install too -- it needs an install, not a registry.

If your account belongs to more than one org/project, set the default explicitly (skip this if you only belong to one of each -- login picks it automatically):

intempt use --org your-org --project your-project   # or omit both flags for an interactive picker

Or set env vars, which always take precedence:

export INTEMPT_ORG=your-org
export INTEMPT_PROJECT=your-project

Cursor

Open Cursor Settings > MCP Servers > Add:

{
  "mcpServers": {
    "intempt": {
      "command": "npx",
      "args": ["-y", "intempt-mcp-server"],
      "env": {
        "INTEMPT_ORG": "your-org",
        "INTEMPT_PROJECT": "your-project"
      }
    }
  }
}

Windsurf

Edit ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "intempt": {
      "command": "npx",
      "args": ["-y", "intempt-mcp-server"],
      "env": {
        "INTEMPT_ORG": "your-org",
        "INTEMPT_PROJECT": "your-project"
      }
    }
  }
}

VS Code (GitHub Copilot)

Add to your workspace .vscode/mcp.json:

{
  "servers": {
    "intempt": {
      "command": "npx",
      "args": ["-y", "intempt-mcp-server"],
      "env": {
        "INTEMPT_ORG": "your-org",
        "INTEMPT_PROJECT": "your-project"
      }
    }
  }
}

Zed

Edit ~/.config/zed/settings.json:

{
  "context_servers": {
    "intempt": {
      "command": {
        "path": "npx",
        "args": ["-y", "intempt-mcp-server"],
        "env": {
          "INTEMPT_ORG": "your-org",
          "INTEMPT_PROJECT": "your-project"
        }
      }
    }
  }
}

Cline

Open Cline Settings > MCP Servers > Add Custom Server:

{
  "mcpServers": {
    "intempt": {
      "command": "npx",
      "args": ["-y", "intempt-mcp-server"],
      "env": {
        "INTEMPT_ORG": "your-org",
        "INTEMPT_PROJECT": "your-project"
      }
    }
  }
}

Authentication

Auth is fully implemented against the Intempt auth service (not Auth0) at api.intempt.com -- there is no separate auth.intempt.com host; that string is only the JWT iss claim value, never an HTTP target. Uses device code flow (RFC 8628).

Interactive Login (Device Flow)

Say "log me in to Intempt" in your AI assistant. The flow:

  1. MCP calls POST /oauth/device on api.intempt.com (client_id: intempt-cli, a real pre-registered public client)
  2. Returns a verification URL + user code -- MCP opens it in your browser automatically (falls back to a clickable link + code in chat if that fails)
  3. User authenticates via Google/Microsoft/Apple in browser
  4. MCP polls POST /oauth/token until approved
  5. Calls GET /v1/myself to fetch identity (email, org/project memberships with roles) -- the token response itself carries only access_token/refresh_token/token_type/expires_in
  6. Access token + refresh token + identity stored at ~/.intempt/auth.json (mode 0600) -- shared with the intempt CLI, so one login covers both
  7. If the account belongs to exactly one org and one project, both are saved as the default automatically -- no INTEMPT_ORG/INTEMPT_PROJECT needed. A multi-org/multi-project account resolves this with intempt use (see above)
  8. Tokens auto-refresh on expiry (single-use rotation)

No passwords in chat. Credentials persist across sessions.

Static Token (CI / Automation)

Set INTEMPT_AUTH_TOKEN to skip interactive login:

{
  "env": {
    "INTEMPT_AUTH_TOKEN": "your-jwt-token",
    "INTEMPT_ORG": "your-org",
    "INTEMPT_PROJECT": "your-project"
  }
}

Tools (124)

124 = 111 registry-backed + 7 content-gen + 3 auth + 3 org/project switching (use_project, list_orgs, list_projects). Counted 2026-08-10 by instrumenting registerTools, not by adding up this page.

The 111 registry-backed tools are derived mechanically from @intempt/commands' 204-entry registry (13 domains, extracted from console-v2's own working API client code) — ask your MCP client to list tools for the exact, current names and schemas. They're generated from the registry, not hand-maintained here, so this section can't drift, but it also won't enumerate all 111 one by one.

Content Generation (7)

Routes through BluChatClient's WebSocket (wss://api.intempt.com/v1/{org}/projects/{project}/chat), never POST /chat/message (dead, no gateway route).

| Tool | Example prompt | |------|----------------| | generate_email | "Write a cold outreach email for enterprise SaaS buyers" | | generate_sms | "Flash sale SMS with 20% off code SPRING20, ends Friday" | | generate_push_notification | "Abandoned cart reminder for running shoes" | | generate_landing_page | "Landing page for our spring sale with hero, features, and CTA" | | generate_slack_message | "Team announcement about hitting 10k active users" | | generate_text | "Product description for our analytics dashboard" | | generate_image | "Hero image for a summer sale campaign" |

Auth (3)

| Tool | Example prompt | |------|----------------| | login | "Log me in to Intempt" | | logout | "Log me out" | | whoami | "Which account am I connected to?" |

Org / project switching (3)

Every data call runs against one organization + project. A user in several orgs has none selected by default, and every data tool then fails with "Organization and project are required" until one is chosen.

| Tool | Example prompt | |------|----------------| | list_orgs | "Which Intempt orgs can I see?" | | list_projects | "What projects are in intempt_external_use?" | | use_project | "Switch to intempt_on_intempt" |

use_project takes effect on the next tool call — no restart. Precedence is use_project selection > INTEMPT_ORG/INTEMPT_PROJECT env vars > the stored default, and whoami says when a session selection is outranking an env var.

Registry-backed (111), by domain

| Domain | Tools | Example | |--------|-------|---------| | accounts | Account overview/summary/activity, tagging, owner assignment | "Show me the Acme Corp account" (get_account_detail, view-parameterized) | | analytics | Funnels, retention, insights, dashboards, reports | "Analyze the signup → activation → purchase funnel" (analyze_funnel_overall) | | blu-chat | Knowledge base, brand kit/personas/tone, snippets, outreach | "Draft an email for [email protected] about our new feature" (draft_outreach, real REST) | | deals | Deal CRUD, tags, deal analytics | "Give me deal analytics for this quarter" (get_deals_analytics) | | designer | Brand designs, studios, characters, poses | "List our brand design templates" (list_brand_designs) | | events | Event CRUD, attributes, event metrics | "What events are we tracking?" (list_events) | | experiences | Experiment/variant CRUD, experience metrics | "How is the Pricing Page test performing?" (get_experience_metrics, view-parameterized) | | journeys | Journey detail views, lifecycle actions (start/stop/pause/...), drafts, transformers | "What's the config for the Welcome Series journey?" (get_journey_detail, view-parameterized) | | meetings | Meeting summaries, meeting types | "Summarize my last meeting with Acme Corp" (summarize_meeting) | | segments | Segment lists, counts, saved views | "How many users are in the Power Users segment?" (get_segment_match_count) | | users | User overview/summary/activity, tagging, owner assignment, outreach | "Tell me everything about [email protected]" (get_user_detail, view-parameterized, auto-resolves the email) | | workflows | list_active_workflows | Confirmed stub — console-v2 has no backend for this yet | | (no domain) | search_project | Confirmed stub — no cross-entity search backend exists yet |

Natural-language identifiers work everywhere they apply -- e.g. "[email protected]" or "Acme Corp" resolve to an internal ID automatically (POST /profile-lists/{users\|accounts}, first match) before the detail/summary call; there's no separate "lookup" tool.

Resolved 2026-08-02: 12 of the 202 registry entries needed bespoke request-body construction (KNOWN_STRUCTURAL_BODYKEY_GAPS, @intempt/commands) -- each now has a buildBody function producing the real payload shape instead of throwing.

Not available: recipe list/search/get/preview/run. The recipe execution backend is confirmed absent across every platform service searched -- these tools don't exist in the 121-tool list at all, not as stubs.

Limitations — what this server will not do

Written so an evaluator learns the ceiling here rather than by hitting it. All figures measured 2026-08-10.

It creates nothing, and it acts on one record at a time. Of the 204 registry entries, 48 are excluded from the MCP surface by design: the 46 marked create-or-bulk-or-destructive are filtered out before registration (mcpConsolidation.ts:254) along with the 2 stubs (:255). Most of the remaining difference between 156 and the 111 registry-backed tools is consolidation, not exclusion — several entries fold into one tool with a selector argument, so they stay reachable. The served catalogue is 56 reads + 44 single-record edits plus the session tools. Asked to create a segment or bulk-delete users, the honest answer is "use the console" — there is no tool to approximate it with.

It does delete, one record at a time. 11 delete_*/remove_* tools are served (snippets, personas, studios, characters, poses, brand designs, knowledge, meeting types, journey drafts/transformers, experience metrics). There is no undo. They carry destructiveHint: true, including delete_journey_draft, which is served over POST and which method-sniffing alone would misclassify.

Collections are capped, and say so. Responses cap at 50 items and shed bulky per-item fields to fit a size budget the client enforces — list_events returns 511 items / 359 KB raw, which the client refuses outright. Truncation is announced in _truncated (with the exact next offset) and field-shedding in _shaped. A capped count is not a total.

3 tools are broken upstream, in the Intempt backend rather than here: get_meetings_summary, list_snippets, get_journey_list_count. Retrying does not help. They are named in the server instructions so an agent does not burn a retry loop on them. Each was re-checked on 2026-08-11 against both the project-scoped and the root path and fails on both.

This list said 6 until 2026-08-11. list_brand_personalities, list_sales_agents and list_brand_methodologies were never broken -- they are platform-wide endpoints at /v1/<path> that we were calling under /v1/{org}/projects/{project}/. They now return real data. A "known broken" list is uniquely self-confirming: it tells agents not to call the very tools that would disprove it, so entries have to be re-measured, not inherited.

list_users search cannot match an email address. Any searchTerm containing @ matches nothing — a backend encoding bug that console-v2's own e2e helper documents and works around. An empty result does not mean the user is absent.

Known unfixed, tracked: 71 declared arguments across the registry are still never forwarded by the dispatcher (down from 95 on 2026-08-10). The set is pinned as a shrink-only baseline in registry.test.ts, which fails in both directions — a new one is a build failure, and so is a fixed one left in the list. The MCP-served subset of that class has been cleared; what remains is predominantly CLI-only, including a genuine one: delete_users / delete_accounts / delete_meetings declare a required id list that apiDelete(path) never sends.

Authorization: see docs/PROTOCOL_CONFORMANCE.md. The audience claim is validated but cannot bind to this server, because the platform issues one shared audience for the whole API — closing that needs an auth-service change, and it is written up there rather than papered over.

Environment Variables

Core

| Variable | Default | Description | |----------|---------|-------------| | INTEMPT_ORG | — | Organization slug (required) | | INTEMPT_PROJECT | — | Project slug (required) | | INTEMPT_AUTH_TOKEN | — | Static JWT token (skips interactive login) | | INTEMPT_API_URL | https://api.intempt.com | API gateway URL | | INTEMPT_AUTH_URL | same as INTEMPT_API_URL | Auth service URL -- same origin as the API, there is no separate auth.intempt.com host |

HTTP Transport

| Variable | Default | Description | |----------|---------|-------------| | MCP_TRANSPORT | stdio | Set to http for remote mode | | MCP_PORT | 3010 | HTTP server port | | MCP_SERVER_URL | http://localhost:3010 | Public URL for OAuth callbacks | | MCP_CLIENT_ID | intempt-mcp | OAuth client ID | | MCP_DEFAULT_PROVIDER | google | Default social login provider |

HTTP Transport (Remote Mode)

For shared infrastructure, multi-user environments, or Claude Connectors:

MCP_TRANSPORT=http MCP_PORT=3010 npx intempt-mcp-server

This starts an HTTP server with OAuth 2.1 (PKCE) at http://localhost:3010.

Endpoints:

| Endpoint | Auth | Description | |----------|------|-------------| | POST /mcp | Bearer | MCP JSON-RPC | | GET /mcp | Bearer | SSE streaming | | DELETE /mcp | Bearer | Session teardown | | GET /health | None | Health check ({"status":"ok","sessions":N}) | | GET /.well-known/oauth-authorization-server | None | OAuth discovery |

Docker

Build and run the HTTP transport in a container:

docker build -t intempt-mcp .
docker run -p 3010:3010 \
  -e INTEMPT_ORG=your-org \
  -e INTEMPT_PROJECT=your-project \
  intempt-mcp

Or with docker compose:

INTEMPT_ORG=your-org INTEMPT_PROJECT=your-project docker compose up

Pull from GHCR (after CI publishes):

docker pull ghcr.io/intempt/mcp-server:latest

CI/CD

Two GitHub Actions workflows:

.github/workflows/ci.yml — Build & Test

Runs on every push to main and on pull requests. Tests against Node.js 18, 20, and 22.

.github/workflows/publish.yml — Publish on Tag

Triggered by version tags (v*). Publishes to three registries:

  1. npmnpm publish --access public (requires NPM_TOKEN secret)
  2. GitHub Packages — scoped @intempt package (uses GITHUB_TOKEN)
  3. GHCR — Docker image with semver tags (uses GITHUB_TOKEN)

Release workflow:

npm version patch          # or minor, major
git push && git push --tags

The tag push triggers the publish workflow which builds, tests, and publishes to all three registries.

Required secrets:

| Secret | Where to set | Purpose | |--------|-------------|---------| | NPM_TOKEN | GitHub repo > Settings > Secrets | npm publish | | GITHUB_TOKEN | Automatic | GitHub Packages + GHCR |

Development

git clone https://github.com/intempt/cli.git
cd cli/packages/commands && npm install && npm run build
cd ../mcp
npm install
npm run build
npm test
npm run dev    # TypeScript watch mode

Publishing Manually

npm

npm publish --access public

The prepublishOnly hook runs tsc automatically.

GitHub Packages

echo "@intempt:registry=https://npm.pkg.github.com" >> .npmrc
npm publish

Docker (GHCR)

docker build -t ghcr.io/intempt/mcp-server:latest .
docker push ghcr.io/intempt/mcp-server:latest

How It Works

Architecture

User (in Claude/Cursor/VS Code/etc.)
  ↓ natural language
MCP Server (packages/mcp, cli repo monorepo)
  ↓ resolves names → IDs internally
Intempt Platform REST API (api.intempt.com)
  ├── /oauth/*, /v1/myself            → auth service (login, identity)
  ├── /v1/{org}/projects/{proj}/chat  → AI gateway, WebSocket (7 content-gen tools, via BluChatClient)
  └── 111 registry-backed tools       → real endpoints per @intempt/commands, extracted
                                         from console-v2's own working API client code
                                         (13 domains, 202 total entries, 200 real / 2 stub)

There is no /mcp/* stub namespace -- that was an earlier, abandoned model. @intempt/commands (shared with the intempt CLI) is the single source of truth for every registry-backed tool's endpoint, args, and write-safety class.

Content Generation

Content tools (generate_email, generate_sms, etc.) route through BluChatClient's WebSocket protocol (wss://api.intempt.com/v1/{org}/projects/{project}/chat) -- first-message {type:"auth",token} frame, then a message frame with a generated session_id and the active_skill, resolving on the server's {type:"messageEnd"} frame. Never POST /chat/message -- that path exists in llm-wrapper but has no gateway route and is unreachable.

User/Account Resolution

All tools accept natural language identifiers (names, emails, descriptions) — never internal IDs. When you say "look up [email protected]", the MCP server:

  1. Calls POST /profile-lists/users with {searchTerm: "[email protected]", perPage: 1}
  2. Gets the internal ID from the first result (no disambiguation list yet if there are multiple matches -- an open gap)
  3. Calls the real detail endpoint (e.g. get_user_overview, one of the views inside the consolidated get_user_detail tool)

Same pattern for accounts (via /profile-lists/accounts).


Tool Inventory Detail

All 121 tools are registered and routed against real endpoints or an explicit, documented gap -- there are no sample-data stubs anywhere in the shipped server.

| Group | Count | Notes | |-------|-------|-------| | Content generation | 7 | Real, via BluChatClient | | Auth | 3 | Real, self-contained device-code flow | | Registry-backed | 111 | Real REST endpoints via @intempt/commands (156 MCP-eligible entries, 61 narrow reads/lifecycle actions consolidated into 16 view-parameterized tools) |

Confirmed stub, no backend anywhere (2 of the 202 registry entries): search_project (no cross-entity search endpoint in console-v2), list_active_workflows (console-v2's workflows page is a bare placeholder with zero API calls).

Not implemented, backend confirmed absent (recipe list/search/get/preview/run): two independent source searches across gateway, single-metadata, llm-wrapper, audience-service, and metric found zero recipe backend anywhere. These tools don't exist in the 121-tool list -- not stubbed, simply absent, matching the "no fabricated data" rule below.

12 registry entries needed bespoke request-body construction -- RESOLVED 2026-08-02: get_account_event_overview, get_account_activity, enrich_accounts, get_user_activity, list_user_meetings, enrich_users, create_group, create_segment, list_deals, create_deal, get_deal_activity, list_meetings. Each now has a buildBody function (@intempt/commands' bodyBuilders.ts) producing the real console-v2 payload shape.

Known Gaps

| Gap | Notes | |-----|-------| | Recipe execution | Platform/backend team dependency, not something this package can unblock by itself | | Payments/billing metering | No per-tool credit metering yet; platform APIs still enforce org-level entitlements at the gateway (403 if the org lacks access) | | Rate limiting | No client-side rate limiting — relies on gateway 429 responses | | npm publish | intempt-mcp-server is not on the registry yet, so npx / npm install -g from npm 404 until the first release. The publish pipeline itself is ready (mcp-publish.yml, on a mcp@* tag or manual dispatch) and needs only an NPM_TOKEN secret plus the branch pushed, since CI builds from the remote. Note this does not block the postinstall skill self-registration, which works from any install including a tarball |

RESOLVED 2026-08-02: Console URLs -- 15 single-entity detail/activity reads in accounts/users/deals/meetings now return a consoleUrl field via RegistryEntry.consoleUrl + the shared attachConsoleUrl helper (@intempt/commands).

RESOLVED 2026-08-02: Disambiguation on multiple entity matches -- the shared resolver (resolveUserId/resolveAccountId, @intempt/commands) now returns an explicit ambiguous-candidates list instead of silently picking the first match; callers ask for id explicitly.


Project Structure

skills/             Vendored copies of intempt/claude-plugin's 9 SKILL.md files -- package
                     ROOT, a sibling of src/ and dist/, not nested under either (postinstall.ts's
                     dist/postinstall.js finds it via ../skills relative to its own dist/ location)
src/
  index.ts          Entry point — creates MCP server (stdio or HTTP)
  tools.ts          121 tool registrations — 111 generated from mcpToolList() (@intempt/commands)
                     + 7 content-gen + 3 auth, with Zod schemas
  handlers.ts       Tool dispatch — registry-backed dispatch via @intempt/commands,
                     BluChatClient for content-gen, custom auth handlers
  client.ts         IntemptClient — HTTP client for platform API
  auth.ts           AuthManager — device-code flow, GET /v1/myself identity,
                     token refresh, shared ~/.intempt/auth.json storage
  oauth.ts          OAuth 2.1 server for HTTP transport mode
  http.ts           HTTP/SSE transport server
  resources.ts      MCP Resources for brand kit/knowledge base — dual-exposed
                     alongside the equivalent tools, same dispatch underneath
  postinstall.ts    Self-registers skills/ into ~/.claude/skills/ on npm install -g
                     (same mechanism as @chatcut/skill)
  __tests__/
    handlers.test.ts     32 tests — tool routing, user/account resolution
    auth.test.ts         39 tests — device flow, GET /v1/myself, refresh, shared storage
    oauth.test.ts        29 tests — OAuth 2.1 server
    client.test.ts       18 tests — HTTP client
    tools.test.ts        14 tests — tool registration, annotation hints
    resources.test.ts     9 tests — MCP Resources
    http.test.ts          7 tests — HTTP transport bearer-auth gating
    postinstall.test.ts  16 tests — skill self-registration, chownToRealUser, per-skill isolation

License

MIT