@agentmanifest/mcp-server 0.0.0-stage → 0.1.2

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 (45) hide show
  1. package/README.md +212 -2
  2. package/dist/create-server.d.ts +3 -0
  3. package/dist/create-server.d.ts.map +1 -0
  4. package/dist/create-server.js +95 -0
  5. package/dist/create-server.js.map +1 -0
  6. package/dist/http.d.ts +3 -0
  7. package/dist/http.d.ts.map +1 -0
  8. package/dist/http.js +74 -0
  9. package/dist/http.js.map +1 -0
  10. package/dist/index.d.ts +3 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +13 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/lib/__tests__/check-permissions.test.d.ts +2 -0
  15. package/dist/lib/__tests__/check-permissions.test.d.ts.map +1 -0
  16. package/dist/lib/__tests__/check-permissions.test.js +29 -0
  17. package/dist/lib/__tests__/check-permissions.test.js.map +1 -0
  18. package/dist/lib/check-permissions.d.ts +13 -0
  19. package/dist/lib/check-permissions.d.ts.map +1 -0
  20. package/dist/lib/check-permissions.js +188 -0
  21. package/dist/lib/check-permissions.js.map +1 -0
  22. package/dist/lib/fetch-manifest.d.ts +5 -0
  23. package/dist/lib/fetch-manifest.d.ts.map +1 -0
  24. package/dist/lib/fetch-manifest.js +74 -0
  25. package/dist/lib/fetch-manifest.js.map +1 -0
  26. package/dist/lib/resolve-manifest-url.d.ts +5 -0
  27. package/dist/lib/resolve-manifest-url.d.ts.map +1 -0
  28. package/dist/lib/resolve-manifest-url.js +8 -0
  29. package/dist/lib/resolve-manifest-url.js.map +1 -0
  30. package/dist/lib/schemas.d.ts +3 -0
  31. package/dist/lib/schemas.d.ts.map +1 -0
  32. package/dist/lib/schemas.js +8 -0
  33. package/dist/lib/schemas.js.map +1 -0
  34. package/dist/lib/types.d.ts +84 -0
  35. package/dist/lib/types.d.ts.map +1 -0
  36. package/dist/lib/types.js +2 -0
  37. package/dist/lib/types.js.map +1 -0
  38. package/dist/lib/validate-syntax.d.ts +3 -0
  39. package/dist/lib/validate-syntax.d.ts.map +1 -0
  40. package/dist/lib/validate-syntax.js +52 -0
  41. package/dist/lib/validate-syntax.js.map +1 -0
  42. package/package.json +62 -4
  43. package/schemas/v0.2/manifest.json +290 -0
  44. package/schemas/v0.3/manifest.json +488 -0
  45. package/smithery.yaml +31 -0
package/README.md CHANGED
@@ -1,3 +1,213 @@
1
- # Temporary Holding Version
1
+ # Agent Manifest Protocol (AMP) — Official MCP Server
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![MCP](https://img.shields.io/badge/MCP-Model%20Context%20Protocol-6366f1)](https://modelcontextprotocol.io)
4
+ [![AMP](https://img.shields.io/badge/AMP-v0.3-0ea5e9)](https://agent-manifest.com)
5
+
6
+ Turn AMP’s **static web discovery** (`/.well-known/agent-manifest.json`) into **runtime MCP tools** so any LLM client (Claude Desktop, Cursor, Smithery, etc.) can discover APIs, validate manifests, and reason about legal/operational boundaries before calling them.
7
+
8
+ ## How AMP complements MCP
9
+
10
+ | Layer | Role |
11
+ | --- | --- |
12
+ | **MCP** | Transport and tool surface between the model and your server |
13
+ | **AMP** | Publisher-hosted manifest describing endpoints, auth, pricing/payment, rate limits, and `agent_notes` for autonomous agents |
14
+
15
+ This server does **not** replace calling third-party APIs. It helps agents **decide whether and how** to call them in line with the publisher’s declared contract.
16
+
17
+ ## Tools
18
+
19
+ ### `fetch_manifest_by_domain`
20
+
21
+ Fetches and parses a manifest from an API origin.
22
+
23
+ **Input**
24
+
25
+ ```json
26
+ {
27
+ "domain": "bakebase.agent-manifest.com"
28
+ }
29
+ ```
30
+
31
+ **Behavior**
32
+
33
+ 1. Normalizes the host (strips scheme/path).
34
+ 2. Tries, in order:
35
+ - `/.well-known/agent-manifest.json` (canonical, RFC 8615)
36
+ - `/.well-known/amp.json`
37
+ - `/agent-manifest.json`
38
+ 3. Returns `manifest`, `manifest_url`, `origin`, and `tried_urls`.
39
+
40
+ ### `validate_manifest_syntax`
41
+
42
+ Validates JSON against the official AMP schema for `agentmanifest-0.2` or `agentmanifest-0.3`.
43
+
44
+ **Input (object)**
45
+
46
+ ```json
47
+ {
48
+ "manifest": {
49
+ "spec_version": "agentmanifest-0.3",
50
+ "name": "My API",
51
+ "...": "..."
52
+ }
53
+ }
54
+ ```
55
+
56
+ **Input (string)**
57
+
58
+ ```json
59
+ {
60
+ "manifest": "{\"spec_version\":\"agentmanifest-0.3\",...}"
61
+ }
62
+ ```
63
+
64
+ **Output**
65
+
66
+ - `valid: true` → `success_token` like `amp-schema-valid:agentmanifest-0.3:My API`
67
+ - `valid: false` → `errors[]` with AJV paths/messages
68
+
69
+ ### `check_agent_permissions`
70
+
71
+ Checks an intended HTTP operation against a manifest’s declared endpoints and constraints.
72
+
73
+ **Input**
74
+
75
+ ```json
76
+ {
77
+ "action": "POST /baking/validate-mix",
78
+ "manifest": { "...": "full manifest object from fetch_manifest_by_domain" },
79
+ "intends_unauthenticated": false,
80
+ "payment_onboarded": false
81
+ }
82
+ ```
83
+
84
+ **Output**
85
+
86
+ - `verdict`: `compliant` | `violation` | `warning` | `unknown`
87
+ - `findings[]`: structured codes (`endpoint_not_declared`, `auth_required`, `payment_onboarding`, `agent_notes_usage_restriction`, …)
88
+ - `matched_endpoint` when a declared route matches (including `{id}` templates)
89
+
90
+ ## Install & run locally
91
+
92
+ ### Prerequisites
93
+
94
+ - Node.js **18+**
95
+ - Build the validator dependency once (local monorepo path):
96
+
97
+ ```bash
98
+ cd agentmanifest/amp-mcp && npm install && npm run build
99
+ # or from monorepo root:
100
+ cd agentmanifest && npm install && npm run build --workspace=amp-mcp
101
+ ```
102
+
103
+ ### Stdio (Cursor, Claude Desktop, CI)
104
+
105
+ ```bash
106
+ npx @agentmanifest/mcp-server
107
+ # or after linking locally:
108
+ node dist/index.js
109
+ ```
110
+
111
+ ### SSE HTTP hub (remote / agent-manifest.com)
112
+
113
+ ```bash
114
+ PORT=8787 HOST=0.0.0.0 npm run start
115
+ # GET http://localhost:8787/mcp — establish SSE stream
116
+ # POST http://localhost:8787/messages?sessionId=... — JSON-RPC from client
117
+ ```
118
+
119
+ Environment variables:
120
+
121
+ | Variable | Default | Purpose |
122
+ | --- | --- | --- |
123
+ | `PORT` | `8787` | HTTP listen port |
124
+ | `HOST` | `0.0.0.0` | Bind address |
125
+ | `AMP_MCP_SSE_PATH` | `/mcp` | SSE endpoint |
126
+ | `AMP_MCP_MESSAGES_PATH` | `/messages` | POST endpoint |
127
+ | `AMP_ALLOWED_HOSTS` | `agent-manifest.com,...` | Host header allow list |
128
+ | `AMP_FETCH_TIMEOUT_MS` | `15000` | Manifest fetch timeout |
129
+
130
+ > **Note:** The MCP SDK marks legacy **HTTP+SSE** as deprecated in favor of Streamable HTTP. This package implements **SSE** as requested for broad client compatibility; you can add Streamable HTTP alongside later using `StreamableHTTPServerTransport`.
131
+
132
+ ## Claude Desktop configuration
133
+
134
+ Add to `claude_desktop_config.json` (macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`):
135
+
136
+ ```json
137
+ {
138
+ "mcpServers": {
139
+ "agent-manifest-protocol": {
140
+ "command": "node",
141
+ "args": ["/absolute/path/to/AMP/amp-mcp/dist/index.js"],
142
+ "env": {
143
+ "AMP_FETCH_TIMEOUT_MS": "15000"
144
+ }
145
+ }
146
+ }
147
+ }
148
+ ```
149
+
150
+ After publishing to npm, replace with:
151
+
152
+ ```json
153
+ {
154
+ "mcpServers": {
155
+ "agent-manifest-protocol": {
156
+ "command": "npx",
157
+ "args": ["-y", "@agentmanifest/mcp-server"]
158
+ }
159
+ }
160
+ }
161
+ ```
162
+
163
+ ## Cursor
164
+
165
+ **Settings → MCP → Add server → Command:**
166
+
167
+ - Command: `node`
168
+ - Args: `/path/to/amp-mcp/dist/index.js`
169
+
170
+ Or use `npx -y @agentmanifest/mcp-server` once published.
171
+
172
+ ## Smithery
173
+
174
+ This repo includes [`smithery.yaml`](./smithery.yaml) for one-command Smithery installs. Point Smithery at this package directory or published GitHub repo; optional env:
175
+
176
+ - `AMP_FETCH_TIMEOUT_MS`
177
+ - `AMP_VALIDATOR_URL` (reserved for future remote validation helpers)
178
+
179
+ ## Registries (official MCP Registry, Smithery, npm)
180
+
181
+ Docs: **[REGISTRY.md](./REGISTRY.md)** and **[modelcontextprotocol.io/registry/about](https://modelcontextprotocol.io/registry/about)**.
182
+
183
+ The MCP Registry holds **metadata** (`server.json`); npm holds the package; Railway holds the remote URL. Host apps often discover you via **aggregators** that sync the registry — not by scraping your site.
184
+
185
+ ```bash
186
+ brew install mcp-publisher # see registry quickstart
187
+ cd amp-mcp
188
+ # package.json mcpName must match server.json "name"
189
+ mcp-publisher login github # or DNS/HTTP for com.agent-manifest/*
190
+ mcp-publisher publish
191
+ ```
192
+
193
+ ## Development
194
+
195
+ ```bash
196
+ npm run dev # SSE server with tsx watch
197
+ npm run dev:stdio # stdio server
198
+ npm test
199
+ ```
200
+
201
+ ## Architecture
202
+
203
+ ```mermaid
204
+ flowchart LR
205
+ LLM[LLM Client] -->|stdio or SSE| MCP[AMP MCP Server]
206
+ MCP -->|HTTPS GET| Origin["API origin /.well-known/agent-manifest.json"]
207
+ MCP -->|AJV| Schema[AMP JSON Schema v0.2/v0.3]
208
+ MCP -->|rules engine| Perms[check_agent_permissions]
209
+ ```
210
+
211
+ ## License
212
+
213
+ MIT © Agent Manifest Protocol
@@ -0,0 +1,3 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function createAmpMcpServer(): McpServer;
3
+ //# sourceMappingURL=create-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-server.d.ts","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAWpE,wBAAgB,kBAAkB,IAAI,SAAS,CAiH9C"}
@@ -0,0 +1,95 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import * as z from 'zod';
3
+ import { fetchManifestByDomain } from './lib/fetch-manifest.js';
4
+ import { validateManifestSyntax } from './lib/validate-syntax.js';
5
+ import { checkAgentPermissions } from './lib/check-permissions.js';
6
+ const manifestObjectSchema = z
7
+ .record(z.unknown())
8
+ .describe('Parsed AMP manifest object (agentmanifest-0.2 or agentmanifest-0.3).');
9
+ export function createAmpMcpServer() {
10
+ const server = new McpServer({
11
+ name: 'agent-manifest-protocol',
12
+ version: '0.1.0',
13
+ }, {
14
+ instructions: [
15
+ 'You are connected to the official Agent Manifest Protocol (AMP) MCP server.',
16
+ 'Use fetch_manifest_by_domain to discover /.well-known/agent-manifest.json (and fallbacks) for any API origin.',
17
+ 'Use validate_manifest_syntax before trusting manifest JSON.',
18
+ 'Use check_agent_permissions before calling an API operation to see if it matches declared endpoints, auth, payment, and agent_notes constraints.',
19
+ 'AMP complements MCP: MCP carries tools; AMP declares what remote agents/APIs allow, cost, and how to authenticate.',
20
+ ].join(' '),
21
+ });
22
+ server.registerTool('fetch_manifest_by_domain', {
23
+ title: 'Fetch AMP manifest by domain',
24
+ description: 'Resolve an API origin from a domain (e.g. "bakebase.agent-manifest.com"), try standard AMP discovery URLs, and return parsed manifest JSON plus metadata.',
25
+ inputSchema: {
26
+ domain: z
27
+ .string()
28
+ .min(1)
29
+ .describe('API hostname or URL origin without a path, e.g. "example.com", "api.example.com", or "https://bakebase.agent-manifest.com".'),
30
+ },
31
+ }, async ({ domain }) => {
32
+ const result = await fetchManifestByDomain(domain);
33
+ return {
34
+ content: [
35
+ {
36
+ type: 'text',
37
+ text: JSON.stringify(result, null, 2),
38
+ },
39
+ ],
40
+ };
41
+ });
42
+ server.registerTool('validate_manifest_syntax', {
43
+ title: 'Validate AMP manifest JSON Schema',
44
+ description: 'Validate a manifest JSON string or object against the official AMP JSON Schema for its spec_version (agentmanifest-0.2 or agentmanifest-0.3). Returns errors or a success_token.',
45
+ inputSchema: {
46
+ manifest: z
47
+ .union([z.string(), manifestObjectSchema])
48
+ .describe('Either a JSON string of the manifest, or a parsed manifest object with spec_version, name, endpoints, etc.'),
49
+ },
50
+ }, async ({ manifest }) => {
51
+ const result = validateManifestSyntax(manifest);
52
+ return {
53
+ content: [
54
+ {
55
+ type: 'text',
56
+ text: JSON.stringify(result, null, 2),
57
+ },
58
+ ],
59
+ };
60
+ });
61
+ server.registerTool('check_agent_permissions', {
62
+ title: 'Check action against AMP manifest constraints',
63
+ description: 'Given an intended HTTP action (method + path or full URL) and a manifest, determine whether the action aligns with declared endpoints, authentication, payment onboarding, rate limits, and language in agent_notes.',
64
+ inputSchema: {
65
+ action: z
66
+ .string()
67
+ .min(1)
68
+ .describe('Intended operation, e.g. "POST /baking/validate-mix", "GET /health", or "POST https://api.example.com/v1/search".'),
69
+ manifest: manifestObjectSchema,
70
+ intends_unauthenticated: z
71
+ .boolean()
72
+ .optional()
73
+ .describe('Set true if the agent plans to call the API without credentials.'),
74
+ payment_onboarded: z
75
+ .boolean()
76
+ .optional()
77
+ .describe('Set true if AMP payment onboarding is already complete for this API.'),
78
+ },
79
+ }, async ({ action, manifest, intends_unauthenticated, payment_onboarded }) => {
80
+ const result = checkAgentPermissions(action, manifest, {
81
+ intends_unauthenticated,
82
+ payment_onboarded,
83
+ });
84
+ return {
85
+ content: [
86
+ {
87
+ type: 'text',
88
+ text: JSON.stringify(result, null, 2),
89
+ },
90
+ ],
91
+ };
92
+ });
93
+ return server;
94
+ }
95
+ //# sourceMappingURL=create-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-server.js","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"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"}
package/dist/http.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":""}
package/dist/http.js ADDED
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+ import { createMcpExpressApp } from '@modelcontextprotocol/sdk/server/express.js';
3
+ import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
4
+ import { createAmpMcpServer } from './create-server.js';
5
+ const MCP_SSE_PATH = process.env.AMP_MCP_SSE_PATH ?? '/mcp';
6
+ const MCP_MESSAGES_PATH = process.env.AMP_MCP_MESSAGES_PATH ?? '/messages';
7
+ const PORT = Number.parseInt(process.env.PORT ?? '8787', 10);
8
+ const HOST = process.env.HOST ?? '0.0.0.0';
9
+ const ALLOWED_HOSTS = process.env.AMP_ALLOWED_HOSTS
10
+ ? process.env.AMP_ALLOWED_HOSTS.split(',').map((h) => h.trim()).filter(Boolean)
11
+ : ['agent-manifest.com', 'www.agent-manifest.com', 'localhost', '127.0.0.1'];
12
+ const transports = {};
13
+ const app = createMcpExpressApp({
14
+ host: HOST,
15
+ allowedHosts: ALLOWED_HOSTS,
16
+ });
17
+ app.get('/health', (_req, res) => {
18
+ res.json({ ok: true, service: 'amp-mcp', transport: 'sse' });
19
+ });
20
+ app.get(MCP_SSE_PATH, async (req, res) => {
21
+ try {
22
+ const transport = new SSEServerTransport(MCP_MESSAGES_PATH, res);
23
+ const sessionId = transport.sessionId;
24
+ transports[sessionId] = transport;
25
+ transport.onclose = () => {
26
+ delete transports[sessionId];
27
+ };
28
+ const server = createAmpMcpServer();
29
+ await server.connect(transport);
30
+ }
31
+ catch (error) {
32
+ console.error('SSE connection error:', error);
33
+ if (!res.headersSent) {
34
+ res.status(500).send('Failed to establish SSE stream');
35
+ }
36
+ }
37
+ });
38
+ app.post(MCP_MESSAGES_PATH, async (req, res) => {
39
+ const sessionId = req.query.sessionId;
40
+ if (typeof sessionId !== 'string' || !sessionId) {
41
+ res.status(400).send('Missing sessionId query parameter');
42
+ return;
43
+ }
44
+ const transport = transports[sessionId];
45
+ if (!transport) {
46
+ res.status(404).send('Unknown session');
47
+ return;
48
+ }
49
+ try {
50
+ await transport.handlePostMessage(req, res, req.body);
51
+ }
52
+ catch (error) {
53
+ console.error('Message handling error:', error);
54
+ if (!res.headersSent) {
55
+ res.status(500).send('Error handling MCP message');
56
+ }
57
+ }
58
+ });
59
+ app.listen(PORT, HOST, () => {
60
+ console.log(`AMP MCP (SSE) listening on http://${HOST}:${PORT} — SSE GET ${MCP_SSE_PATH}, POST ${MCP_MESSAGES_PATH}`);
61
+ });
62
+ process.on('SIGINT', async () => {
63
+ for (const id of Object.keys(transports)) {
64
+ try {
65
+ await transports[id].close();
66
+ }
67
+ catch {
68
+ /* ignore */
69
+ }
70
+ delete transports[id];
71
+ }
72
+ process.exit(0);
73
+ });
74
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { createAmpMcpServer } from './create-server.js';
4
+ async function main() {
5
+ const server = createAmpMcpServer();
6
+ const transport = new StdioServerTransport();
7
+ await server.connect(transport);
8
+ }
9
+ main().catch((err) => {
10
+ console.error('AMP MCP server failed:', err);
11
+ process.exit(1);
12
+ });
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;IACpC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=check-permissions.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-permissions.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/check-permissions.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { checkAgentPermissions, parseAction } from '../check-permissions.js';
3
+ import { validateManifestSyntax } from '../validate-syntax.js';
4
+ import { readFileSync } from 'node:fs';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { dirname, join } from 'node:path';
7
+ const fixture = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), '../../../../validator/fixtures/v03-free-valid.json'), 'utf-8'));
8
+ describe('parseAction', () => {
9
+ it('parses method and path', () => {
10
+ expect(parseAction('POST /baking/validate-mix')).toEqual({
11
+ method: 'POST',
12
+ path: '/baking/validate-mix',
13
+ });
14
+ });
15
+ });
16
+ describe('checkAgentPermissions', () => {
17
+ const manifest = fixture;
18
+ it('flags undeclared endpoints', () => {
19
+ const result = checkAgentPermissions('GET /not-in-manifest', manifest);
20
+ expect(result.verdict).toBe('violation');
21
+ expect(result.findings.some((f) => f.code === 'endpoint_not_declared')).toBe(true);
22
+ });
23
+ it('validates fixture syntax', () => {
24
+ const syntax = validateManifestSyntax(manifest);
25
+ expect(syntax.valid).toBe(true);
26
+ expect(syntax.success_token).toMatch(/^amp-schema-valid:/);
27
+ });
28
+ });
29
+ //# sourceMappingURL=check-permissions.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-permissions.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/check-permissions.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CACxB,YAAY,CACV,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,oDAAoD,CAAC,EACnG,OAAO,CACR,CACyB,CAAC;AAE7B,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,WAAW,CAAC,2BAA2B,CAAC,CAAC,CAAC,OAAO,CAAC;YACvD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,sBAAsB;SAC7B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,MAAM,QAAQ,GAAG,OAAkC,CAAC;IAEpD,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,MAAM,GAAG,qBAAqB,CAAC,sBAAsB,EAAE,QAAQ,CAAC,CAAC;QACvE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,MAAM,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { AmpManifest, PermissionCheckResult } from './types.js';
2
+ export declare function parseAction(action: string): {
3
+ method: string | null;
4
+ path: string | null;
5
+ };
6
+ export interface CheckPermissionsOptions {
7
+ /** If true, treat unauthenticated access as a violation when auth is required. */
8
+ intends_unauthenticated?: boolean;
9
+ /** If true, agent claims payment/onboarding is already complete. */
10
+ payment_onboarded?: boolean;
11
+ }
12
+ export declare function checkAgentPermissions(action: string, manifest: AmpManifest, options?: CheckPermissionsOptions): PermissionCheckResult;
13
+ //# sourceMappingURL=check-permissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-permissions.d.ts","sourceRoot":"","sources":["../../src/lib/check-permissions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAqB,MAAM,YAAY,CAAC;AA8BxF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAuB1F;AAsDD,MAAM,WAAW,uBAAuB;IACtC,kFAAkF;IAClF,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,WAAW,EACrB,OAAO,GAAE,uBAA4B,GACpC,qBAAqB,CA8GvB"}