@anyproto/anytype-mcp 1.0.3 → 1.0.5

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.
@@ -8,6 +8,9 @@ on:
8
8
  branches:
9
9
  - "**"
10
10
 
11
+ permissions:
12
+ contents: read
13
+
11
14
  jobs:
12
15
  lint:
13
16
  runs-on: ubuntu-latest
@@ -3,7 +3,11 @@ name: Create release and publish to npmjs.com
3
3
  on:
4
4
  push:
5
5
  tags:
6
- - 'v[0-9]+.[0-9]+.[0-9]+'
6
+ - "v[0-9]+.[0-9]+.[0-9]+"
7
+
8
+ permissions:
9
+ contents: write
10
+ packages: write
7
11
 
8
12
  jobs:
9
13
  release:
@@ -30,7 +34,7 @@ jobs:
30
34
  env:
31
35
  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
32
36
 
33
- - name: create release
37
+ - name: Create Release
34
38
  uses: softprops/action-gh-release@v2
35
39
  with:
36
40
  name: ${{ github.ref_name }}
package/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Anytype MCP Server
2
2
 
3
- The Anytype MCP Server is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server implementation, enabling AI assistants to seamlessly interact with [Anytype's API](https://github.com/anyproto/anytype-api) through natural language.
3
+ <a href="https://npmjs.org/package/@anyproto/anytype-mcp"><img src="https://img.shields.io/npm/v/@anyproto/anytype-mcp.svg" alt="NPM version" height="20" /></a>
4
+ <a href="https://cursor.com/install-mcp?name=anytype&config=JTdCJTIyY29tbWFuZCUyMiUzQSUyMm5weCUyMC15JTIwJTQwYW55cHJvdG8lMkZhbnl0eXBlLW1jcCUyMiUyQyUyMmVudiUyMiUzQSU3QiUyMk9QRU5BUElfTUNQX0hFQURFUlMlMjIlM0ElMjIlN0IlNUMlMjJBdXRob3JpemF0aW9uJTVDJTIyJTNBJTVDJTIyQmVhcmVyJTIwJTNDWU9VUl9BUElfS0VZJTNFJTVDJTIyJTJDJTIwJTVDJTIyQW55dHlwZS1WZXJzaW9uJTVDJTIyJTNBJTVDJTIyMjAyNS0wNS0yMCU1QyUyMiU3RCUyMiU3RCU3RA%3D%3D"><img src="https://cursor.com/deeplink/mcp-install-dark.svg" alt="Add anytype MCP server to Cursor" height="20" /></a>
5
+ <a href="https://lmstudio.ai/install-mcp?name=anytype&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBhbnlwcm90by9hbnl0eXBlLW1jcCJdLCJlbnYiOnsiT1BFTkFQSV9NQ1BfSEVBREVSUyI6IntcIkF1dGhvcml6YXRpb25cIjpcIkJlYXJlciA8WU9VUl9BUElfS0VZPlwiLCBcIkFueXR5cGUtVmVyc2lvblwiOlwiMjAyNS0wNS0yMFwifSJ9fQ%3D%3D"><img src="https://files.lmstudio.ai/deeplink/mcp-install-light.svg" alt="Add MCP Server anytype to LM Studio" height="20" /></a>
6
+
7
+ The Anytype MCP Server is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server enabling AI assistants to seamlessly interact with [Anytype's API](https://github.com/anyproto/anytype-api) through natural language.
4
8
 
5
9
  It bridges the gap between AI and Anytype's powerful features by converting Anytype's OpenAPI specification into MCP tools, allowing you to manage your knowledge base through conversation.
6
10
 
@@ -17,9 +21,9 @@ It bridges the gap between AI and Anytype's powerful features by converting Anyt
17
21
  ### 1. Get Your API Key
18
22
 
19
23
  1. Open Anytype
20
- 2. Go to Settings
21
- 3. Navigate to API Keys
22
- 4. Create a new API key
24
+ 2. Go to App Settings
25
+ 3. Navigate to API Keys section
26
+ 4. Click on `Create new` button
23
27
 
24
28
  <details>
25
29
  <summary>Alternative: Get API key via CLI</summary>
@@ -50,6 +54,8 @@ Add the following configuration to your MCP client settings:
50
54
  }
51
55
  ```
52
56
 
57
+ > **Tip:** After creating an API key in Anytype, you can copy a ready-to-use configuration snippet with your API key already filled in from the API Keys section.
58
+
53
59
  <details>
54
60
  <summary>Alternative: Global Installation</summary>
55
61
 
package/bin/cli.mjs CHANGED
@@ -70,7 +70,7 @@ Add this to your MCP settings file as:`),console.log(`
70
70
  `}var gr=class{constructor(a=r2.stdin,t=r2.stdout){this._stdin=a,this._stdout=t,this._readBuffer=new xr,this._started=!1,this._ondata=i=>{this._readBuffer.append(i),this.processReadBuffer()},this._onerror=i=>{var n;(n=this.onerror)===null||n===void 0||n.call(this,i)}}async start(){if(this._started)throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror)}processReadBuffer(){for(var a,t;;)try{let i=this._readBuffer.readMessage();if(i===null)break;(a=this.onmessage)===null||a===void 0||a.call(this,i)}catch(i){(t=this.onerror)===null||t===void 0||t.call(this,i)}}async close(){var a;this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._stdin.listenerCount("data")===0&&this._stdin.pause(),this._readBuffer.clear(),(a=this.onclose)===null||a===void 0||a.call(this)}send(a){return new Promise(t=>{let i=n2(a);this._stdout.write(i)?t():this._stdout.once("drain",t)})}};import Dg from"node:fs";import Pg from"node:path";var I8=6e4,br=class{constructor(a){this._options=a,this._requestMessageId=0,this._requestHandlers=new Map,this._requestHandlerAbortControllers=new Map,this._notificationHandlers=new Map,this._responseHandlers=new Map,this._progressHandlers=new Map,this._timeoutInfo=new Map,this.setNotificationHandler(lr,t=>{let i=this._requestHandlerAbortControllers.get(t.params.requestId);i?.abort(t.params.reason)}),this.setNotificationHandler(mr,t=>{this._onprogress(t)}),this.setRequestHandler(cr,t=>({}))}_setupTimeout(a,t,i,n){this._timeoutInfo.set(a,{timeoutId:setTimeout(n,t),startTime:Date.now(),timeout:t,maxTotalTimeout:i,onTimeout:n})}_resetTimeout(a){let t=this._timeoutInfo.get(a);if(!t)return!1;let i=Date.now()-t.startTime;if(t.maxTotalTimeout&&i>=t.maxTotalTimeout)throw this._timeoutInfo.delete(a),new Ot(Ma.RequestTimeout,"Maximum total timeout exceeded",{maxTotalTimeout:t.maxTotalTimeout,totalElapsed:i});return clearTimeout(t.timeoutId),t.timeoutId=setTimeout(t.onTimeout,t.timeout),!0}_cleanupTimeout(a){let t=this._timeoutInfo.get(a);t&&(clearTimeout(t.timeoutId),this._timeoutInfo.delete(a))}async connect(a){this._transport=a,this._transport.onclose=()=>{this._onclose()},this._transport.onerror=t=>{this._onerror(t)},this._transport.onmessage=t=>{"method"in t?"id"in t?this._onrequest(t):this._onnotification(t):this._onresponse(t)},await this._transport.start()}_onclose(){var a;let t=this._responseHandlers;this._responseHandlers=new Map,this._progressHandlers.clear(),this._transport=void 0,(a=this.onclose)===null||a===void 0||a.call(this);let i=new Ot(Ma.ConnectionClosed,"Connection closed");for(let n of t.values())n(i)}_onerror(a){var t;(t=this.onerror)===null||t===void 0||t.call(this,a)}_onnotification(a){var t;let i=(t=this._notificationHandlers.get(a.method))!==null&&t!==void 0?t:this.fallbackNotificationHandler;i!==void 0&&Promise.resolve().then(()=>i(a)).catch(n=>this._onerror(new Error(`Uncaught error in notification handler: ${n}`)))}_onrequest(a){var t,i,n;let r=(t=this._requestHandlers.get(a.method))!==null&&t!==void 0?t:this.fallbackRequestHandler;if(r===void 0){(i=this._transport)===null||i===void 0||i.send({jsonrpc:"2.0",id:a.id,error:{code:Ma.MethodNotFound,message:"Method not found"}}).catch(o=>this._onerror(new Error(`Failed to send an error response: ${o}`)));return}let p=new AbortController;this._requestHandlerAbortControllers.set(a.id,p);let s={signal:p.signal,sessionId:(n=this._transport)===null||n===void 0?void 0:n.sessionId};Promise.resolve().then(()=>r(a,s)).then(o=>{var d;if(!p.signal.aborted)return(d=this._transport)===null||d===void 0?void 0:d.send({result:o,jsonrpc:"2.0",id:a.id})},o=>{var d,l;if(!p.signal.aborted)return(d=this._transport)===null||d===void 0?void 0:d.send({jsonrpc:"2.0",id:a.id,error:{code:Number.isSafeInteger(o.code)?o.code:Ma.InternalError,message:(l=o.message)!==null&&l!==void 0?l:"Internal error"}})}).catch(o=>this._onerror(new Error(`Failed to send response: ${o}`))).finally(()=>{this._requestHandlerAbortControllers.delete(a.id)})}_onprogress(a){let{progressToken:t,...i}=a.params,n=Number(t),r=this._progressHandlers.get(n);if(!r){this._onerror(new Error(`Received a progress notification for an unknown token: ${JSON.stringify(a)}`));return}let p=this._responseHandlers.get(n);if(this._timeoutInfo.has(n)&&p)try{this._resetTimeout(n)}catch(s){p(s);return}r(i)}_onresponse(a){let t=Number(a.id),i=this._responseHandlers.get(t);if(i===void 0){this._onerror(new Error(`Received a response for an unknown message ID: ${JSON.stringify(a)}`));return}if(this._responseHandlers.delete(t),this._progressHandlers.delete(t),this._cleanupTimeout(t),"result"in a)i(a);else{let n=new Ot(a.error.code,a.error.message,a.error.data);i(n)}}get transport(){return this._transport}async close(){var a;await((a=this._transport)===null||a===void 0?void 0:a.close())}request(a,t,i){return new Promise((n,r)=>{var p,s,o,d;if(!this._transport){r(new Error("Not connected"));return}((p=this._options)===null||p===void 0?void 0:p.enforceStrictCapabilities)===!0&&this.assertCapabilityForMethod(a.method),(s=i?.signal)===null||s===void 0||s.throwIfAborted();let l=this._requestMessageId++,c={...a,jsonrpc:"2.0",id:l};i?.onprogress&&(this._progressHandlers.set(l,i.onprogress),c.params={...a.params,_meta:{progressToken:l}});let x=f=>{var h;this._responseHandlers.delete(l),this._progressHandlers.delete(l),this._cleanupTimeout(l),(h=this._transport)===null||h===void 0||h.send({jsonrpc:"2.0",method:"notifications/cancelled",params:{requestId:l,reason:String(f)}}).catch(y=>this._onerror(new Error(`Failed to send cancellation: ${y}`))),r(f)};this._responseHandlers.set(l,f=>{var h;if(!(!((h=i?.signal)===null||h===void 0)&&h.aborted)){if(f instanceof Error)return r(f);try{let y=t.parse(f.result);n(y)}catch(y){r(y)}}}),(o=i?.signal)===null||o===void 0||o.addEventListener("abort",()=>{var f;x((f=i?.signal)===null||f===void 0?void 0:f.reason)});let g=(d=i?.timeout)!==null&&d!==void 0?d:I8,u=()=>x(new Ot(Ma.RequestTimeout,"Request timed out",{timeout:g}));this._setupTimeout(l,g,i?.maxTotalTimeout,u),this._transport.send(c).catch(f=>{this._cleanupTimeout(l),r(f)})})}async notification(a){if(!this._transport)throw new Error("Not connected");this.assertNotificationCapability(a.method);let t={...a,jsonrpc:"2.0"};await this._transport.send(t)}setRequestHandler(a,t){let i=a.shape.method.value;this.assertRequestHandlerCapability(i),this._requestHandlers.set(i,(n,r)=>Promise.resolve(t(a.parse(n),r)))}removeRequestHandler(a){this._requestHandlers.delete(a)}assertCanSetRequestHandler(a){if(this._requestHandlers.has(a))throw new Error(`A request handler for ${a} already exists, which would be overridden`)}setNotificationHandler(a,t){this._notificationHandlers.set(a.shape.method.value,i=>Promise.resolve(t(a.parse(i))))}removeNotificationHandler(a){this._notificationHandlers.delete(a)}};function p2(e,a){return Object.entries(a).reduce((t,[i,n])=>(n&&typeof n=="object"?t[i]=t[i]?{...t[i],...n}:n:t[i]=n,t),{...e})}var yr=class extends br{constructor(a,t){var i;super(t),this._serverInfo=a,this._capabilities=(i=t?.capabilities)!==null&&i!==void 0?i:{},this._instructions=t?.instructions,this.setRequestHandler(Cs,n=>this._oninitialize(n)),this.setNotificationHandler(ks,()=>{var n;return(n=this.oninitialized)===null||n===void 0?void 0:n.call(this)})}registerCapabilities(a){if(this.transport)throw new Error("Cannot register capabilities after connecting to transport");this._capabilities=p2(this._capabilities,a)}assertCapabilityForMethod(a){var t,i;switch(a){case"sampling/createMessage":if(!(!((t=this._clientCapabilities)===null||t===void 0)&&t.sampling))throw new Error(`Client does not support sampling (required for ${a})`);break;case"roots/list":if(!(!((i=this._clientCapabilities)===null||i===void 0)&&i.roots))throw new Error(`Client does not support listing roots (required for ${a})`);break;case"ping":break}}assertNotificationCapability(a){switch(a){case"notifications/message":if(!this._capabilities.logging)throw new Error(`Server does not support logging (required for ${a})`);break;case"notifications/resources/updated":case"notifications/resources/list_changed":if(!this._capabilities.resources)throw new Error(`Server does not support notifying about resources (required for ${a})`);break;case"notifications/tools/list_changed":if(!this._capabilities.tools)throw new Error(`Server does not support notifying of tool list changes (required for ${a})`);break;case"notifications/prompts/list_changed":if(!this._capabilities.prompts)throw new Error(`Server does not support notifying of prompt list changes (required for ${a})`);break;case"notifications/cancelled":break;case"notifications/progress":break}}assertRequestHandlerCapability(a){switch(a){case"sampling/createMessage":if(!this._capabilities.sampling)throw new Error(`Server does not support sampling (required for ${a})`);break;case"logging/setLevel":if(!this._capabilities.logging)throw new Error(`Server does not support logging (required for ${a})`);break;case"prompts/get":case"prompts/list":if(!this._capabilities.prompts)throw new Error(`Server does not support prompts (required for ${a})`);break;case"resources/list":case"resources/templates/list":case"resources/read":if(!this._capabilities.resources)throw new Error(`Server does not support resources (required for ${a})`);break;case"tools/call":case"tools/list":if(!this._capabilities.tools)throw new Error(`Server does not support tools (required for ${a})`);break;case"ping":case"initialize":break}}async _oninitialize(a){let t=a.params.protocolVersion;return this._clientCapabilities=a.params.capabilities,this._clientVersion=a.params.clientInfo,{protocolVersion:Zc.includes(t)?t:Rs,capabilities:this.getCapabilities(),serverInfo:this._serverInfo,...this._instructions&&{instructions:this._instructions}}}getClientCapabilities(){return this._clientCapabilities}getClientVersion(){return this._clientVersion}getCapabilities(){return this._capabilities}async ping(){return this.request({method:"ping"},dr)}async createMessage(a,t){return this.request({method:"sampling/createMessage",params:a},js,t)}async listRoots(a,t){return this.request({method:"roots/list",params:a},Fs,t)}async sendLoggingMessage(a){return this.notification({method:"notifications/message",params:a})}async sendResourceUpdated(a){return this.notification({method:"notifications/resources/updated",params:a})}async sendResourceListChanged(){return this.notification({method:"notifications/resources/list_changed"})}async sendToolListChanged(){return this.notification({method:"notifications/tools/list_changed"})}async sendPromptListChanged(){return this.notification({method:"notifications/prompts/list_changed"})}};var b0=qt(qn(),1),o1=qt($2(),1),d1=qt(x0(),1);import kg from"fs";function g0(e){let a=[];if(!e.requestBody)return a;let n=(e.requestBody.content||{})["multipart/form-data"];if(!n?.schema)return a;let r=n.schema;return r.type!=="object"||!r.properties||Object.entries(r.properties).forEach(([p,s])=>{let o=s;if(o.type==="string"&&o.format==="binary"&&a.push(p),o.type==="array"&&o.items){let d=o.items;d.type==="string"&&d.format==="binary"&&a.push(p)}}),a}var _n=class extends Error{constructor(t,i,n,r){super(`${i} ${t}`);this.status=i;this.data=n;this.headers=r;this.name="HttpClientError"}},rp=class{constructor(a,t){this.client=new(d1.default.default??d1.default)({definition:t,axiosConfigDefaults:{baseURL:a.baseUrl,headers:{"Content-Type":"application/json","User-Agent":"anytype-mcp-server",...a.headers}}}),this.api=this.client.init()}async prepareFileUpload(a,t){console.error("prepareFileUpload",{operation:a,params:t});let i=g0(a);if(i.length===0)return null;let n=new b0.default;for(let p of i){let o=function(d,l){try{let c=kg.createReadStream(l);n.append(d,c)}catch(c){throw new Error(`Failed to read file at ${l}: ${c}`)}};var r=o;console.error(`extracting ${p}`,{params:t});let s=t[p];if(!s)throw new Error(`File path must be provided for parameter: ${p}`);switch(typeof s){case"string":o(p,s);break;case"object":if(Array.isArray(s)){let d=0;for(let l of s)o(p,l),d++;break}default:throw new Error(`Unsupported file type: ${typeof s}`)}}for(let[p,s]of Object.entries(t))i.includes(p)||n.append(p,s);return n}async executeOperation(a,t={}){let i=await this.api,n=a.operationId;if(!n)throw new Error("Operation ID is required");let r=await this.prepareFileUpload(a,t),p={},s=r||{...t};if(a.parameters)for(let d of a.parameters)"name"in d&&d.name&&d.in&&(d.in==="path"||d.in==="query")&&t[d.name]!==void 0&&(p[d.name]=t[d.name],r||delete s[d.name]);if(!a.requestBody&&!r)for(let d in s)s[d]!==void 0&&(p[d]=s[d],delete s[d]);let o=i[n];if(!o)throw new Error(`Operation ${n} not found`);try{let d=Object.keys(s).length>0,c={headers:{...r?r.getHeaders():{...d?{"Content-Type":"application/json"}:{"Content-Type":null}}}};console.error("calling operation",{operationId:n,urlParameters:p,bodyParams:s,requestConfig:c});let x=await o(p,d?s:void 0,c);console.error("operation finished");let g=new o1.Headers;return Object.entries(x.headers).forEach(([u,f])=>{f&&g.append(u,f.toString())}),{data:x.data,status:x.status,headers:g}}catch(d){if(d.response){console.error("Error in http client",d);let l=new o1.Headers;throw Object.entries(d.response.headers).forEach(([c,x])=>{x&&l.append(c,x.toString())}),new _n(d.response.statusText||"Request failed",d.response.status,d.response.data,l)}throw d}}};var pp=class{constructor(a){this.openApiSpec=a;this.schemaCache={};this.nameCounter=0}internalResolveRef(a,t){if(!a.startsWith("#/")||t.has(a))return null;let i=a.replace(/^#\//,"").split("/"),n=this.openApiSpec;for(let r of i)if(n=n[r],!n)return null;return t.add(a),n}convertOpenApiSchemaToJsonSchema(a,t,i=!0){if("$ref"in a){let r=a.$ref;if(!i){if(r.startsWith("#/components/schemas/"))return{$ref:r.replace(/^#\/components\/schemas\//,"#/$defs/"),..."description"in a?{description:a.description}:{}};console.error(`Attempting to resolve ref ${r} not found in components collection.`)}let p={$ref:r};if("description"in a&&a.description&&(p.description=a.description),this.schemaCache[r])return this.schemaCache[r];let s=this.internalResolveRef(r,t);if(s){let o=this.convertOpenApiSchemaToJsonSchema(s,t,i);return this.schemaCache[r]=o,o}else return console.error(`Failed to resolve ref ${r}`),{$ref:r.replace(/^#\/components\/schemas\//,"#/$defs/"),description:"description"in a?a.description??"":""}}let n={};if(a.type&&(n.type=a.type),a.format==="binary"){n.format="uri-reference";let r="absolute paths to local files";n.description=a.description?`${a.description} (${r})`:r}else a.format&&(n.format=a.format),a.description&&(n.description=a.description);if(a.enum&&(n.enum=a.enum),a.default!==void 0&&(n.default=a.default),a.type==="object"){if(n.type="object",a.properties){n.properties={};for(let[r,p]of Object.entries(a.properties))n.properties[r]=this.convertOpenApiSchemaToJsonSchema(p,t,i)}a.required&&(n.required=a.required),a.additionalProperties===!0||a.additionalProperties===void 0?n.additionalProperties=!0:a.additionalProperties&&typeof a.additionalProperties=="object"?n.additionalProperties=this.convertOpenApiSchemaToJsonSchema(a.additionalProperties,t,i):n.additionalProperties=!1}if(a.type==="array"&&a.items&&(n.type="array",n.items=this.convertOpenApiSchemaToJsonSchema(a.items,t,i)),a.oneOf){if(a.oneOf.some(o=>typeof o=="object"&&"$ref"in o&&o.$ref==="#/components/schemas/apimodel.EmojiIcon"))return{type:"object",description:a.description,properties:{emoji:{type:"string",description:"The emoji of the icon"},format:{type:"string",description:"The format of the icon",enum:["emoji"]}},additionalProperties:!0};let p=a.oneOf.every(o=>typeof o=="object"&&"$ref"in o&&o.$ref.endsWith("PropertyValue")),s=a.oneOf.every(o=>typeof o=="object"&&"$ref"in o&&o.$ref.endsWith("PropertyLinkValue"));if(p||s)return{type:"object",properties:{...{...s?{key:{type:"string",description:"The key of the property",examples:["last_modified_date"]}}:{id:{type:"string",description:"The id of the property",examples:["last_modified_date"]},key:{type:"string",description:"The key of the property",examples:["last_modified_date"]},name:{type:"string",description:"The name of the property",examples:["Last modified date"]},object:{type:"string",description:"The data model of the object",examples:["property"]}}},text:{type:"string",description:"The text value, if applicable",examples:["Some text..."]},number:{type:"number",description:"The number value, if applicable",examples:[42]},select:{type:"string",description:"The selected tag id, if applicable",examples:["tag_id"]},multi_select:{type:"array",description:"The selected tag ids, if applicable",items:{type:"string"},examples:[["tag_id"]]},date:{type:"string",description:"The date value in ISO 8601 format, if applicable",examples:["2025-02-14T12:34:56Z"]},files:{type:"array",description:"The file ids, if applicable",items:{type:"string"},examples:[["['file_id']"]]},checkbox:{type:"boolean",description:"The checkbox value, if applicable",examples:[!0]},url:{type:"string",description:"The url value, if applicable",examples:["https://example.com"]},email:{type:"string",description:"The email value, if applicable",examples:["example@example.com"]},phone:{type:"string",description:"The phone number value, if applicable",examples:["+1234567890"]},objects:{type:"array",description:"The object ids, if applicable",items:{type:"string"},examples:[["['object_id']"]]}}}}return a.oneOf&&(n.oneOf=a.oneOf.map(r=>this.convertOpenApiSchemaToJsonSchema(r,t,i))),a.anyOf&&(n.anyOf=a.anyOf.map(r=>this.convertOpenApiSchemaToJsonSchema(r,t,i))),a.allOf&&(n.allOf=a.allOf.map(r=>this.convertOpenApiSchemaToJsonSchema(r,t,i))),n}convertToMCPTools(){let a="API",t={},i={[a]:{methods:[]}},n={};for(let[r,p]of Object.entries(this.openApiSpec.paths||{}))if(p)for(let[s,o]of Object.entries(p)){if(!this.isOperation(s,o)||o.tags?.includes("Auth")||s.toLowerCase()==="delete")continue;let d=this.convertOperationToMCPMethod(o,s,r);if(d){let l=this.ensureUniqueName(d.name).replaceAll("_","-");d.name=l,i[a].methods.push(d),t[a+"-"+l]={...o,method:s,path:r},n[a+"-"+l]={openApi:{...o,method:s,path:r},mcp:d}}}return{tools:i,openApiLookup:t,zip:n}}convertToOpenAITools(){let a=[];for(let[t,i]of Object.entries(this.openApiSpec.paths||{}))if(i)for(let[n,r]of Object.entries(i)){if(!this.isOperation(n,r)||r.tags?.includes("Auth")||n.toLowerCase()==="delete")continue;let p=this.convertOperationToJsonSchema(r,n,t),s={type:"function",function:{name:r.operationId,description:r.summary||r.description||"",parameters:p}};a.push(s)}return a}convertToAnthropicTools(){let a=[];for(let[t,i]of Object.entries(this.openApiSpec.paths||{}))if(i)for(let[n,r]of Object.entries(i)){if(!this.isOperation(n,r)||r.tags?.includes("Auth")||n.toLowerCase()==="delete")continue;let p=this.convertOperationToJsonSchema(r,n,t),s={name:r.operationId,description:r.summary||r.description||"",input_schema:p};a.push(s)}return a}convertComponentsToJsonSchema(){let a=this.openApiSpec.components||{},t={};for(let[i,n]of Object.entries(a.schemas||{}))t[i]=this.convertOpenApiSchemaToJsonSchema(n,new Set);return t}convertOperationToJsonSchema(a,t,i){let n={type:"object",properties:{},required:[],$defs:{}};if(a.parameters)for(let r of a.parameters){let p=this.resolveParameter(r);if(p&&p.schema){if(p.name==="Anytype-Version")continue;let s=this.convertOpenApiSchemaToJsonSchema(p.schema,new Set);p.description&&(s.description=p.description),n.properties[p.name]=s,p.required&&n.required.push(p.name)}}if(a.requestBody){let r=this.resolveRequestBody(a.requestBody);if(r?.content&&r.content["application/json"]?.schema){let p=this.convertOpenApiSchemaToJsonSchema(r.content["application/json"].schema,new Set);if(p.type==="object"&&p.properties){for(let[s,o]of Object.entries(p.properties))n.properties[s]=o;p.required&&n.required.push(...p.required)}}}return n}isOperation(a,t){return["get","post","put","delete","patch"].includes(a.toLowerCase())}isParameterObject(a){return!("$ref"in a)}isRequestBodyObject(a){return!("$ref"in a)}resolveParameter(a){if(this.isParameterObject(a))return a;{let t=this.internalResolveRef(a.$ref,new Set);if(t&&t.name)return t}return null}resolveRequestBody(a){if(this.isRequestBodyObject(a))return a;{let t=this.internalResolveRef(a.$ref,new Set);if(t)return t}return null}resolveResponse(a){if("$ref"in a){let t=this.internalResolveRef(a.$ref,new Set);return t||null}return a}convertOperationToMCPMethod(a,t,i){if(!a.operationId)return console.warn(`Operation without operationId at ${t} ${i}`),null;let n=a.operationId,r={$defs:{},type:"object",properties:{},required:[]};if(a.parameters)for(let o of a.parameters){let d=this.resolveParameter(o);if(d&&d.schema){if(d.name==="Anytype-Version")continue;let l=this.convertOpenApiSchemaToJsonSchema(d.schema,new Set,!0);d.description&&(l.description=d.description),r.properties[d.name]=l,d.required&&r.required.push(d.name)}}if(a.requestBody){let o=this.resolveRequestBody(a.requestBody);if(o?.content){if(o.content["multipart/form-data"]?.schema){let d=this.convertOpenApiSchemaToJsonSchema(o.content["multipart/form-data"].schema,new Set,!0);if(d.type==="object"&&d.properties){for(let[l,c]of Object.entries(d.properties))r.properties[l]=c;d.required&&r.required.push(...d.required)}}else if(o.content["application/json"]?.schema){let d=this.convertOpenApiSchemaToJsonSchema(o.content["application/json"].schema,new Set,!0);if(d.type==="object"&&d.properties){for(let[l,c]of Object.entries(d.properties))r.properties[l]=c;d.required&&r.required.push(...d.required)}else r.properties.body=d,r.required.push("body")}}}let p=a.summary||a.description||"";if(a.responses){let o=Object.entries(a.responses).filter(([d])=>d.startsWith("4")||d.startsWith("5")).map(([d,l])=>{let x=this.resolveResponse(l)?.description||"";return`${d}: ${x}`});o.length>0&&(p+=`
71
71
  Error Responses:
72
72
  `+o.join(`
73
- `))}let s=this.extractResponseType(a.responses);try{return{name:n,description:p,inputSchema:r,...s?{outputSchema:s}:{}}}catch(o){return console.warn(`Failed to generate Zod schema for ${n}:`,o),{name:n,description:p,inputSchema:r,...s?{outputSchema:s}:{}}}}extractResponseType(a){let t=a?.["200"]||a?.["201"]||a?.["202"]||a?.["204"];if(!t)return null;let i=this.resolveResponse(t);if(!i||!i.content)return null;if(i.content["application/json"]?.schema){let n=this.convertOpenApiSchemaToJsonSchema(i.content["application/json"].schema,new Set,!0);return n.$defs={},i.description&&!n.description&&(n.description=i.description),n}return i.content["image/png"]||i.content["image/jpeg"]?{type:"string",format:"binary",description:i.description||""}:{type:"string",description:i.description||""}}ensureUniqueName(a){if(a.length<=64)return a;let t=a.slice(0,59),i=this.generateUniqueSuffix();return`${t}-${i}`}generateUniqueSuffix(){return this.nameCounter+=1,this.nameCounter.toString().padStart(4,"0")}};var sp=class{constructor(a,t){this.server=new yr({name:a,version:"1.0.0"},{capabilities:{tools:{}}});let i=t.servers?.[0].url;if(!i)throw new Error("No base URL found in OpenAPI spec");this.httpClient=new rp({baseUrl:i,headers:this.parseHeadersFromEnv()},t);let n=new pp(t),{tools:r,openApiLookup:p}=n.convertToMCPTools();this.tools=r,this.openApiLookup=p,this.setupHandlers()}setupHandlers(){this.server.setRequestHandler(Ds,async()=>{let a=[];return Object.entries(this.tools).forEach(([t,i])=>{i.methods.forEach(n=>{let r=`${t}-${n.name}`,p=this.truncateToolName(r);a.push({name:p,description:n.description,inputSchema:n.inputSchema})})}),{tools:a}}),this.server.setRequestHandler(Ps,async a=>{console.error("calling tool",a.params);let{name:t,arguments:i}=a.params,n=this.findOperation(t);if(console.error("operations",this.openApiLookup),!n)throw new Error(`Method ${t} not found`);try{let r=await this.httpClient.executeOperation(n,i);return{content:[{type:"text",text:JSON.stringify(r.data)}]}}catch(r){if(console.error("Error in tool call",r),r instanceof _n){console.error("HttpClientError encountered, returning structured error",r);let p=r.data?.response?.data??r.data??{};return{content:[{type:"text",text:JSON.stringify({status:"error",...typeof p=="object"?p:{data:p}})}]}}throw r}})}findOperation(a){return this.openApiLookup[a]??null}parseHeadersFromEnv(){let a=process.env.OPENAPI_MCP_HEADERS;if(!a)return{};try{let t=JSON.parse(a);return typeof t!="object"||t===null?(console.warn("OPENAPI_MCP_HEADERS environment variable must be a JSON object, got:",typeof t),{}):t}catch(t){return console.warn("Failed to parse OPENAPI_MCP_HEADERS environment variable:",t),{}}}getContentType(a){let t=a.get("content-type");return t?t.includes("text")||t.includes("json")?"text":t.includes("image")?"image":"binary":"binary"}truncateToolName(a){return a.length<=64?a:a.slice(0,64)}async connect(a){await this.server.connect(a)}};var op=class extends Error{constructor(t){super("OpenAPI validation failed");this.errors=t;this.name="ValidationError"}};async function l1(e){let t=e||"http://localhost:31009/docs/openapi.json",i;if(t.startsWith("http://")||t.startsWith("https://"))try{let n=await ct.get(t);i=typeof n.data=="string"?n.data:JSON.stringify(n.data)}catch(n){n.code==="ECONNREFUSED"&&(console.error("Can't connect to API. Please ensure Anytype is running and reachable."),process.exit(1)),console.error("Failed to fetch OpenAPI specification from URL:",n.message),process.exit(1)}else{let n=Pg.resolve(process.cwd(),t);i=Dg.readFileSync(n,"utf-8")}try{return JSON.parse(i)}catch(n){console.error("Failed to parse OpenAPI specification:",n.message),process.exit(1)}}async function y0(e){let a=await l1(e),t=new sp("Anytype API",a);return console.error("Connecting to Anytype API..."),t.connect(new gr)}async function jg(e){let t=(await l1(e)).servers?.[0]?.url||"http://localhost:31009";await new er(t).generateAppKey()}async function Fg(e=process.argv.slice(2)){let[a,t]=e;!a||a==="run"?await y0(t):a==="get-key"?await jg(t):(console.error(`Error: Unknown command "${a}"`),process.exit(1))}Fg().catch(e=>{e instanceof op?(console.error("Invalid OpenAPI 3.1 specification:"),e.errors.forEach(a=>console.error(a))):console.error("Error:",e.message),process.exit(1)});export{Fg as main};
73
+ `))}let s=this.extractResponseType(a.responses);try{return{name:n,description:p,inputSchema:r,...s?{outputSchema:s}:{}}}catch(o){return console.warn(`Failed to generate Zod schema for ${n}:`,o),{name:n,description:p,inputSchema:r,...s?{outputSchema:s}:{}}}}extractResponseType(a){let t=a?.["200"]||a?.["201"]||a?.["202"]||a?.["204"];if(!t)return null;let i=this.resolveResponse(t);if(!i||!i.content)return null;if(i.content["application/json"]?.schema){let n=this.convertOpenApiSchemaToJsonSchema(i.content["application/json"].schema,new Set,!0);return n.$defs={},i.description&&!n.description&&(n.description=i.description),n}return i.content["image/png"]||i.content["image/jpeg"]?{type:"string",format:"binary",description:i.description||""}:{type:"string",description:i.description||""}}ensureUniqueName(a){if(a.length<=64)return a;let t=a.slice(0,59),i=this.generateUniqueSuffix();return`${t}-${i}`}generateUniqueSuffix(){return this.nameCounter+=1,this.nameCounter.toString().padStart(4,"0")}};var sp=class{constructor(a,t){this.server=new yr({name:a,version:"1.0.0"},{capabilities:{tools:{}}});let i=t.servers?.[0].url||"http://127.0.0.1:31009";this.httpClient=new rp({baseUrl:i,headers:this.parseHeadersFromEnv()},t);let n=new pp(t),{tools:r,openApiLookup:p}=n.convertToMCPTools();this.tools=r,this.openApiLookup=p,this.setupHandlers()}setupHandlers(){this.server.setRequestHandler(Ds,async()=>{let a=[];return Object.entries(this.tools).forEach(([t,i])=>{i.methods.forEach(n=>{let r=`${t}-${n.name}`,p=this.truncateToolName(r);a.push({name:p,description:n.description,inputSchema:n.inputSchema})})}),{tools:a}}),this.server.setRequestHandler(Ps,async a=>{console.error("calling tool",a.params);let{name:t,arguments:i}=a.params,n=this.findOperation(t);if(console.error("operations",this.openApiLookup),!n)throw new Error(`Method ${t} not found`);try{let r=await this.httpClient.executeOperation(n,i);return{content:[{type:"text",text:JSON.stringify(r.data)}]}}catch(r){if(console.error("Error in tool call",r),r instanceof _n){console.error("HttpClientError encountered, returning structured error",r);let p=r.data?.response?.data??r.data??{};return{content:[{type:"text",text:JSON.stringify({status:"error",...typeof p=="object"?p:{data:p}})}]}}throw r}})}findOperation(a){return this.openApiLookup[a]??null}parseHeadersFromEnv(){let a=process.env.OPENAPI_MCP_HEADERS;if(!a)return{};try{let t=JSON.parse(a);return typeof t!="object"||t===null?(console.warn("OPENAPI_MCP_HEADERS environment variable must be a JSON object, got:",typeof t),{}):t}catch(t){return console.warn("Failed to parse OPENAPI_MCP_HEADERS environment variable:",t),{}}}getContentType(a){let t=a.get("content-type");return t?t.includes("text")||t.includes("json")?"text":t.includes("image")?"image":"binary":"binary"}truncateToolName(a){return a.length<=64?a:a.slice(0,64)}async connect(a){await this.server.connect(a)}};var op=class extends Error{constructor(t){super("OpenAPI validation failed");this.errors=t;this.name="ValidationError"}};async function l1(e){let a=e||"http://127.0.0.1:31009/docs/openapi.json",t;if(a.startsWith("http://")||a.startsWith("https://"))try{let i=await ct.get(a);t=typeof i.data=="string"?i.data:JSON.stringify(i.data)}catch(i){i.code==="ECONNREFUSED"&&(console.error("Can't connect to API. Please ensure Anytype is running and reachable."),process.exit(1)),console.error("Failed to fetch OpenAPI specification from URL:",i.message),process.exit(1)}else{let i=Pg.resolve(process.cwd(),a);t=Dg.readFileSync(i,"utf-8")}try{return JSON.parse(t)}catch(i){console.error("Failed to parse OpenAPI specification:",i.message),process.exit(1)}}async function y0(e){console.error("Initializing Anytype MCP Server...");let a=await l1(e);await new sp("Anytype API",a).connect(new gr),console.error("Anytype MCP Server running on stdio")}async function jg(e){let t=(await l1(e)).servers?.[0]?.url||"http://127.0.0.1:31009";await new er(t).generateAppKey()}async function Fg(e=process.argv.slice(2)){let[a,t]=e;!a||a==="run"?await y0(t):a==="get-key"?await jg(t):(console.error(`Error: Unknown command "${a}"`),process.exit(1))}Fg().catch(e=>{e instanceof op?(console.error("Invalid OpenAPI 3.1 specification:"),e.errors.forEach(a=>console.error(a))):console.error("Error:",e.message),process.exit(1)});export{Fg as main};
74
74
  /*! Bundled license information:
75
75
 
76
76
  mime-db/index.js:
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "mcp",
7
7
  "server"
8
8
  ],
9
- "version": "1.0.3",
9
+ "version": "1.0.5",
10
10
  "license": "MIT",
11
11
  "type": "module",
12
12
  "scripts": {
@@ -3,7 +3,7 @@ import { initProxy, loadOpenApiSpec, ValidationError } from "../src/init-server"
3
3
 
4
4
  async function generateAppKey(specPath?: string) {
5
5
  const openApiSpec = await loadOpenApiSpec(specPath);
6
- const baseUrl = openApiSpec.servers?.[0]?.url || "http://localhost:31009";
6
+ const baseUrl = openApiSpec.servers?.[0]?.url || "http://127.0.0.1:31009";
7
7
  const generator = new AppKeyGenerator(baseUrl);
8
8
  await generator.generateAppKey();
9
9
  }
@@ -13,8 +13,7 @@ export class ValidationError extends Error {
13
13
  }
14
14
 
15
15
  export async function loadOpenApiSpec(specPath?: string): Promise<OpenAPIV3.Document> {
16
- const defaultSpecUrl = "http://localhost:31009/docs/openapi.json";
17
- const finalSpec = specPath || defaultSpecUrl;
16
+ const finalSpec = specPath || "http://127.0.0.1:31009/docs/openapi.json";
18
17
  let rawSpec: string;
19
18
 
20
19
  if (finalSpec.startsWith("http://") || finalSpec.startsWith("https://")) {
@@ -43,9 +42,10 @@ export async function loadOpenApiSpec(specPath?: string): Promise<OpenAPIV3.Docu
43
42
  }
44
43
 
45
44
  export async function initProxy(specPath: string) {
45
+ console.error("Initializing Anytype MCP Server...");
46
46
  const openApiSpec = await loadOpenApiSpec(specPath);
47
47
  const proxy = new MCPProxy("Anytype API", openApiSpec);
48
48
 
49
- console.error("Connecting to Anytype API...");
50
- return proxy.connect(new StdioServerTransport());
49
+ await proxy.connect(new StdioServerTransport());
50
+ console.error("Anytype MCP Server running on stdio");
51
51
  }
package/src/mcp/proxy.ts CHANGED
@@ -32,10 +32,7 @@ export class MCPProxy {
32
32
 
33
33
  constructor(name: string, openApiSpec: OpenAPIV3.Document) {
34
34
  this.server = new Server({ name, version: "1.0.0" }, { capabilities: { tools: {} } });
35
- const baseUrl = openApiSpec.servers?.[0].url;
36
- if (!baseUrl) {
37
- throw new Error("No base URL found in OpenAPI spec");
38
- }
35
+ const baseUrl = openApiSpec.servers?.[0].url || "http://127.0.0.1:31009";
39
36
  this.httpClient = new HttpClient(
40
37
  {
41
38
  baseUrl,