HTTP/1.1 200 OK Date: Tue, 09 Apr 2002 11:03:21 GMT Server: Apache/1.3.20 (Unix) Last-Modified: Wed, 07 Apr 1999 08:28:00 GMT ETag: "361f32-9810-370b1710" Accept-Ranges: bytes Content-Length: 38928 Connection: close Content-Type: text/plain INTERNET-DRAFT David Reilly Expires: September 1999 davidreilly.com March 1999 Simple Agent Commmunication Protocol Status of this Memo This document is an Internet-Draft and is in full conformance with all provisions of Section 10 of RFC2026 except that the right to produce derivative works is not granted. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet-Drafts. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." The list of current Internet-Drafts can be accessed at http://www.ietf.org/ietf/1id-abstracts.txt The list of Internet-Draft Shadow Directories can be accessed at http://www.ietf.org/shadow.html. Abstract The Simple Agent Communication Protocol (SACP) is an application protocol designed to facilitate communication of data and facts between software agents over the Internet. While designed with agents in mind, it is also suited to applications where the agent metaphor can be applied, such as autonomous processes, or to systems which might be accessed by agents, such as databases or directories. Applications which need to transmit or receive machine-readable data, or structured information that is stored hierarchically, are ideally suited to SACP. As its name suggests, SACP has been designed with simplicity in mind. It offers an alternative to complex agent communication languages such as KQML, and to other forms of data exchange that require large amounts of overhead (such as a web server, or remote database calls). SACP is language-neutral, unlike many software agent communication architectures, and is a good candidate for an agent communication mechanism where portability is required. It can also be used as a bridge to other agent communication architectures, or to platform/language specific types of information retrieval. Reilly Page 1 Table of contents 1. Introduction...................................................1 1.1 Purpose.......................................................1 1.2 Rationale.....................................................2 1.3 Definitions...................................................2 1.4 Protocol Operation............................................3 1.4.1 Information Organization................................3 1.4.2 Node content............................................4 1.4.3 Agent activities........................................4 2. Protocol Specification.........................................4 2.1 Specification Notation....................................4 2.2 Protocol Rules............................................5 2.3 Protocol Commands.........................................7 2.3.1 IDENTITY command....................................7 2.3.2 AUTHENTICATE command................................7 2.3.3 GETNODE command.....................................8 2.3.4 CHANGENODE command..................................8 2.3.5 CREATENODE command..................................8 2.3.6 DELETENODE command..................................9 2.3.7 DELETEKEY command...................................9 2.3.8 READ command.......................................10 2.3.9 LIST command.......................................10 2.3.10 LISTNODES command.................................10 2.3.11 CREATEKEY command.................................11 2.3.12 WRITE command.....................................11 2.3.13 QUERY command.....................................12 2.4 Command Responses........................................12 2.4.1 Operation State....................................12 2.4.2 Message status code................................13 2.4.2.1 Operation Successful.........................13 2.4.2.2 Agent Client Error...........................14 2.4.2.3 Agent Server Error...........................15 2.5 Security/Performance considerations......................15 2.5.1 Security considerations............................15 2.5.2 Performance considerations.........................15 3. References....................................................16 4. Author's Address..............................................16 1. Introduction 1.1 Purpose The Simple Agent Communication Protocol (SACP) is an application protocol designed to facilitate the easy exchange of data and knowledge between software agents over the Internet. SACP aims to make agent communication simpler for developers. Software developers employ a large range of communication mechanisms when writing agent software. Many of these are platform or language specific and involve a large amount of overhead (such as running a database for a very small amount of data, or data that is generated dynamically). Additionally, many of these methods are complex and involve a steep learning curve for programmers. SACP allows agents to talk with other agents and request data. Data is stored in key-value pairs, which are stored in a hierarchical Reilly Page 2 "nodespace". An agent's nodespace may represent files on a disk, in-memory data structures, or even dynamically generated information (such as a database lookup). Nodes may contain subnodes, as well as zero or more keys. Each key has an associated MIME type[1], and the values of such keys can be either text or binary data. While designed with agents in mind, it is also suited to applications where the agent metaphor can be applied, such as autonomous processes, or to systems which might be accessed by agents, such as address books, information directories, etc. Applications which need to transmit or receive machine-readable data, or structured information that is stored hierarchically, are ideally suited to SACP. 1.2 Rationale Many solutions for agent communication already exist. Some involve language-specific solutions, rendering them unportable, and others involve complex languages and encoding schemes, such as KQML. In systems where portability across language and platform are not an issue, or which already involve high levels of complexity (such as shared knowledge bases), these solutions are quite appropriate. SACP is not a universal solution to the problem of sharing data and information - but in cases where agents are to be distributed across large networks with different platforms, or where an easily implemented solution to sharing data is required, there is a need for a simplified protocol that is language and platform independent. This is the role that SACP is intended to fulfil. A language-specific implementation may not be appropriate, and the overhead of invoking remote procedures or operating database servers may too great for simple uses. Rather than writing and implementing a proprietary protocol for every agent, SACP can be used. 1.3 Definitions The following definitions are used in ths document:- broker, an agent which acts as an intermediary for communication between two or more agents. information key, a string that is used as an identifier to access a stored data value. listener agent, an agent that accepts connections from others agent, and processes commands sent by them. nodepath, a location within a nodespace (the name of each parent node is separated by a '/' char). nodespace, a collection of information nodes. Reilly Page 3 sacp, Simple Agent Communication Protocol. software agent, a software process which may be executing under the control of a user, or executing autonomously. talker agent, an agent that initiates a connection to another SACP-speaking agent, and issues commands. 1.4 Protocol Operation SACP is an application-level protocol, which runs over a TCP stream. Agents that wish to offer information will accept TCP connections, and will act as an agent server (referred to as a "listener". Agents that wish to initiate communication with a specific agent can connect via TCP as a client (referred to as a "talker"). However, there is no limitation placed on agents that prohibits an agent from acting both as a talker and a listener. Indeed, this practice should be encouraged, because it allows agents to both initiate dialogue with other agents and to listen for incoming requests. Once a connection between talker and listener has been established, a series of transactions will take place. SACP transactions consist of a series of requests/responses. Talker agents issue requests, which are composed of commands and parameters, while listener agents answer with a response. The number of commands in SACP is limited to small number - this helps reduce the complexity of the protocol and its implementation. Agents can make multiple requests of a talker in a given session, which improves efficiency. SACP talkers can request information, as well as send information to a server for storage (though under controlled conditions set by the listener). 1.4.1 Information Organization Information under SACP is organized in a hierarchical structure of nodes, referred to as a "nodespace". Each node can contain links to zero or many subnodes. This allows information to be stored hierarchically, and for an agent to quickly access the focus of its search by descending through node levels in a depth-first search. The organization of information under SACP is in a tree-like structure, with information keys, and an associated MIME content type[1]. Agent implementers are free to implement whatever structure of nodes they see fit, though it is important that other agents are able to find information they seek (e.g. - a listener might use a pre-defined structure of nodes and keys, so that talkers know where to look). The title of a node may be of assistance to talkers as an indicator of its purpose, as well as its ancestors and the keys stored within a node. It is proposed that some node titles be reserved for special purposes. For example, the "identity" node would always contain keys that identify the user, organization, machine or object represented by its parent node. Comment on reserved title names is especially welcome. Reilly Page 4 The mechanism for storage of these nodes is left largely up to the implementer of the agent listener - nodes can represent directories on a file system, tables and records in a database, an in-memory data structure, or any other type of storage mechanism. The underlying implementation details are transparent to agents that interact with an agent listener. 1.4.2 Node contents Each node can contain zero or more child nodes, as well as zero or more information keys. Each information key maps to a single value. A value can be composed of ASCII information, or a binary stream of data, and has associated with it a MIME content type[1]. The SACP listener is responsible for storing and retrieving this information, and for access control. 1.4.3 Agent activities Talker agents under SACP are capable of accessing and modifying information nodes and their contents. They are also capable of creating new nodes of information, and creating new key-value pair mappings. The details of access and security are left largely up to the implementer of the listener (for example, restricting access by IP address), but support for an authentication scheme is present, and error codes are available for a listener to inform the talker that it is not authorized to perform a write or read operation. Agents under SACP, are also capable of more complex behavior than just reading and writing data. Talker agents can also issue queries to listeners. No specific query language is defined, and it is proposed that such details is left up to agent implementers. This would allow developers to use existing languages (such as SQL to interface with a database, or KQML for high level communication), and to define their own for custom applications. When a query command is issued, a query language is specified as a parameter. Another important role that agents can play is that of a broker. Agents that act as a broker can act as intermediaries between two or more agents. However, no explicit support for brokering or multi-agent communcation has been incorporated into SACP - though it would be possible to use queries to implement broker functionality. Comments are especially welcome in this area. 2. Protocol Specification 2.1 Specification Notation Throughout the document, the protocol is described using a mixture of text descriptions and Extended Backus-Naur Form (EBNF) notation. When implementing a SACP listener agent or talker agent, this specification should be used to aid in the construction of a compliant system. The following notation is used throughout this specification : Reilly Page 5 rule ::= definition Rules can be defined through the ::= operator. A rule definition may be composed of literal strings, other rules, operators or any combination thereof. "literal string" Quotation marks indicate literal strings, which are composed of ASCII text. rule_a | rule_b Rule definitions can include the | operator, which represents a logical OR operation. In this example, rule_a or rule_b can be accepted. The | operator can also specify more than two options, such as rule_a | rule_b | rule_c. rule_a | (rule_b | rule_c ) rule_d Rule definitions can contain brackets, which allows nested statements. In this example, rule_a, rule_b rule_d, or rule_c rule_d is defined. * repetition Rule definitions can include a * operator, which indicates that a sequence of zero, one or many is present in the definition. Where a number is specified (e.g. 2*) then the exact number of repeated items is given. {rule_a} The curly bracket operators { } indicate that something is optional (it may be present, but is not required). 2.2 Protocol Rules The SACP protocol is composed of a series of transactions, issued by a talker and processed by a listener. Individual transactions are made up of a command and request. Each command/response represents a single transaction, and multiple transactions can be made in any given session. Before defining such transactions, it is important to establish some basic rules. Basic rules # Any valid 8-bit ASCII code ASCII ::= # Either lowercase or uppercase letters are accepted LETTER ::= # Numerical values NUMBER ::= # Character includes numbers, as well as # - . and _ to avoid need for a space CHARACTER ::= LETTER | "-" | "_" | "." | NUMBER Reilly Page 6 # Symbol allows limited use of punctuation, such as / for path # statement and * $ for wildcards SYMBOL ::= "/" | "?" | "*" | "$" # Space character is ASCII value 20h (in hexadecimal) SPACE ::= " " # Hyphen character HYPHEN ::= "-" # Character or a symbol CHARSYMBOL::= CHARACTER | SYMBOL # A sequence of characters WORD ::= *CHARACTER # A sequence of characters or symbols SYMBOLWORD::= *CHARSYMBOL # Carriage return followed by a linefeed 0dh 0ch (in hex) NEWLINE ::= "" # Terminator indicates end of data TERMINATOR ::= NEWLINE "." NEWLINE Transaction rules # Transaction is a command followed by a response TRANSACTION ::= COMMAND RESPONSE # Command is composed of a command name, zero or more # parameters, and a newline. Some commands may require # data, but talkers sending non-data commands should # not send data. COMMAND ::= COMMAND_TYPE *PARAMETER NEWLINE {DATA} COMMAND_TYPE ::= WORD # Parameters can be composed of symbols or words PARAMETER ::= *SYMBOLWORD # Some responses, for example a directory change, don't # require any data. Listeners should not send data unless # the command requires it. RESPONSE ::= STATUS NEWLINE {DATA} # Three digit message code MSGCODE ::= 3*(NUMBER) # Optional message descriptor MSG ::= *SYMBOLWORD # Response state followed by msg code and optional text message STATUS ::= ("OK" | "ERROR") SPACE HYPHEN SPACE MSGCODE {MSG} Reilly Page 7 # Syntactical representation of data. Mime type is optional # if and only if MIME is of type text/plain. Else # the MIME type should be specified DATA::= ("MIME:" MIME_TYPE NEWLINE {"LENGTH:" *NUMBER NEWLINE} *ASCII) | *SYMBOLWORD TERMINATOR 2.3 Protocol Commands The syntax of every command supported by SACP, and their meaning, is described in the following section. Commands that require or support optional parameters are indicated, as well as commands that require or return data. Different commands are capable of returning different response codes; for more information see Section 2.4. 2.3.1 IDENTITY command Parameters : yes Requires data : no Returns data : no Upon connecting to the listener, the talker may choose to identify itself through the IDENTITY command. The format of identity information is unrestricted, and is to be left up to agent listeners. However, a suggested format is the following :- C: IDENTITY myhostname FOR "user" USING SACPv1.0 S: OK - 107 Hello "user" from myhostname The listener will then respond with a status code, indicating the success or failure of the identification. Listeners are free to reject the identification offered by the talker for any reason. It should be remembered, however, that an agent claiming to be from a particular host and representing a particular user may not be what it appears, and listeners with secure data should verify such claims (using the IP address, or by requiring authentication of user before access is granted to data). 2.3.2 AUTHENTICATE command Parameters : optional Requires data : yes, if a parameter is present Returns data : no Authentication of the identity of an agent may be necessary for access to non-public nodes and keys, or for writing to the server. Listeners may use whichever authentication scheme they choose - some may choose to request a password, some may use more vigorous schemes such as requiring a digital certificate. When a talker agent wishes to authenticate itself (usually after the IDENTITY command has been issued), it can issue the authenticate command. When no parameters are present, the server will respond Reilly Page 8 with information about the type of scheme it requires. If the talker can support that scheme, it can issue the authenticate command again, along with the data that is required for authentication. At a minimum, talkers that wish to be authenticated should be capable of supporting the byPassword authentication scheme - more advanced schemes are at the discretion of implementers. The following is an example of a password authentication for a ficticious account. C: IDENTITY davidreilly S: OK - 107 Greetings davidreilly C: AUTHENTICATE S: OK - 100 Command accepted S: byPassword C: AUTHENTICATE byPassword C: MIME: text/plain C: this_is_not_my_real_password C: . S: OK - 108 Password accepted 2.3.3 GETNODE command Parameters : no Requires data : no Returns data : yes Talker agents navigating through a server nodespace can issue the GETNODE command, with no parameters, to find out their current nodepath. The following is an example of the GETNODE command. C: GETNODE S: OK - 100 Nodepath follows S: /users/george/identity 2.3.4 CHANGENODE command Parameters : yes Requires data : no Returns data : no Talker agents can move to a different node by issuing the CHANGENODE command, with the target node as a parameter. The following is an example of the CHANGENODE command :- C: CHANGENODE /user/fred/ S: ERROR - 200 invalid node C: CHANGENODE /users/fred/ S: OK - 101 changing node 2.3.5 CREATENODE command Parameters : yes Reilly Page 9 Requires data : no Returns data : no Talker agents can attempt to create a new node within a listener's nodespace. The newly created node will be empty, and contain no keys. Talkers should be aware that listeners will not always accept requests for new nodes, and rarely without some form of authentication. Once a node has been created, the listener will make the new location as the current node. The following is an example of the CHANGENODE command :- C: CREATENODE /home/newnode/ S: OK - 102 node created successfully C: GETNODE S: OK - 100 returning current location S: /home/newnode/ 2.3.6 DELETENODE command Parameters : yes Requires data : no Returns data : no Talkers can attempt to delete a specific node by issuing the DELETENODE command, with the target node as a parameter. The listener is free to reject such a request, particularly when the agent's identity hasn't been authenticated. The following is an example of the DELETENODE command :- C: DELETENODE /user/fred/ S: ERROR - 200 write protected C: DELETENODE /users/fred/temp S: OK - 105 deleting /users/fred/temp 2.3.7 DELETEKEY command Parameters : yes Requires data : no Returns data : no Talkers can attempt to delete a specific key in the current node through the use of the DELETEKEY command. The DELETEKEY takes as a parameter the name of the key. The listener is free to reject such a request, particularly when the talker's identity hasn't been authenticated. The following is an example of the DELETEKEY command :- C: DELETEKEY name S: ERROR - 200 write protected C: DELETEKEY url S: OK - 105 deleting url Reilly Page 10 2.3.8 READ command Parameters : yes Requires data : no Returns data : yes Nodes can have zero or more key-value pairs of data. A talker may request the value of a specific key by executing the READ command, and specifying the key name as a parameter. The value returned by the listener can be text, or binary data. Access to information keys may be restricted by the listener. If access is permitted, the listener will specify the MIME content type[1] of the value, followed by its contents. The following is an example of the READ command :- C: READ name S: OK - 104 Key follows S: MIME: text/plain S: David Reilly S: . C: READ photo S: OK - 104 Key follows S: MIME: image/gif S: GIF89v''sdv#&^7..... 2.3.9 LIST command Parameters : optional Requires data : no Returns data : yes A talker may request a list of keys and their associated MIME type using the LIST command. A talker can list keys stored within the current node, or within a specific node by specifying the correct path. When listing keys in the current node, no parameter is required. Access to information keys may be restricted by the listener. If access is permitted, the result returned will contain the name of the keys, and their MIME type, on separate lines as a data value. The following is an example of the LIST command :- C: LIST S: OK - 106 Key list follows S: KEY: name MIME: text/plain S: KEY: email MIME: text/plain S: KEY: image MIME: image/jpeg S: . 2.3.10 LISTNODES command Parameters : optional Requires data : no Returns data : yes Reilly Page 11 A talker may request a list of subnodes by issuing the LISTNODES command. A talker can request a list of sub-nodes either from the current node, or a specific node by specifying a nodepath. When listing nodes in the current node, no parameter is required. Access to information keys may be restricted by the listener. If access is permitted, the result returned will contain the node names on separate lines. The following is an example of the LISTNODES command :- C: LISTNODES S: OK - 106 Node list follows S: NODE: users S: NODE: identity S: NODE: status S: . 2.3.11 CREATEKEY command Parameters : yes Requires data : no Returns data : no A talker may create a key in the current node by issuing a CREATEKEY command, and specifying the name and MIME type of the key as a parameter. A key is empty, by default, until such time as data is written to it using the WRITE command. Listeners are free to reject write requests, particularly if the talker's identity has not been authenticated. The following is an example of the CREATEKEY command :- C: CREATEKEY photo image/jpeg S: ERROR - 200 talker not authorized C: CHANGENODE /tmp/ S: OK - 101 Changing nodes C: CREATEKEY name text/plain S: OK - 102 name created 2.3.12 WRITE command Parameters : yes Requires data : yes Returns data : no A talker may write to a key in the current node by issuing a WRITE command, and then specifying the name of the key as a parameter. The new value of the key will be sent, including the MIME type if not text/plain, as data. The following is an example of the WRITE command :- C: WRITE name C: MIME: text/plain C: David Reilly S: OK - 103 write operation successful Reilly Page 12 2.3.13 QUERY command Parameters : yes Requires data : yes Returns data : yes Agents communicating under SACP aren't limited just to simple requests for data, but are also capable of responding to advanced queries. This is particularly important when an agent wishes to locate information from a listener agent with a large nodespace. Searching through every node might consume large amounts of network bandwidth and CPU time (on the part of both listener and talker). SACP doesn't dictate the specific query syntax or language which agents must use. Agents will likely be capable of using many query languages, and prescribing a set of languages would limit the versatility of the protocol. Talkers must specify as a parameter, the query language that is to be used, and then are free to send any form of data. QUERY commands can also be used to add a more sophisticated message passing system to agents, by QUERYing a message and receiving a response. QUERY can also be used to implement a two-way message system (one agent, the talker, polls the server for new messages, which are stored until the listener requests them). Such behavior, however, is beyond the scope of simple agents, and many SACP agents will not support such features. The following is an example of a QUERY command :- C: QUERY query/sql C: select * C: from employees C: where name like "John" C: . S: OK - 106 Database query follows S: MIME: text/plain S: "John Doe", 2423, "jd@mycompany.com" S: . 2.4 Command Responses When a command is issued by a talker, the listener will respond with a status line (indicating the success or failure of the operation), and when required by the nature of the command, data. The status line is composed of the operation state, and a message status code which gives more information about the operation. Optionally, a server may return a text message on the status line which gives human readable information about the result of the operation. 2.4.1 Operation State The state of the operation is indicated by one of the following two tokens "OK - " Reilly Page 13 "ERROR - " If an operation has been completed successfully, and without any problem, then the "OK -" is sent by the server. If any form of error has occurred, the "ERROR -" is sent, and the exact reason for the operation's failure must be determined through analysis of the message status code, and possibly the message sent by the server. When an error occurs, no data will be returned. 2.4.2 Message status code The three digit numerical status code included in all server response messages, provides more information on the success or failure of an operation that just its state. The status code gives an indication of why a message has failed, or that an command was successful. The first digit of the message's status code indicates which category of error occurred (based on a similar method used in HTTP[2]). The remaining digits give a more specific reason for the error and are described below:- 1 - Operation successful The operation was executed successfully. 2 - Agent Client Error The request made by the talker was in error. 3 - Agent Server Error The request could not be completed by the listener. 4 - Agent Broker Error The request generated an error with the broker (requires broker support). 5 - Reserved for future use This category is reserved for future use. Listeners should not issue these status codes. 6 - Reserved for future use This category is reserved for future use. Listeners should not issue these status codes. 7,8,9 - Experimental These categories are free for use by agent listeners that implement experimental commands and require new error categories/codes. 2.4.2.1 Operation Successful When an operation completes successfully, the listener will issue a status code whose first digit is 1. The following is a list of common 1xx codes and their meanings 100 Command executed successfully Generally applicable to any successful command. 101 Access to node granted Access to the node specified by the talker has been granted. Reilly Page 14 102 Resource created A new resource has been created, at the request of a talker agent. 103 Resource modified A resource has been modified, at the request of a talker agent. 104 Resource follows Access to a resource has been granted, and the contents of the resource will follow. 105 Resource destroyed A resource has been destroyed, at the request of a talker agent. 106 List follows (list, listnodes) The request for a list of items has been accepted, and a list will follow. 106 Query results follow (query) The query was succesful, and data will follow. 107 Identity accepted The listener has accepted the identity of the talker agent. 108 Client authenticated The listener has authenticated the identity of the talker agent. 2.4.2.2 Agent Client Error When an invalid request is made by a talker, the server will respond with a status code whose first digit is 2. The following is a list of common 2xx codes and their meaning. 200 Client Error The request made by the talker was in error. This code is generally applicable to any situation in which the talker has made a request which is invalid. 201 Invalid Command The command issued by the talker was unknown, or did not follow syntax. 202 Access Requires Authentication Access to this resource requires authentication of the talker's identity. 203 Access Denied Access is prohibited by the listener, because of the talker's identity or because authentication has failed. 204 Invalid node An attempt was made to access a node that did not exist. 205 Invalid key An attempt was made to access a key-value pair that did not exist. Reilly Page 15 206 Invalid authentication scheme The authentication scheme suggested by the talker is not supported by the listener, or is inappropriate for the identity of the talker. 207 Invalid query language The language for the query submitted by the talker is not supported by the listener. 2.4.2.3 Agent Server Error When a server cannot fulfill a request made by the talker that appears to be valid, it will issue an Agent Server Error code. Such error codes are distinguished by the fact that their first digit begins with 3. 300 General server error An error has occurred with the server, and it is unable to fulfill the request. 301 Temporarily unavailable The resource that is the focus of the request is temporarily unavailable. Such a situation might arise if two talkers attempt to access the same resource concurrently, or if the resource is locked by another system process. 302 Listener busy The listener is currently too busy to perform the request. The talker should wait for a few moments, and resubmit the request. 303 Not supported The type of request being made is not supported by the listener. 2.5 Security/Performance considerations 2.5.1 Security considerations In designing SACP, a balance has been struck between the need to incorporate security into the protocol, and the need of developers for freedom of implementation. No security mechanisms are dictated, and at all times, the listener agent has control over how much information is made available to talker agents. SACP does support authentication of identity, though any form of authentication can be implemented in listener and talker agents. The rationale behind these choices is to allow developers to implement a stronger standard for agents that require greater security, without specifying any one standard that might be too strong for simpler agents. There does exist a potential for misuse, in the form of the query command. For this reason, it is strongly advised that all listeners implementing queries require an agent's identity to be authenticated before accepting queries. 2.5.2 Performance considerations SACP has been designed to be a very light protocol, with a small command-set and minimal overhead. For dynamically changing data, SACP should offer a better alternative to running a web server or Reilly Page 16 database server and regularly updating information via these methods. However, the performance of SACP agents that use breadth first searches of a nodespace have not been fully investigated. Such agents may be better advised to use queries, where the search time is smaller on the server. Finally, queries may have a significant impact on system performance, depending on the query engine and the nature of the query. 3. References [1] N. Borenstein, N. Freed. MIME (Multipurpose Internet Mail Extensions), RFC 1521, September 1993. [2] T. Berners-Lee, R. Fielding, and H. Frystyk. Hypertext Transfer Protocol -- HTTP/1.0, RFC 1945, May 1996. 4. Author's Address David Reilly web : http://www.davidreilly.com 2/10 Samarai Avenue email: dodo@fan.net.au Gold Coast, QLD 4216, Australia