@anychat-ai/mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +174 -0
  3. package/dist/bin.d.ts +2 -0
  4. package/dist/bin.js +98 -0
  5. package/dist/bin.js.map +1 -0
  6. package/dist/client.d.ts +91 -0
  7. package/dist/client.js +154 -0
  8. package/dist/client.js.map +1 -0
  9. package/dist/docs.d.ts +60 -0
  10. package/dist/docs.js +238 -0
  11. package/dist/docs.js.map +1 -0
  12. package/dist/format.d.ts +19 -0
  13. package/dist/format.js +67 -0
  14. package/dist/format.js.map +1 -0
  15. package/dist/index.d.ts +21 -0
  16. package/dist/index.js +35 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/server.d.ts +26 -0
  19. package/dist/server.js +72 -0
  20. package/dist/server.js.map +1 -0
  21. package/dist/tool.d.ts +43 -0
  22. package/dist/tool.js +8 -0
  23. package/dist/tool.js.map +1 -0
  24. package/dist/tools/activity.d.ts +1 -0
  25. package/dist/tools/activity.js +153 -0
  26. package/dist/tools/activity.js.map +1 -0
  27. package/dist/tools/agents.d.ts +1 -0
  28. package/dist/tools/agents.js +309 -0
  29. package/dist/tools/agents.js.map +1 -0
  30. package/dist/tools/capabilities.d.ts +1 -0
  31. package/dist/tools/capabilities.js +325 -0
  32. package/dist/tools/capabilities.js.map +1 -0
  33. package/dist/tools/channels.d.ts +1 -0
  34. package/dist/tools/channels.js +208 -0
  35. package/dist/tools/channels.js.map +1 -0
  36. package/dist/tools/definition.d.ts +1 -0
  37. package/dist/tools/definition.js +531 -0
  38. package/dist/tools/definition.js.map +1 -0
  39. package/dist/tools/docs.d.ts +1 -0
  40. package/dist/tools/docs.js +67 -0
  41. package/dist/tools/docs.js.map +1 -0
  42. package/dist/tools/index.d.ts +8 -0
  43. package/dist/tools/index.js +30 -0
  44. package/dist/tools/index.js.map +1 -0
  45. package/dist/tools/me.d.ts +1 -0
  46. package/dist/tools/me.js +17 -0
  47. package/dist/tools/me.js.map +1 -0
  48. package/dist/tools/org.d.ts +1 -0
  49. package/dist/tools/org.js +178 -0
  50. package/dist/tools/org.js.map +1 -0
  51. package/dist/tools/people.d.ts +1 -0
  52. package/dist/tools/people.js +411 -0
  53. package/dist/tools/people.js.map +1 -0
  54. package/dist/version.d.ts +1 -0
  55. package/dist/version.js +6 -0
  56. package/dist/version.js.map +1 -0
  57. package/package.json +77 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Redirect Ventures Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,174 @@
1
+ # @anychat-ai/mcp
2
+
3
+ **Drive your [Anychat](https://www.anychat.ai) workspace from Claude Code, Claude Desktop, Cursor, or any MCP host.**
4
+
5
+ Anychat is the agent framework for business messaging — RCS, WhatsApp, Apple Messages for Business, SMS and Webchat. This [Model Context Protocol](https://modelcontextprotocol.io) server exposes the Anychat public API as tools, so an AI agent can read and change your agents, playbooks, channels, people and outreach _with your own API key and your own permissions_ — nothing it does exceeds what you could do with `curl`.
6
+
7
+ Docs: <https://docs.anychat.ai/integrations/mcp/> · API reference: <https://docs.anychat.ai/reference/agent-api/>
8
+
9
+ ## Setup
10
+
11
+ 1. Create an API key in the Anychat console: **Workspace → API keys**. Give it only the scopes you want your agent to have (e.g. `agents:write`, `people:read`, `messages:read`).
12
+ 2. Add the server to your host.
13
+
14
+ **Claude Code**
15
+
16
+ ```bash
17
+ claude mcp add anychat --env ANYCHAT_API_KEY=sk-any-... -- npx -y @anychat-ai/mcp
18
+ ```
19
+
20
+ **Claude Desktop / Cursor / other MCP hosts** — add to the `mcpServers` config:
21
+
22
+ ```json
23
+ {
24
+ "mcpServers": {
25
+ "anychat": {
26
+ "command": "npx",
27
+ "args": ["-y", "@anychat-ai/mcp"],
28
+ "env": { "ANYCHAT_API_KEY": "sk-any-..." }
29
+ }
30
+ }
31
+ }
32
+ ```
33
+
34
+ **Check the key** (prints org, role, scopes):
35
+
36
+ ```bash
37
+ ANYCHAT_API_KEY=sk-any-... npx -y @anychat-ai/mcp check
38
+ ```
39
+
40
+ ## Environment
41
+
42
+ | Variable | Required | Default |
43
+ | ------------------ | -------- | ------------------------- |
44
+ | `ANYCHAT_API_KEY` | yes | — |
45
+ | `ANYCHAT_API_URL` | no | `https://api.anychat.ai` |
46
+ | `ANYCHAT_DOCS_URL` | no | `https://docs.anychat.ai` |
47
+
48
+ Flags: `--read-only` registers only read tools. Subcommands: `check`, `tools`, `--version`, `--help`.
49
+
50
+ ## Tools
51
+
52
+ 94 tools, a 1:1 projection of the [Agent API](https://docs.anychat.ai/reference/agent-api/) grouped as the reference is (orient → Definition → Capabilities → Channels → People → Activity → Org → Docs). `npx -y @anychat-ai/mcp tools` prints the live table.
53
+
54
+ Every tool carries MCP annotations: `read` tools are `readOnlyHint`; `write` tools change configuration; `destructive` tools (deletes, provisioning requests, imports over an existing agent, secret rotation) are `destructiveHint` so your host asks before running them.
55
+
56
+ <details>
57
+ <summary>Full tool table</summary>
58
+
59
+ | Tool | Kind | Scope | Purpose |
60
+ | ----------------------------- | ----------- | ---------------------- | --------------------------------------------------- |
61
+ | `whoami` | read | `(any)` | Who am I |
62
+ | `list_agents` | read | `agents:read` | List agents |
63
+ | `get_agent` | read | `agents:read` | Get agent |
64
+ | `create_agent` | write | `agents:write` | Create agent |
65
+ | `update_agent` | write | `agents:write` | Update agent |
66
+ | `delete_agent` | destructive | `agents:write` | Delete agent |
67
+ | `export_agent` | read | `agents:read` | Export agent |
68
+ | `import_agent` | destructive | `agents:write` | Import agent document |
69
+ | `apply_agent_template` | destructive | `templates:apply` | Apply agent template |
70
+ | `list_agent_updates` | read | `agents:read` | List available catalog updates |
71
+ | `apply_agent_update` | write | `agents:write` | Apply one catalog update |
72
+ | `list_catalog_items` | read | `catalogs:read` | List a system catalog |
73
+ | `get_catalog_item` | read | `catalogs:read` | Get a catalog item |
74
+ | `get_identity` | read | `agents:read` | Get agent identity |
75
+ | `update_identity` | write | `agents:write` | Update agent identity |
76
+ | `get_personality` | read | `agents:read` | Get agent personality |
77
+ | `set_personality` | write | `agents:write` | Set agent personality |
78
+ | `import_personality_template` | write | `templates:apply` | Import personality template |
79
+ | `get_objectives` | read | `agents:read` | Get agent objectives |
80
+ | `set_objectives` | write | `agents:write` | Set agent objectives |
81
+ | `import_objective_template` | write | `templates:apply` | Import objective template |
82
+ | `get_guardrails` | read | `agents:read` | Get agent guardrails |
83
+ | `set_guardrails` | write | `agents:write` | Set agent guardrails |
84
+ | `update_guardrails` | write | `agents:write` | Update agent guardrails |
85
+ | `import_guardrail_template` | write | `templates:apply` | Import guardrail template |
86
+ | `list_playbooks` | read | `agents:read` | List playbooks |
87
+ | `get_playbook` | read | `agents:read` | Get playbook |
88
+ | `create_playbook` | write | `agents:write` | Create playbook |
89
+ | `update_playbook` | write | `agents:write` | Update playbook |
90
+ | `delete_playbook` | destructive | `agents:write` | Delete playbook |
91
+ | `set_default_playbook` | write | `agents:write` | Set default playbook |
92
+ | `import_playbook_template` | write | `templates:apply` | Import playbook template |
93
+ | `list_message_templates` | read | `agents:read` | List message templates |
94
+ | `get_message_template` | read | `agents:read` | Get message template |
95
+ | `upsert_message_template` | write | `agents:write` | Create or replace message template |
96
+ | `delete_message_template` | destructive | `agents:write` | Delete message template |
97
+ | `preview_message_template` | read | `agents:read` | Preview message template |
98
+ | `list_tool_bindings` | read | `agents:read` | List tool bindings |
99
+ | `get_tool_binding` | read | `agents:read` | Get a tool binding |
100
+ | `upsert_tool_binding` | write | `agents:write` | Create or replace a tool binding |
101
+ | `update_tool_binding` | write | `agents:write` | Update a tool binding (merge) |
102
+ | `set_tool_binding_enabled` | write | `agents:write` | Enable or disable a tool binding |
103
+ | `delete_tool_binding` | destructive | `agents:write` | Delete a tool binding |
104
+ | `get_oauth_status` | read | `agents:read` | Get OAuth connection status |
105
+ | `disconnect_oauth` | destructive | `agents:write` | Disconnect an OAuth grant |
106
+ | `get_outreach_config` | read | `agents:read` | Get outreach config |
107
+ | `replace_outreach_config` | write | `agents:write` | Replace outreach config |
108
+ | `preview_outreach` | read | `agents:read` | Preview outreach greeting |
109
+ | `list_outreach_links` | read | `agents:read` | List outreach links |
110
+ | `create_outreach_link` | write | `agents:write` | Create an outreach link |
111
+ | `update_outreach_link` | write | `agents:write` | Pause or resume an outreach link |
112
+ | `delete_outreach_link` | destructive | `agents:write` | Delete an outreach link |
113
+ | `list_knowledge_documents` | read | `knowledge:read` | List knowledge documents |
114
+ | `list_channels` | read | `agents:read` | List channel bindings |
115
+ | `get_channel` | read | `agents:read` | Get a channel binding |
116
+ | `request_channel` | destructive | `agents:write` | Request a managed channel |
117
+ | `bind_channel` | write | `agents:write` | Bind an unmanaged channel (bring your own provider) |
118
+ | `update_channel` | write | `agents:write` | Update a channel binding |
119
+ | `disable_channel` | write | `agents:write` | Disable a channel binding |
120
+ | `enable_channel` | write | `agents:write` | Enable a channel binding |
121
+ | `delete_channel` | destructive | `agents:write` | Delete a channel binding |
122
+ | `list_people` | read | `people:read` | List people |
123
+ | `get_person` | read | `people:read` | Get a person |
124
+ | `create_person` | write | `people:write` | Create a person |
125
+ | `update_person` | write | `people:write` | Update a person |
126
+ | `delete_person` | destructive | `people:write` | Delete a person |
127
+ | `merge_people` | write | `people:write` | Merge two people |
128
+ | `export_people` | read | `people:export` | Export people (bulk) |
129
+ | `import_people` | write | `people:write` | Import people |
130
+ | `list_person_appointments` | read | `people:read` | List a person's appointments |
131
+ | `list_appointments` | read | `people:read` | List appointments (all people) |
132
+ | `list_segments` | read | `people:read` | List people segments |
133
+ | `get_segment` | read | `people:read` | Get a people segment |
134
+ | `create_segment` | write | `people:write` | Create a people segment |
135
+ | `update_segment` | write | `people:write` | Replace a people segment |
136
+ | `delete_segment` | destructive | `people:write` | Delete a people segment |
137
+ | `list_messages` | read | `messages:read` | List messages |
138
+ | `list_conversations` | read | `messages:read` | List conversations |
139
+ | `list_users` | read | `messages:read` | List users |
140
+ | `list_logs` | read | `messages:read` | List runtime logs |
141
+ | `list_activity` | read | `messages:read` | List activity feed |
142
+ | `get_org` | read | `(any)` | Get org |
143
+ | `update_org` | write | `org:admin` | Update org |
144
+ | `list_api_keys` | read | `org:admin` | List API keys |
145
+ | `get_api_key` | read | `org:admin` | Get API key |
146
+ | `list_webhooks` | read | `webhooks:manage` | List webhooks |
147
+ | `get_webhook` | read | `webhooks:manage` | Get webhook |
148
+ | `create_webhook` | write | `webhooks:manage` | Create webhook |
149
+ | `update_webhook` | write | `webhooks:manage` | Update webhook |
150
+ | `delete_webhook` | destructive | `webhooks:manage` | Delete webhook |
151
+ | `rotate_webhook_secret` | destructive | `webhooks:manage` | Rotate webhook signing secret |
152
+ | `search_docs` | read | `(none — public docs)` | Search Anychat docs |
153
+ | `list_docs` | read | `(none — public docs)` | List Anychat docs pages |
154
+ | `read_doc` | read | `(none — public docs)` | Read an Anychat docs page |
155
+
156
+ </details>
157
+
158
+ ## Programmatic use
159
+
160
+ ```ts
161
+ import { AnychatClient, createServer } from '@anychat-ai/mcp';
162
+ const client = new AnychatClient({ apiKey: process.env.ANYCHAT_API_KEY! });
163
+ const server = createServer({ client }); // an McpServer — attach any transport
164
+ ```
165
+
166
+ ## Security
167
+
168
+ - The server holds no credentials of its own; every request carries the key you gave it, and the Anychat API enforces the key's org, role and scopes exactly as it would for you.
169
+ - Treat tool results as data: they contain your agents' configuration and your customers' records.
170
+ - Requests are tagged `X-Anychat-Agent: mcp` so they can be told apart in your access logs.
171
+
172
+ ## License
173
+
174
+ MIT © Redirect Ventures Inc.
package/dist/bin.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/bin.js ADDED
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ /**
5
+ * `anychat-mcp` — stdio MCP server over the Anychat public API.
6
+ *
7
+ * ANYCHAT_API_KEY=sk-any-... npx -y @anychat-ai/mcp
8
+ *
9
+ * Env:
10
+ * ANYCHAT_API_KEY required — API key from the console (Workspace → API keys)
11
+ * ANYCHAT_API_URL optional — API origin (default https://api.anychat.ai)
12
+ * ANYCHAT_DOCS_URL optional — docs origin (default https://docs.anychat.ai)
13
+ *
14
+ * Subcommands:
15
+ * (none) start the stdio server
16
+ * check verify the key: prints org, role, scopes, and exits
17
+ * --read-only register only read tools
18
+ * --version / --help
19
+ *
20
+ * All diagnostics go to stderr; stdout is the MCP transport.
21
+ */
22
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
23
+ const client_1 = require("./client");
24
+ const docs_1 = require("./docs");
25
+ const server_1 = require("./server");
26
+ const tools_1 = require("./tools");
27
+ const version_1 = require("./version");
28
+ const HELP = `anychat-mcp ${version_1.VERSION} — Anychat MCP server
29
+
30
+ Usage:
31
+ anychat-mcp [--read-only] start the stdio MCP server
32
+ anychat-mcp check verify ANYCHAT_API_KEY and print org/role/scopes
33
+ anychat-mcp tools list the tool table
34
+ anychat-mcp --version | --help
35
+
36
+ Environment:
37
+ ANYCHAT_API_KEY required — API key from the console (Workspace → API keys)
38
+ ANYCHAT_API_URL optional — default ${client_1.DEFAULT_API_URL}
39
+ ANYCHAT_DOCS_URL optional — default ${docs_1.DEFAULT_DOCS_URL}
40
+
41
+ Docs: https://docs.anychat.ai/integrations/mcp/`;
42
+ async function main(argv) {
43
+ const args = new Set(argv);
44
+ if (args.has('--help') || args.has('-h')) {
45
+ process.stderr.write(HELP + '\n');
46
+ return 0;
47
+ }
48
+ if (args.has('--version') || args.has('-v')) {
49
+ process.stdout.write(version_1.VERSION + '\n');
50
+ return 0;
51
+ }
52
+ if (args.has('tools')) {
53
+ for (const t of tools_1.allTools) {
54
+ process.stdout.write(`${t.name.padEnd(28)} ${t.kind.padEnd(11)} ${t.scope.padEnd(16)} ${t.title}\n`);
55
+ }
56
+ return 0;
57
+ }
58
+ const apiKey = process.env.ANYCHAT_API_KEY;
59
+ if (!apiKey) {
60
+ process.stderr.write('anychat-mcp: ANYCHAT_API_KEY is not set. Create a key in the Anychat console (Workspace → API keys) and export it.\n');
61
+ return 2;
62
+ }
63
+ const client = new client_1.AnychatClient({
64
+ apiKey,
65
+ baseUrl: process.env.ANYCHAT_API_URL,
66
+ userAgent: `anychat-mcp/${version_1.VERSION}`,
67
+ });
68
+ if (args.has('check')) {
69
+ try {
70
+ const me = await client.me();
71
+ process.stdout.write(`OK — org ${me.org.id}${me.org.name ? ` (${me.org.name})` : ''}, role ${me.org.role}, scopes: ${me.scopes.join(', ') || '(none)'}\nAPI: ${client.baseUrl}\n`);
72
+ return 0;
73
+ }
74
+ catch (err) {
75
+ process.stderr.write(`anychat-mcp: check failed — ${err.message}\n`);
76
+ return 1;
77
+ }
78
+ }
79
+ const server = (0, server_1.createServer)({
80
+ client,
81
+ docs: new docs_1.DocsIndex({ baseUrl: process.env.ANYCHAT_DOCS_URL }),
82
+ readOnly: args.has('--read-only'),
83
+ });
84
+ const transport = new stdio_js_1.StdioServerTransport();
85
+ await server.connect(transport);
86
+ process.stderr.write(`anychat-mcp ${version_1.VERSION} ready (${client.baseUrl})\n`);
87
+ // Keep running until the host closes stdin.
88
+ return new Promise(resolve => {
89
+ process.stdin.on('close', () => resolve(0));
90
+ process.on('SIGINT', () => resolve(0));
91
+ process.on('SIGTERM', () => resolve(0));
92
+ });
93
+ }
94
+ main(process.argv.slice(2)).then(code => process.exit(code), err => {
95
+ process.stderr.write(`anychat-mcp: ${err?.stack || err}\n`);
96
+ process.exit(1);
97
+ });
98
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Thin HTTP client for the Anychat public API (`/v1`).
3
+ *
4
+ * Deliberately dumb: no retries, no caching beyond the `/v1/me` org lookup,
5
+ * no knowledge of resources. Tools are a 1:1 projection of documented routes
6
+ * (https://docs.anychat.ai/reference/agent-api/) and this class only owns the
7
+ * transport: base URL, bearer key, org path prefix, error shaping.
8
+ *
9
+ * Every request carries the caller's own API key — the server can do nothing
10
+ * the key holder couldn't do with curl. `X-Anychat-Agent` identifies this
11
+ * automation to the api's access log (see console-copilot design §5).
12
+ */
13
+ export declare const DEFAULT_API_URL = "https://api.anychat.ai";
14
+ export interface AnychatClientOptions {
15
+ /** API origin, e.g. `https://api.anychat.ai`. `/v1` is appended. */
16
+ baseUrl?: string;
17
+ /** Anychat API key (`sk-any-…`) or a console session bearer token. */
18
+ apiKey: string;
19
+ /** Value for `X-Anychat-Agent`; defaults to `mcp`. */
20
+ agent?: string;
21
+ /** User-Agent suffix; defaults to the package version. */
22
+ userAgent?: string;
23
+ /** Injectable fetch for tests. */
24
+ fetchImpl?: typeof fetch;
25
+ }
26
+ /** Shape of `GET /v1/me`. */
27
+ export interface MeInfo {
28
+ caller: {
29
+ kind: string;
30
+ id: string;
31
+ };
32
+ org: {
33
+ id: string;
34
+ name?: string;
35
+ role: string;
36
+ };
37
+ isSysop?: boolean;
38
+ scopes: string[];
39
+ rateLimit: unknown;
40
+ }
41
+ export type QueryValue = string | number | boolean | undefined | null;
42
+ export type Query = Record<string, QueryValue>;
43
+ export interface RequestOptions {
44
+ query?: Query;
45
+ body?: unknown;
46
+ /** Extra headers (rare — e.g. `If-Match`). */
47
+ headers?: Record<string, string>;
48
+ }
49
+ /** Error thrown for non-2xx responses. `body` is the parsed JSON when present. */
50
+ export declare class AnychatApiError extends Error {
51
+ readonly status: number;
52
+ readonly body?: unknown | undefined;
53
+ readonly method?: string | undefined;
54
+ readonly path?: string | undefined;
55
+ constructor(status: number, message: string, body?: unknown | undefined, method?: string | undefined, path?: string | undefined);
56
+ }
57
+ export declare class AnychatClient {
58
+ readonly baseUrl: string;
59
+ private readonly apiKey;
60
+ private readonly agent;
61
+ private readonly userAgent;
62
+ private readonly fetchImpl;
63
+ private mePromise?;
64
+ constructor(opts: AnychatClientOptions);
65
+ /** `GET /v1/me`, cached for the life of the client. */
66
+ me(): Promise<MeInfo>;
67
+ /** The org id this key is bound to. */
68
+ orgId(): Promise<string>;
69
+ /**
70
+ * Build an org-scoped path: `orgPath('/agents')` → `/orgs/{org}/agents`.
71
+ * Path segments the caller supplies must already be encoded (use
72
+ * `encodeURIComponent` for ids that can contain `/` such as `@anychat/...`).
73
+ */
74
+ orgPath(subPath: string): Promise<string>;
75
+ get<T = unknown>(path: string, query?: Query): Promise<T>;
76
+ post<T = unknown>(path: string, body?: unknown, query?: Query): Promise<T>;
77
+ put<T = unknown>(path: string, body?: unknown, query?: Query): Promise<T>;
78
+ patch<T = unknown>(path: string, body?: unknown, query?: Query): Promise<T>;
79
+ delete<T = unknown>(path: string, query?: Query): Promise<T>;
80
+ /**
81
+ * Issue a request against `/v1{path}`. Returns parsed JSON, or `null` for
82
+ * 204 / empty bodies. Throws {@link AnychatApiError} on non-2xx.
83
+ */
84
+ request<T = unknown>(method: string, path: string, opts?: RequestOptions): Promise<T>;
85
+ }
86
+ /**
87
+ * Extract a human message from an error body. The api answers with RFC 7807
88
+ * problem details (`title`, `detail`, `code`, `errors[]`) on newer routes and
89
+ * `{ statusCode, message }` on older ones; strings and empty bodies happen too.
90
+ */
91
+ export declare function errorMessage(body: unknown, fallback?: string): string;
package/dist/client.js ADDED
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ /**
3
+ * Thin HTTP client for the Anychat public API (`/v1`).
4
+ *
5
+ * Deliberately dumb: no retries, no caching beyond the `/v1/me` org lookup,
6
+ * no knowledge of resources. Tools are a 1:1 projection of documented routes
7
+ * (https://docs.anychat.ai/reference/agent-api/) and this class only owns the
8
+ * transport: base URL, bearer key, org path prefix, error shaping.
9
+ *
10
+ * Every request carries the caller's own API key — the server can do nothing
11
+ * the key holder couldn't do with curl. `X-Anychat-Agent` identifies this
12
+ * automation to the api's access log (see console-copilot design §5).
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.AnychatClient = exports.AnychatApiError = exports.DEFAULT_API_URL = void 0;
16
+ exports.errorMessage = errorMessage;
17
+ exports.DEFAULT_API_URL = 'https://api.anychat.ai';
18
+ /** Error thrown for non-2xx responses. `body` is the parsed JSON when present. */
19
+ class AnychatApiError extends Error {
20
+ status;
21
+ body;
22
+ method;
23
+ path;
24
+ constructor(status, message, body, method, path) {
25
+ super(message);
26
+ this.status = status;
27
+ this.body = body;
28
+ this.method = method;
29
+ this.path = path;
30
+ this.name = 'AnychatApiError';
31
+ }
32
+ }
33
+ exports.AnychatApiError = AnychatApiError;
34
+ class AnychatClient {
35
+ baseUrl;
36
+ apiKey;
37
+ agent;
38
+ userAgent;
39
+ fetchImpl;
40
+ mePromise;
41
+ constructor(opts) {
42
+ if (!opts.apiKey)
43
+ throw new Error('AnychatClient: apiKey is required');
44
+ this.baseUrl = (opts.baseUrl || exports.DEFAULT_API_URL).replace(/\/+$/, '');
45
+ this.apiKey = opts.apiKey;
46
+ this.agent = opts.agent || 'mcp';
47
+ this.userAgent = opts.userAgent || `anychat-mcp`;
48
+ this.fetchImpl = opts.fetchImpl || fetch;
49
+ }
50
+ /** `GET /v1/me`, cached for the life of the client. */
51
+ me() {
52
+ if (!this.mePromise) {
53
+ this.mePromise = this.request('GET', '/me').catch(err => {
54
+ this.mePromise = undefined; // don't cache failures
55
+ throw err;
56
+ });
57
+ }
58
+ return this.mePromise;
59
+ }
60
+ /** The org id this key is bound to. */
61
+ async orgId() {
62
+ return (await this.me()).org.id;
63
+ }
64
+ /**
65
+ * Build an org-scoped path: `orgPath('/agents')` → `/orgs/{org}/agents`.
66
+ * Path segments the caller supplies must already be encoded (use
67
+ * `encodeURIComponent` for ids that can contain `/` such as `@anychat/...`).
68
+ */
69
+ async orgPath(subPath) {
70
+ const org = await this.orgId();
71
+ return `/orgs/${encodeURIComponent(org)}${subPath.startsWith('/') ? '' : '/'}${subPath}`;
72
+ }
73
+ get(path, query) {
74
+ return this.request('GET', path, { query });
75
+ }
76
+ post(path, body, query) {
77
+ return this.request('POST', path, { body, query });
78
+ }
79
+ put(path, body, query) {
80
+ return this.request('PUT', path, { body, query });
81
+ }
82
+ patch(path, body, query) {
83
+ return this.request('PATCH', path, { body, query });
84
+ }
85
+ delete(path, query) {
86
+ return this.request('DELETE', path, { query });
87
+ }
88
+ /**
89
+ * Issue a request against `/v1{path}`. Returns parsed JSON, or `null` for
90
+ * 204 / empty bodies. Throws {@link AnychatApiError} on non-2xx.
91
+ */
92
+ async request(method, path, opts = {}) {
93
+ const url = new URL(`${this.baseUrl}/v1${path.startsWith('/') ? '' : '/'}${path}`);
94
+ for (const [k, v] of Object.entries(opts.query || {})) {
95
+ if (v === undefined || v === null || v === '')
96
+ continue;
97
+ url.searchParams.set(k, String(v));
98
+ }
99
+ const headers = {
100
+ Authorization: `Bearer ${this.apiKey}`,
101
+ Accept: 'application/json',
102
+ 'User-Agent': this.userAgent,
103
+ 'X-Anychat-Agent': this.agent,
104
+ ...(opts.headers || {}),
105
+ };
106
+ let body;
107
+ if (opts.body !== undefined) {
108
+ headers['Content-Type'] = 'application/json';
109
+ body = JSON.stringify(opts.body);
110
+ }
111
+ const res = await this.fetchImpl(url, { method, headers, body });
112
+ const text = await res.text();
113
+ let parsed = null;
114
+ if (text) {
115
+ try {
116
+ parsed = JSON.parse(text);
117
+ }
118
+ catch {
119
+ parsed = text;
120
+ }
121
+ }
122
+ if (!res.ok) {
123
+ throw new AnychatApiError(res.status, errorMessage(parsed, res.statusText) || `HTTP ${res.status}`, parsed, method, path);
124
+ }
125
+ return parsed;
126
+ }
127
+ }
128
+ exports.AnychatClient = AnychatClient;
129
+ /**
130
+ * Extract a human message from an error body. The api answers with RFC 7807
131
+ * problem details (`title`, `detail`, `code`, `errors[]`) on newer routes and
132
+ * `{ statusCode, message }` on older ones; strings and empty bodies happen too.
133
+ */
134
+ function errorMessage(body, fallback = '') {
135
+ if (typeof body === 'string')
136
+ return body;
137
+ if (!body || typeof body !== 'object')
138
+ return fallback;
139
+ const b = body;
140
+ const head = b.message || b.title || b.detail || b.error || fallback;
141
+ const parts = [];
142
+ if (head)
143
+ parts.push(String(head));
144
+ if (b.code && !String(head).includes(String(b.code)))
145
+ parts.push(`[${b.code}]`);
146
+ if (Array.isArray(b.errors) && b.errors.length) {
147
+ const fields = b.errors
148
+ .map((e) => e && e.field ? `${e.field}: ${e.message ?? 'invalid'}` : JSON.stringify(e))
149
+ .join('; ');
150
+ parts.push(`(${fields})`);
151
+ }
152
+ return parts.join(' ');
153
+ }
154
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAmKH,oCAiBC;AAlLY,QAAA,eAAe,GAAG,wBAAwB,CAAC;AAkCxD,kFAAkF;AAClF,MAAa,eAAgB,SAAQ,KAAK;IAEtB;IAEA;IACA;IACA;IALlB,YACkB,MAAc,EAC9B,OAAe,EACC,IAAc,EACd,MAAe,EACf,IAAa;QAE7B,KAAK,CAAC,OAAO,CAAC,CAAC;QANC,WAAM,GAAN,MAAM,CAAQ;QAEd,SAAI,GAAJ,IAAI,CAAU;QACd,WAAM,GAAN,MAAM,CAAS;QACf,SAAI,GAAJ,IAAI,CAAS;QAG7B,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAXD,0CAWC;AAED,MAAa,aAAa;IACf,OAAO,CAAS;IACR,MAAM,CAAS;IACf,KAAK,CAAS;IACd,SAAS,CAAS;IAClB,SAAS,CAAe;IACjC,SAAS,CAAmB;IAEpC,YAAY,IAA0B;QACpC,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvE,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,uBAAe,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,aAAa,CAAC;QACjD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;IAC3C,CAAC;IAED,uDAAuD;IACvD,EAAE;QACA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAS,KAAK,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;gBAC9D,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC,uBAAuB;gBACnD,MAAM,GAAG,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,uCAAuC;IACvC,KAAK,CAAC,KAAK;QACT,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IAClC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,OAAe;QAC3B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QAC/B,OAAO,SAAS,kBAAkB,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO,EAAE,CAAC;IAC3F,CAAC;IAED,GAAG,CAAc,IAAY,EAAE,KAAa;QAC1C,OAAO,IAAI,CAAC,OAAO,CAAI,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,CAAc,IAAY,EAAE,IAAc,EAAE,KAAa;QAC3D,OAAO,IAAI,CAAC,OAAO,CAAI,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,GAAG,CAAc,IAAY,EAAE,IAAc,EAAE,KAAa;QAC1D,OAAO,IAAI,CAAC,OAAO,CAAI,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACvD,CAAC;IACD,KAAK,CAAc,IAAY,EAAE,IAAc,EAAE,KAAa;QAC5D,OAAO,IAAI,CAAC,OAAO,CAAI,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,CAAc,IAAY,EAAE,KAAa;QAC7C,OAAO,IAAI,CAAC,OAAO,CAAI,QAAQ,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACpD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAO,CACX,MAAc,EACd,IAAY,EACZ,OAAuB,EAAE;QAEzB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC,CAAC;QACnF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;YACtD,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE;gBAAE,SAAS;YACxD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC;QACD,MAAM,OAAO,GAA2B;YACtC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;YACtC,MAAM,EAAE,kBAAkB;YAC1B,YAAY,EAAE,IAAI,CAAC,SAAS;YAC5B,iBAAiB,EAAE,IAAI,CAAC,KAAK;YAC7B,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;SACxB,CAAC;QACF,IAAI,IAAwB,CAAC;QAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;YAC7C,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,MAAM,GAAY,IAAI,CAAC;QAC3B,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,GAAG,IAAI,CAAC;YAChB,CAAC;QACH,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,eAAe,CACvB,GAAG,CAAC,MAAM,EACV,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,IAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,EAC5D,MAAM,EACN,MAAM,EACN,IAAI,CACL,CAAC;QACJ,CAAC;QACD,OAAO,MAAW,CAAC;IACrB,CAAC;CACF;AA1GD,sCA0GC;AAED;;;;GAIG;AACH,SAAgB,YAAY,CAAC,IAAa,EAAE,QAAQ,GAAG,EAAE;IACvD,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IACvD,MAAM,CAAC,GAAG,IAA2B,CAAC;IACtC,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC;IACrE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACnC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IAChF,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM;aACpB,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CACd,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,OAAO,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAC3E;aACA,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,KAAK,CAAC,IAAI,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC"}
package/dist/docs.d.ts ADDED
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Product-docs access for the `search_docs` / `read_doc` tools.
3
+ *
4
+ * Reads the machine-readable exports of docs.anychat.ai:
5
+ * - `/llms.txt` — index: `- [Title](url): one-line summary` per page
6
+ * - `/llms-full.txt` — every page's markdown, each preceded by
7
+ * `<!-- page: <url> -->` and `# Title`
8
+ * (both generated at docs build time — see the docs repo).
9
+ *
10
+ * Search is a plain keyword scorer over title + summary + body: the corpus is
11
+ * ~30 pages, so anything fancier is overkill, and the model reads the page it
12
+ * picks with `read_doc` anyway.
13
+ */
14
+ export declare const DEFAULT_DOCS_URL = "https://docs.anychat.ai";
15
+ export interface DocPage {
16
+ title: string;
17
+ url: string;
18
+ summary: string;
19
+ /** Full markdown; present once llms-full.txt has loaded. */
20
+ body?: string;
21
+ }
22
+ export interface DocSearchHit {
23
+ title: string;
24
+ url: string;
25
+ summary: string;
26
+ score: number;
27
+ snippet?: string;
28
+ }
29
+ export declare class DocsIndex {
30
+ private readonly baseUrl;
31
+ private readonly fetchImpl;
32
+ private index?;
33
+ private full?;
34
+ constructor(opts?: {
35
+ baseUrl?: string;
36
+ fetchImpl?: typeof fetch;
37
+ });
38
+ /** The page index (llms.txt), cached for {@link CACHE_TTL_MS}. */
39
+ pages(): Promise<DocPage[]>;
40
+ /** url → markdown body from llms-full.txt, cached. */
41
+ private bodies;
42
+ search(query: string, limit?: number): Promise<DocSearchHit[]>;
43
+ /**
44
+ * Full markdown for a page, by exact url, by url path suffix, or by
45
+ * case-insensitive title match. Prefers the per-page markdown file the
46
+ * llms.txt entry links to; falls back to the llms-full.txt body.
47
+ */
48
+ read(ref: string): Promise<DocPage | undefined>;
49
+ private fetchText;
50
+ }
51
+ /** Parse `- [Title](url): summary` lines. Tolerates leading `*` and missing summaries. */
52
+ export declare function parseLlmsTxt(text: string): DocPage[];
53
+ /** Split llms-full.txt on `<!-- page: url -->` markers → url → body. */
54
+ export declare function parseLlmsFull(text: string): Map<string, string>;
55
+ /**
56
+ * `https://d/x/index.md`, `https://d/x/`, `https://d/x/index.html` and
57
+ * `https://d/x` all identify the same page — llms.txt links the markdown file
58
+ * while llms-full.txt markers carry the canonical HTML url.
59
+ */
60
+ export declare function normalizeUrl(url: string): string;