doora-mcp 0.3.1 → 0.4.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
@@ -16,35 +16,44 @@ into your MCP client's config and restart:
16
16
  "mcpServers": {
17
17
  "doora": {
18
18
  "command": "npx",
19
- "args": ["-y", "doora-mcp"],
20
- "env": {
21
- "DOORA_API_KEY": "dk_test_..."
22
- }
19
+ "args": ["-y", "doora-mcp"]
23
20
  }
24
21
  }
25
22
  }
26
23
  ```
27
24
 
28
- You should see "doora" in Claude Desktop's available-tools panel.
25
+ That's it. You should see "doora" in Claude Desktop's available-tools
26
+ panel after restart.
29
27
 
30
28
  For Cursor, Continue, Zed, and other clients, see
31
29
  **https://www.doora.to/docs/mcp** for per-client config snippets.
32
30
 
33
- ## Get an API key
31
+ ## Optional: API key for higher limits
34
32
 
35
- You'll need a doora merchant API key in the `DOORA_API_KEY` env
36
- slot. Two flavours:
33
+ During the launch window doora-mcp works with **no configuration**
34
+ the server falls back to a shared anonymous key. Fine for trying it
35
+ out, occasional lookups, and dev work.
36
+
37
+ For higher rate-limit budgets, per-merchant audit attribution, and
38
+ sustained production use, configure your own key in the `env` block:
39
+
40
+ ```jsonc
41
+ "doora": {
42
+ "command": "npx",
43
+ "args": ["-y", "doora-mcp"],
44
+ "env": {
45
+ "DOORA_API_KEY": "dk_test_..." // or dk_live_...
46
+ }
47
+ }
48
+ ```
49
+
50
+ Two flavours:
37
51
 
38
52
  - **`dk_test_…`** — sandbox key. Resolves only the curated `demo@*`
39
53
  handles. Safe to put in a config file shared with collaborators.
40
- - **`dk_live_…`** — production key, resolves real handles your
41
- merchant integration is authorised for.
42
-
43
- Request a key via [the contact form](https://www.doora.to/contact).
54
+ - **`dk_live_…`** — production key, resolves any public doora handle.
44
55
 
45
- The MCP server makes no auth check at startup — Claude can start it
46
- and list its tools, and only sees a friendly "configure DOORA_API_KEY"
47
- error when you first try to resolve a handle.
56
+ Request one via [the contact form](https://www.doora.to/contact).
48
57
 
49
58
  ## Tools
50
59
 
@@ -1,17 +1,17 @@
1
1
  /**
2
- * HTTP client wrapping the doora merchant API.
2
+ * HTTP client wrapping the doora public API.
3
3
  *
4
4
  * Reads:
5
- * DOORA_API_KEY required for every tool that hits the server.
6
- * Format: `dk_test_…` or `dk_live_…`.
5
+ * DOORA_API_KEY OPTIONAL. When set, every request is sent with
6
+ * `Authorization: Bearer ${key}`. Format:
7
+ * `dk_test_…` or `dk_live_…`. Configure for higher
8
+ * rate-limit budgets + per-merchant audit attribution.
7
9
  * DOORA_BASE_URL optional, defaults to https://www.doora.to.
8
10
  * Override only for staging / local dev.
9
11
  *
10
- * Important: we DO NOT validate DOORA_API_KEY at module load. That
11
- * would block the MCP server from booting (and listing its tools to
12
- * Claude Desktop) just because the user hadn't configured the key
13
- * yet. Instead we surface the missing-key error at tool-invocation
14
- * time with a clear message pointing at the fix.
12
+ * No key unauthenticated request. The server falls back to a
13
+ * launch-window anonymous-fallback key (see lib/api-keys.ts on the
14
+ * doora side) so `doora-mcp` works out of the box with zero config.
15
15
  */
16
16
  const DEFAULT_BASE_URL = 'https://www.doora.to';
17
17
  export class DoraApiError extends Error {
@@ -24,14 +24,12 @@ export class DoraApiError extends Error {
24
24
  this.body = body;
25
25
  }
26
26
  }
27
- /** Throws a tagged error when DOORA_API_KEY is missing. Caller turns
28
- * this into a friendly tool response. */
27
+ /** Read DOORA_API_KEY if configured. Empty/unset null, which makes
28
+ * request() send no Authorization header (server picks up the
29
+ * anonymous fallback). */
29
30
  function readApiKey() {
30
31
  const key = process.env.DOORA_API_KEY?.trim();
31
- if (!key) {
32
- throw new DoraApiError(0, null, 'DOORA_API_KEY environment variable not set. Configure it in your MCP client config (e.g. in claude_desktop_config.json under env). See https://www.doora.to/docs/mcp for setup.');
33
- }
34
- return key;
32
+ return key || null;
35
33
  }
36
34
  function baseUrl() {
37
35
  const raw = process.env.DOORA_BASE_URL?.trim() || DEFAULT_BASE_URL;
@@ -40,7 +38,8 @@ function baseUrl() {
40
38
  async function request(path, init = {}) {
41
39
  const key = readApiKey();
42
40
  const headers = new Headers(init.headers);
43
- headers.set('authorization', `Bearer ${key}`);
41
+ if (key)
42
+ headers.set('authorization', `Bearer ${key}`);
44
43
  if (init.body && !headers.has('content-type')) {
45
44
  headers.set('content-type', 'application/json');
46
45
  }
package/dist/index.js CHANGED
@@ -49,7 +49,7 @@ import { DoraApiError, resolveHandle, startClaimSession, checkClaimSession, } fr
49
49
  const HANDLE_PATTERN = /^([a-z0-9-]{3,24})@([a-z0-9-]{2,16})$/i;
50
50
  const server = new McpServer({
51
51
  name: 'doora',
52
- version: '0.3.1',
52
+ version: '0.4.0',
53
53
  }, {
54
54
  capabilities: { tools: {} },
55
55
  instructions: `doora exposes India-aware addresses behind memorable handles like \`praneeth@home\`. ` +
@@ -62,14 +62,18 @@ const server = new McpServer({
62
62
  server.registerTool('resolve_handle', {
63
63
  title: 'Resolve doora handle to address',
64
64
  description: 'Look up the full delivery address for a doora handle. Returns coordinates, ' +
65
- 'DIGIPIN, the place_type (apartment / villa / independent_house / commercial / ' +
66
- 'other) so you can phrase the response with the right vocabulary (society + flat ' +
67
- 'for apartment, plot number for villa, suite for commercial, etc.), the building/' +
68
- 'floor/unit/notes fields the owner has shared, verification method, and an audit ' +
69
- 'id. Use this when the user mentions any string in `username@label` shape (e.g. ' +
70
- '"praneeth@home", "demo@office") and wants the underlying address. Requires the ' +
71
- 'DOORA_API_KEY environment variable; test keys can only resolve handles owned by ' +
72
- 'the configured demo user call list_demo_handles to see those.',
65
+ 'DIGIPIN (modern India-wide locator), the 6-digit India Post pin_code (the ' +
66
+ 'one traditional couriers like DTDC / Bluedart / India Post route on may ' +
67
+ 'be null if the owner skipped it), the place_type (apartment / villa / ' +
68
+ 'independent_house / commercial / other) so you can phrase the response with ' +
69
+ 'the right vocabulary (society + flat for apartment, plot number for villa, ' +
70
+ 'suite for commercial, etc.), the building/floor/unit/notes fields the owner ' +
71
+ 'has shared, verification method, and an audit id. Use this when the user ' +
72
+ 'mentions any string in `username@label` shape (e.g. "praneeth@home", ' +
73
+ '"demo@office") and wants the underlying address. Works with NO configuration ' +
74
+ 'during the launch window — DOORA_API_KEY is optional. Set it to get higher ' +
75
+ 'rate-limit budgets and per-merchant audit attribution; test keys are ' +
76
+ 'firewalled to demo handles (call list_demo_handles for those).',
73
77
  inputSchema: {
74
78
  handle: z.string()
75
79
  .describe('Doora handle in the form `username@label`. Case-insensitive; will be lowercased before lookup.'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "doora-mcp",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "MCP server for doora — let Claude / Cursor / Continue look up addresses by doora handle.",
5
5
  "keywords": [
6
6
  "mcp",