@drupalmcp/adk 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -37,9 +37,16 @@ unreachable. `drupalTools()` rewrites both on the way through. You can use
37
37
  the rewrite on its own with `normaliseSchema()`.
38
38
 
39
39
  **Explains a refusal.** A call the credential may not make comes back as
40
- HTTP 403 with a challenge naming the missing scope. The MCP client drops
41
- that header, so the library keeps it and gives the model a sentence that
42
- says what happened and that retrying will not help.
40
+ HTTP 403 with a challenge naming the missing scope. That header is dropped
41
+ before the error reaches you, so the library keeps it and gives the model a
42
+ sentence that says what happened and that retrying will not help.
43
+
44
+ **Resolves its dependencies once, at import.** The tools are built on the
45
+ protocol SDK directly rather than on the agent kit's own MCP toolset, which
46
+ looks the SDK up lazily at the first tool call from whatever directory it
47
+ happens to be running in. That lookup fails inside the dev server's temporary
48
+ build folder, reporting a missing dependency that is sitting in
49
+ `node_modules`. Importing at the top of the file cannot fail that way.
43
50
 
44
51
  ## Agents defined in Drupal
45
52
 
@@ -65,13 +72,25 @@ is how a tone-of-voice rule reaches an agent running outside Drupal.
65
72
  long a definition is reused; it defaults to ten seconds and zero re-reads
66
73
  every turn.
67
74
 
75
+ If the site has no such agent, the call refuses and says where to look rather
76
+ than failing obscurely. Keep these agents in their own folder: the ADK dev
77
+ server loads every agent in the directory you point it at, and one that cannot
78
+ reach its definition will report that at startup.
79
+
68
80
  ## Choosing what the agent can reach
69
81
 
70
82
  ```ts
71
83
  drupalTools({ auth, only: ['tool_api__tool_belt_entity_list'] });
84
+ drupalTools({ auth, except: ['tool_api__tool_belt_entity_bundle_list'] });
72
85
  ```
73
86
 
74
- `only` narrows the tool list. It is a convenience, not a boundary: what the
75
- agent may actually do is decided by the credential's scopes on the server.
87
+ `only` narrows the tool list and `except` removes from it. Both are a
88
+ convenience, not a boundary: what the agent may actually do is decided by the
89
+ credential's scopes on the server.
90
+
91
+ `except` earns its keep for a tool the site publishes that this credential can
92
+ never run. Listing a content type's bundles, for instance, needs an
93
+ administrator permission an agent should not have, so offering the tool only
94
+ invites a refusal in the middle of a job.
76
95
 
77
96
  Apache-2.0. Part of [drupalmcp-ts](https://github.com/Omedia/drupalmcp-ts).
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { MCPToolset } from '@google/adk/tools/mcp';
2
- import { LlmAgent } from '@google/adk';
1
+ import { BaseToolset, ReadonlyContext, BaseTool, LlmAgent } from '@google/adk';
3
2
 
4
3
  /**
5
4
  * OAuth 2 client credentials against a Drupal site running drupal/mcp.
@@ -59,6 +58,14 @@ declare class DrupalOAuth {
59
58
 
60
59
  /**
61
60
  * The Drupal site's MCP tools, ready to hand to an ADK agent.
61
+ *
62
+ * These are built on the protocol SDK directly rather than on the agent kit's
63
+ * own MCP toolset. The kit resolves the SDK lazily at the moment of the first
64
+ * tool call, from whatever directory it happens to be running in, and when its
65
+ * dev server transpiles an agent into a temporary folder that lookup can fail
66
+ * with a message claiming the SDK is not installed. Importing it here, at the
67
+ * top of the file, means it is resolved once when this module loads, and
68
+ * bundled with the agent by anything that bundles.
62
69
  */
63
70
 
64
71
  interface DrupalToolsOptions {
@@ -72,6 +79,12 @@ interface DrupalToolsOptions {
72
79
  * site publishes; the credential's scopes still decide what may run.
73
80
  */
74
81
  only?: string[];
82
+ /**
83
+ * Leave these tools out. Useful for a tool the site publishes but this
84
+ * credential can never run, such as one that needs an administrator
85
+ * permission: offering it only invites a refusal mid-conversation.
86
+ */
87
+ except?: string[];
75
88
  /** Prefix added to every tool name, for telling two sites apart. */
76
89
  prefix?: string;
77
90
  }
@@ -80,10 +93,41 @@ interface DrupalToolsOptions {
80
93
  *
81
94
  * The bearer token is attached per request rather than frozen into the
82
95
  * transport, so a token expiring mid-conversation is replaced without the
83
- * agent noticing. Tool schemas are rewritten on the way through; see
84
- * {@link normaliseSchema}.
96
+ * agent noticing.
85
97
  */
86
- declare function drupalTools(options: DrupalToolsOptions): MCPToolset;
98
+ declare function drupalTools(options: DrupalToolsOptions): DrupalToolset;
99
+ /**
100
+ * An ADK toolset backed by one MCP session against a Drupal site.
101
+ */
102
+ declare class DrupalToolset extends BaseToolset {
103
+ private readonly baseUrl;
104
+ private readonly auth;
105
+ private readonly only;
106
+ private readonly except;
107
+ private readonly namePrefix;
108
+ /** The last authentication challenge the site sent, if any. */
109
+ private challenge;
110
+ private client;
111
+ private connecting;
112
+ constructor(options: DrupalToolsOptions);
113
+ /**
114
+ * {@inheritdoc}
115
+ */
116
+ getTools(_context?: ReadonlyContext): Promise<BaseTool[]>;
117
+ /**
118
+ * {@inheritdoc}
119
+ */
120
+ close(): Promise<void>;
121
+ /**
122
+ * Runs one tool, translating a refusal into something the model can use.
123
+ *
124
+ * @internal
125
+ */
126
+ call(name: string, args: Record<string, unknown>): Promise<unknown>;
127
+ /** The connected client, opening the session on first use. */
128
+ private connect;
129
+ private open;
130
+ }
87
131
 
88
132
  /**
89
133
  * Agents defined in Drupal, running in ADK.
@@ -203,6 +247,6 @@ declare function scopeFromChallenge(challenge: string | null | undefined): strin
203
247
  declare function describeRefusal(error: unknown): string | null;
204
248
 
205
249
  /** Kept in step with package.json; sent as the user agent. */
206
- declare const VERSION = "0.1.0";
250
+ declare const VERSION = "0.2.0";
207
251
 
208
252
  export { AUTHENTICATION_REQUIRED_CODE, type AgentDefinition, type AgentSummary, type DrupalAgentOptions, DrupalOAuth, type DrupalOAuthOptions, type DrupalToolsOptions, INSUFFICIENT_SCOPE_CODE, type JsonSchema, VERSION, describeRefusal, drupalAgent, drupalTools, listAgents, normaliseSchema, promptFrom, scopeFromChallenge };